iproute/backport-nstat-fix-potential-NULL-deref.patch

365 lines
19 KiB
Diff
Raw Normal View History

From d348d1d6466a4a712b47612c1e9388161334fc7a Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Mon, 8 May 2023 19:42:03 -0700
Subject: [PATCH] nstat: fix potential NULL deref
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reported as:
CC nstat
nstat.c: In function load_ugly_table:
nstat.c:205:24: warning: dereference of NULL p [CWE-476] [-Wanalyzer-null-dereference]
205 | while (*p) {
| ^~
main: events 1-14
|
| 575 | int main(int argc, char *argv[])
| | ^~~~
| | |
| | (1) entry to main
|......
| 635 | if (scan_interval > 0) {
| | ~
| | |
| | (2) following true branch...
| 636 | if (time_constant == 0)
| | ~~~~~~~~~~~~~~~~~~
| | |
| | (3) ...to here
|......
| 640 | if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
| | ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | | |
| | | (4) when socket succeeds
| | (5) following false branch (when fd >= 0)...
|......
| 644 | if (bind(fd, (struct sockaddr *)&sun, 2+1+strlen(sun.sun_path+1)) < 0) {
| | ~ ~~~~~~~~~~~~~~~~~~~~~~
| | | |
| | (7) following false branch... (6) ...to here
|......
| 648 | if (listen(fd, 5) < 0) {
| | ~~~~~~~~~~~~~~
| | ||
| | |(8) ...to here
| | |(9) when listen succeeds
| | (10) following false branch...
|......
| 652 | if (daemon(0, 0)) {
| | ~~~~~~~~~~~~~
| | ||
| | |(11) ...to here
| | (12) following false branch...
|......
| 656 | signal(SIGPIPE, SIG_IGN);
| | ~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (13) ...to here
| 657 | signal(SIGCHLD, sigchild);
| 658 | server_loop(fd);
| | ~~~~~~~~~~~~~~~
| | |
| | (14) calling server_loop from main
|
+--> server_loop: events 15-16
|
| 472 | static void server_loop(int fd)
| | ^~~~~~~~~~~
| | |
| | (15) entry to server_loop
|......
| 483 | load_netstat();
| | ~~~~~~~~~~~~~~
| | |
| | (16) calling load_netstat from server_loop
|
+--> load_netstat: events 17-20
|
| 302 | static void load_netstat(void)
| | ^~~~~~~~~~~~
| | |
| | (17) entry to load_netstat
|......
| 306 | if (fp) {
| | ~
| | |
| | (18) following true branch (when fp is non-NULL)...
| 307 | load_ugly_table(fp);
| | ~~~~~~~~~~~~~~~~~~~
| | |
| | (19) ...to here
| | (20) calling load_ugly_table from load_netstat
|
+--> load_ugly_table: events 21-26
|
| 178 | static void load_ugly_table(FILE *fp)
| | ^~~~~~~~~~~~~~~
| | |
| | (21) entry to load_ugly_table
| 179 | {
| 180 | char *buf = NULL;
| | ~~~
| | |
| | (22) buf is NULL
|......
| 186 | while ((nread = getline(&buf, &buflen, fp)) != -1) {
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (23) following true branch...
|......
| 192 | p = strchr(buf, ':');
| | ~~~~~~~~~~~~~~~~
| | |
| | (24) ...to here
| | (25) when strchr returns non-NULL
| 193 | if (!p) {
| | ~
| | |
| | (26) following false branch (when p is non-NULL)...
|
load_ugly_table: event 27
|
|cc1:
| (27): ...to here
|
load_ugly_table: events 28-40
|
| 205 | while (*p) {
| | ^~
| | |
| | (28) following true branch...
| | (40) dereference of NULL p
|......
| 208 | if ((next = strchr(p, ' ')) != NULL)
| | ~ ~~~~~~~~~~~~~~
| | | |
| | | (29) ...to here
| | | (30) when strchr returns NULL
| | (31) following false branch (when next is NULL)...
| 209 | *next++ = 0;
| 210 | else if ((next = strchr(p, '\n')) != NULL)
| | ~ ~~~~~~~~~~~~~~~
| | | |
| | | (32) ...to here
| | | (33) when strchr returns NULL
| | (34) following false branch (when next is NULL)...
| 211 | *next++ = 0;
| 212 | if (off < sizeof(idbuf)) {
| | ~~~~~~~~~~~~~~~~~~~~
| | | |
| | | (35) ...to here
| | (36) following false branch...
|......
| 216 | n = malloc(sizeof(*n));
| | ~~~~~~~~~~~~~~~~~~
| | |
| | (37) ...to here
| 217 | if (!n) {
| | ~
| | |
| | (38) following false branch (when n is non-NULL)...
|......
| 221 | n->id = strdup(idbuf);
| | ~~~~~~~~~~~~~
| | |
| | (39) ...to here
|
nstat.c:254:35: warning: dereference of NULL n [CWE-476] [-Wanalyzer-null-dereference]
254 | n = n->next;
| ~~^~~~~~~~~
main: events 1-14
|
| 575 | int main(int argc, char *argv[])
| | ^~~~
| | |
| | (1) entry to main
|......
| 635 | if (scan_interval > 0) {
| | ~
| | |
| | (2) following true branch...
| 636 | if (time_constant == 0)
| | ~~~~~~~~~~~~~~~~~~
| | |
| | (3) ...to here
|......
| 640 | if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
| | ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | | |
| | | (4) when socket succeeds
| | (5) following false branch (when fd >= 0)...
|......
| 644 | if (bind(fd, (struct sockaddr *)&sun, 2+1+strlen(sun.sun_path+1)) < 0) {
| | ~ ~~~~~~~~~~~~~~~~~~~~~~
| | | |
| | (7) following false branch... (6) ...to here
|......
| 648 | if (listen(fd, 5) < 0) {
| | ~~~~~~~~~~~~~~
| | ||
| | |(8) ...to here
| | |(9) when listen succeeds
| | (10) following false branch...
|......
| 652 | if (daemon(0, 0)) {
| | ~~~~~~~~~~~~~
| | ||
| | |(11) ...to here
| | (12) following false branch...
|......
| 656 | signal(SIGPIPE, SIG_IGN);
| | ~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (13) ...to here
| 657 | signal(SIGCHLD, sigchild);
| 658 | server_loop(fd);
| | ~~~~~~~~~~~~~~~
| | |
| | (14) calling server_loop from main
|
+--> server_loop: events 15-16
|
| 472 | static void server_loop(int fd)
| | ^~~~~~~~~~~
| | |
| | (15) entry to server_loop
|......
| 483 | load_netstat();
| | ~~~~~~~~~~~~~~
| | |
| | (16) calling load_netstat from server_loop
|
+--> load_netstat: events 17-20
|
| 302 | static void load_netstat(void)
| | ^~~~~~~~~~~~
| | |
| | (17) entry to load_netstat
|......
| 306 | if (fp) {
| | ~
| | |
| | (18) following true branch (when fp is non-NULL)...
| 307 | load_ugly_table(fp);
| | ~~~~~~~~~~~~~~~~~~~
| | |
| | (19) ...to here
| | (20) calling load_ugly_table from load_netstat
|
+--> load_ugly_table: events 21-25
|
| 178 | static void load_ugly_table(FILE *fp)
| | ^~~~~~~~~~~~~~~
| | |
| | (21) entry to load_ugly_table
|......
| 186 | while ((nread = getline(&buf, &buflen, fp)) != -1) {
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (22) following true branch...
|......
| 192 | p = strchr(buf, ':');
| | ~~~~~~~~~~~~~~~~
| | |
| | (23) ...to here
| | (24) when strchr returns non-NULL
| 193 | if (!p) {
| | ~
| | |
| | (25) following false branch (when p is non-NULL)...
|
load_ugly_table: event 26
|
|cc1:
| (26): ...to here
|
load_ugly_table: events 27-28
|
| 205 | while (*p) {
| | ^
| | |
| | (27) following false branch...
|......
| 228 | nread = getline(&buf, &buflen, fp);
| | ~
| | |
| | (28) inlined call to getline from load_ugly_table
|
+--> getline: event 29
|
|/usr/include/bits/stdio.h:120:10:
| 120 | return __getdelim (__lineptr, __n, '\n', __stream);
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (29) ...to here
|
<------+
|
load_ugly_table: events 30-36
|
|nstat.c:229:20:
| 229 | if (nread == -1) {
| | ^
| | |
| | (30) following false branch...
|......
| 234 | count2 = count_spaces(buf);
| | ~~~~~~~~~~~~~~~~~
| | |
| | (31) ...to here
|......
| 239 | if (!p) {
| | ~
| | |
| | (32) following false branch (when p is non-NULL)...
|......
| 244 | *p = 0;
| | ~~~~~~
| | |
| | (33) ...to here
| 245 | if (sscanf(p+1, "%llu", &n->val) != 1) {
| | ~
| | |
| | (34) following false branch...
|......
| 251 | if (skip)
| | ~
| | |
| | (35) ...to here
|......
| 254 | n = n->next;
| | ~~~~~~~~~~~
| | |
| | (36) dereference of NULL n
|
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
misc/nstat.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/misc/nstat.c b/misc/nstat.c
index 0ab92ecb..2c10feaa 100644
--- a/misc/nstat.c
+++ b/misc/nstat.c
@@ -219,9 +219,15 @@ static void load_ugly_table(FILE *fp)
exit(-1);
}
n->id = strdup(idbuf);
+ if (n->id == NULL) {
+ perror("nstat: strdup");
+ exit(-1);
+ }
n->rate = 0;
n->next = db;
db = n;
+ if (next == NULL)
+ break;
p = next;
}
n = db;
--
2.27.0