There are patch to integrate the CodeChecker into ci: https://github.com/apache/nuttx/pull/7114 https://github.com/apache/nuttx/pull/7090 you can follow them for cppcheck too. The hard problem is that tools normally report many false alarms which make it impractical to enable the check in ci/cd.
On Wed, Oct 11, 2023 at 2:34 AM Daniel Appiagyei <daniel.appiag...@braincorp.com.invalid> wrote: > Hey, > I was running the [cppcheck](https://cppcheck.sourceforge.io/) static > analysis tool, found a few potential bugs, and wrote the following to share > how tools like this can help us ensure the integrity of our code. The > following are some bugs found. If anyone is interested in running cppcheck > on their project, scroll to the bottom for a HOW-TO. Is using a static > analysis tool like this something we'd be interested in adding to ci/cd? > > *The following were found in NuttX 12.2.1* > ## Null pointer dereference > #### 1: sched/signal/sig_dispatch.c:325 > ``` > src/deps/nuttx/sched/signal/sig_dispatch.c:325:26: warning: Either the > condition 'info!=NULL' is redundant or there is possible null pointer > dereference: info. [nullPointerRedundantCheck] > stcb, stcb->pid, info->si_signo, info->si_code, > > > ^ > > > src/deps/nuttx/sched/signal/sig_dispatch.c:329:36: note: Assuming that > condition 'info!=NULL' is not redundant > > DEBUGASSERT(stcb != NULL && info != NULL); > > > ^ > > > src/deps/nuttx/sched/signal/sig_dispatch.c:325:26: note: Null pointer > dereference > > stcb, stcb->pid, info->si_signo, info->si_code, > > > ^ > > > ``` > > #### 2: sched/signal/sig_dispatch.c:326 > ``` > src/deps/nuttx/sched/signal/sig_dispatch.c:326:9: warning: Either the > condition 'info!=NULL' is redundant or there is possible null pointer > dereference: info. [nullPointerRedundantCheck] > info->si_value.sival_int, > > > ^ > src/deps/nuttx/sched/signal/sig_dispatch.c:329:36: note: Assuming that > condition 'info!=NULL' is not redundant > DEBUGASSERT(stcb != NULL && info != NULL); > ^ > src/deps/nuttx/sched/signal/sig_dispatch.c:326:9: note: Null pointer > dereference > info->si_value.sival_int, > ^ > ``` > > #### 3: sched/signal/sig_dispatch.c:327 > ``` > src/deps/nuttx/sched/signal/sig_dispatch.c:327:41: warning: Either the > condition 'info!=NULL' is redundant or there is possible null pointer > dereference: info. [nullPointerRedundantCheck] > sigismember(&stcb->sigprocmask, info->si_signo) == 1 ? "YES" : > "NO"); > ^ > src/deps/nuttx/sched/signal/sig_dispatch.c:329:36: note: Assuming that > condition 'info!=NULL' is not redundant > DEBUGASSERT(stcb != NULL && info != NULL); > ^ > src/deps/nuttx/sched/signal/sig_dispatch.c:327:41: note: Null pointer > dereference > sigismember(&stcb->sigprocmask, info->si_signo) == 1 ? "YES" : > "NO"); > ^ > ``` > > #### 4: src/deps/nuttx/libs/libc/stdlib/lib_mbstowcs.c:42 > ``` > src/deps/nuttx/libs/libc/stdlib/lib_mbstowcs.c:42:36: error: Null pointer > dereference [nullPointer] > > return mbsrtowcs(dst, &src, len, NULL); > > > ^ > ``` > > #### 5: nuttx/libs/libc/stdlib/lib_wcstombs.c:38 > ``` > src/deps/nuttx/libs/libc/stdlib/lib_wcstombs.c:38:36: error: Null pointer > dereference [nullPointer] > return wcsrtombs(dst, &src, len, NULL); > ``` > > #### 6: drivers/net/netdev_upperhalf.c:168 > ``` > src/deps/nuttx/drivers/net/netdev_upperhalf.c:168:42: warning: Either the > condition 'dev' is redundant or there is possible null pointer dereference: > dev. [nullPointerRedundantCheck] > FAR struct netdev_upperhalf_s *upper = dev->d_private; > ^ > src/deps/nuttx/drivers/net/netdev_upperhalf.c:170:15: note: Assuming that > condition 'dev' is not redundant > DEBUGASSERT(dev && pkt); > ^ > src/deps/nuttx/drivers/net/netdev_upperhalf.c:168:42: note: Null pointer > dereference > FAR struct netdev_upperhalf_s *upper = dev->d_private; > ^ > ``` > > #### 7: sched/task/task_init.c:90 > ``` > src/deps/nuttx/sched/task/task_init.c:90:19: warning: Either the condition > 'tcb' is redundant or there is possible null pointer dereference: tcb. > [nullPointerRedundantCheck] > uint8_t ttype = tcb->cmn.flags & TCB_FLAG_TTYPE_MASK; > ^ > src/deps/nuttx/sched/task/task_init.c:96:15: note: Assuming that condition > 'tcb' is not redundant > DEBUGASSERT(tcb && ttype != TCB_FLAG_TTYPE_PTHREAD); > ^ > ``` > > ## Signed integer overflow > The [C standard]( > > https://www.gnu.org/software/autoconf/manual/autoconf-2.63/html_node/Integer-Overflow-Basics.html > ) > treats _signed_ integer overflow as undefined behavior. > #### 8: arch/arm/src/armv7-m/arm_fpuconfig.c:75 > ``` > src/deps/nuttx/arch/arm/src/armv7-m/arm_fpuconfig.c:75:15: error: Signed > integer overflow for expression '1<<31'. [integerOverflow] > > regval &= ~(NVIC_FPCCR_ASPEN | NVIC_FPCCR_LSPEN); > ``` > > #### 9: arch/arm/src/armv7-m/arm_hardfault.c:169 > ``` > src/deps/nuttx/arch/arm/src/armv7-m/arm_hardfault.c:169:19: error: Signed > integer overflow for expression '1<<31'. [integerOverflow] > else if (hfsr & NVIC_HFAULTS_DEBUGEVT) > ``` > > ## Buffer Overflow > #### 10: nuttx/tools/mkdeps.c:795 > ``` > src/deps/nuttx/tools/mkdeps.c:795:12: warning: Either the condition > 'cmdlen>=10240' is redundant or the array 'g_command[10240]' is accessed at > index 10240, which is out of bounds. [arrayIndexOutOfBoundsCond] > g_command[cmdlen] = '\0'; > ^ > src/deps/nuttx/tools/mkdeps.c:781:18: note: Assuming that condition > 'cmdlen>=10240' is not redundant > if (cmdlen >= MAX_BUFFER) > ^ > src/deps/nuttx/tools/mkdeps.c:794:3: note: cmdlen is incremented', new > value is 10240 > cmdlen++; > ^ > src/deps/nuttx/tools/mkdeps.c:795:12: note: Array index out of bounds > g_command[cmdlen] = '\0'; > ^ > ``` > > ## Uninitialized Variable > #### 11: src/deps/nuttx/tools/mkdeps.c:138 > ``` > src/deps/nuttx/tools/mkdeps.c:138:23: warning: Uninitialized variable: > *saveptr [uninitvar] > else if (saveptr && *saveptr) > ^ > src/deps/nuttx/tools/mkdeps.c:962:39: note: Calling function 'my_strtok_r', > 3rd argument '&lasts' value is <Uninit> > while ((file = strtok_r(files, " ", &lasts)) != NULL) > ^ > src/deps/nuttx/tools/mkdeps.c:138:23: note: Uninitialized variable: > *saveptr > else if (saveptr && *saveptr) > ^ > ``` > > ## Background > I needed a way to create a [compile_commands.json]( > > https://cmake.org/cmake/help/latest/variable/CMAKE_EXPORT_COMPILE_COMMANDS.html > ) > from `make`, so I installed [bear](https://github.com/rizsotto/Bear) from > my ubuntu package manager. I cloned `cppcheck` from its [github repo]( > https://github.com/danmar/cppcheck) and built it by following the [cmake > instructions](https://github.com/danmar/cppcheck#cmake). > > Next, I ran `make clean` followed by `bear make` on my project, which > generated the `compile_commands.json`. > Then, I ran: > ``` > >>> /path/to/build/bin/cppcheck --version > Cppcheck 2.13 dev > > >>> /path/to/build/bin/cppcheck --project=/path/to/compile_commands.json > -j8 --std=c++11 --std=c89 --quiet --enable=warning > ``` > > -- > > > *Daniel Appiagyei | Embedded Software Engineer* >