I'm not the right guy to talk about CI,but I believe that every modified
C file is run through Lint. If you have questions, I am sure someone
else can expound.
On 10/10/2023 12:33 PM, Daniel Appiagyei 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
```