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*
>

Reply via email to