iproute/backport-ipmaddr-fix-dereference-of-NULL-on-malloc-failure.patch
gaoxingwang 552d5e248f backport patches to fix bugs
(cherry picked from commit 2e9232daaeeab8917abc9a7830b7a9195d7a1da0)
2023-08-17 17:20:22 +08:00

318 lines
14 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From 8cda7a24a971170b833009f392579cfea87711bf Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Mon, 8 May 2023 19:02:20 -0700
Subject: [PATCH] ipmaddr: fix dereference of NULL on malloc() failure
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Found by -fanalyzer. This is a bug since beginning of initial
versions of ip multicast support (pre git).
ipmaddr.c: In function read_dev_mcast:
ipmaddr.c:105:25: warning: dereference of possibly-NULL ma [CWE-690] [-Wanalyzer-possible-null-dereference]
105 | memcpy(ma, &m, sizeof(m));
| ^~~~~~~~~~~~~~~~~~~~~~~~~
do_multiaddr: events 1-4
|
| 354 | int do_multiaddr(int argc, char **argv)
| | ^~~~~~~~~~~~
| | |
| | (1) entry to do_multiaddr
| 355 | {
| 356 | if (argc < 1)
| | ~
| | |
| | (2) following true branch (when argc <= 0)...
| 357 | return multiaddr_list(0, NULL);
| | ~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (3) ...to here
| | (4) calling multiaddr_list from do_multiaddr
|
+--> multiaddr_list: events 5-10
|
| 255 | static int multiaddr_list(int argc, char **argv)
| | ^~~~~~~~~~~~~~
| | |
| | (5) entry to multiaddr_list
|......
| 262 | while (argc > 0) {
| | ~~~~~~~~
| | |
| | (6) following false branch (when argc <= 0)...
|......
| 275 | if (!filter.family || filter.family == AF_PACKET)
| | ~ ~~~~~~~~~~~~~
| | | |
| | | (7) ...to here
| | (8) following true branch...
| 276 | read_dev_mcast(&list);
| | ~~~~~~~~~~~~~~~~~~~~~
| | |
| | (9) ...to here
| | (10) calling read_dev_mcast from multiaddr_list
|
+--> read_dev_mcast: events 11-12
|
| 82 | static void read_dev_mcast(struct ma_info **result_p)
| | ^~~~~~~~~~~~~~
| | |
| | (11) entry to read_dev_mcast
|......
| 87 | if (!fp)
| | ~
| | |
| | (12) following false branch (when fp is non-NULL)...
|
read_dev_mcast: event 13
|
|cc1:
| (13): ...to here
|
read_dev_mcast: events 14-17
|
| 90 | while (fgets(buf, sizeof(buf), fp)) {
| | ^~~~~
| | |
| | (14) following true branch...
| 91 | char hexa[256];
| 92 | struct ma_info m = { .addr.family = AF_PACKET };
| | ~
| | |
| | (15) ...to here
|......
| 103 | struct ma_info *ma = malloc(sizeof(m));
| | ~~~~~~~~~~~~~~~~~
| | |
| | (16) this call could return NULL
| 104 |
| 105 | memcpy(ma, &m, sizeof(m));
| | ~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (17) ma could be NULL: unchecked value from (16)
|
ipmaddr.c: In function read_igmp:
ipmaddr.c:152:17: warning: dereference of possibly-NULL ma [CWE-690] [-Wanalyzer-possible-null-dereference]
152 | memcpy(ma, &m, sizeof(m));
| ^~~~~~~~~~~~~~~~~~~~~~~~~
do_multiaddr: events 1-4
|
| 354 | int do_multiaddr(int argc, char **argv)
| | ^~~~~~~~~~~~
| | |
| | (1) entry to do_multiaddr
| 355 | {
| 356 | if (argc < 1)
| | ~
| | |
| | (2) following true branch (when argc <= 0)...
| 357 | return multiaddr_list(0, NULL);
| | ~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (3) ...to here
| | (4) calling multiaddr_list from do_multiaddr
|
+--> multiaddr_list: events 5-10
|
| 255 | static int multiaddr_list(int argc, char **argv)
| | ^~~~~~~~~~~~~~
| | |
| | (5) entry to multiaddr_list
|......
| 262 | while (argc > 0) {
| | ~~~~~~~~
| | |
| | (6) following false branch (when argc <= 0)...
|......
| 275 | if (!filter.family || filter.family == AF_PACKET)
| | ~~~~~~~~~~~~~
| | |
| | (7) ...to here
| 276 | read_dev_mcast(&list);
| 277 | if (!filter.family || filter.family == AF_INET)
| | ~
| | |
| | (8) following true branch...
| 278 | read_igmp(&list);
| | ~~~~~~~~~~~~~~~~
| | |
| | (9) ...to here
| | (10) calling read_igmp from multiaddr_list
|
+--> read_igmp: events 11-14
|
| 116 | static void read_igmp(struct ma_info **result_p)
| | ^~~~~~~~~
| | |
| | (11) entry to read_igmp
|......
| 126 | if (!fp)
| | ~
| | |
| | (12) following false branch (when fp is non-NULL)...
| 127 | return;
| 128 | if (!fgets(buf, sizeof(buf), fp)) {
| | ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | | |
| | | (13) ...to here
| | (14) following false branch...
|
read_igmp: event 15
|
|cc1:
| (15): ...to here
|
read_igmp: events 16-19
|
| 133 | while (fgets(buf, sizeof(buf), fp)) {
| | ^~~~~
| | |
| | (16) following true branch...
|......
| 136 | if (buf[0] != '\t') {
| | ~~~~~~
| | |
| | (17) ...to here
|......
| 151 | ma = malloc(sizeof(m));
| | ~~~~~~~~~~~~~~~~~
| | |
| | (18) this call could return NULL
| 152 | memcpy(ma, &m, sizeof(m));
| | ~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (19) ma could be NULL: unchecked value from (18)
|
ipmaddr.c: In function read_igmp6:
ipmaddr.c:181:25: warning: dereference of possibly-NULL ma [CWE-690] [-Wanalyzer-possible-null-dereference]
181 | memcpy(ma, &m, sizeof(m));
| ^~~~~~~~~~~~~~~~~~~~~~~~~
do_multiaddr: events 1-4
|
| 354 | int do_multiaddr(int argc, char **argv)
| | ^~~~~~~~~~~~
| | |
| | (1) entry to do_multiaddr
| 355 | {
| 356 | if (argc < 1)
| | ~
| | |
| | (2) following true branch (when argc <= 0)...
| 357 | return multiaddr_list(0, NULL);
| | ~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (3) ...to here
| | (4) calling multiaddr_list from do_multiaddr
|
+--> multiaddr_list: events 5-10
|
| 255 | static int multiaddr_list(int argc, char **argv)
| | ^~~~~~~~~~~~~~
| | |
| | (5) entry to multiaddr_list
|......
| 262 | while (argc > 0) {
| | ~~~~~~~~
| | |
| | (6) following false branch (when argc <= 0)...
|......
| 275 | if (!filter.family || filter.family == AF_PACKET)
| | ~~~~~~~~~~~~~
| | |
| | (7) ...to here
|......
| 279 | if (!filter.family || filter.family == AF_INET6)
| | ~
| | |
| | (8) following true branch...
| 280 | read_igmp6(&list);
| | ~~~~~~~~~~~~~~~~~
| | |
| | (9) ...to here
| | (10) calling read_igmp6 from multiaddr_list
|
+--> read_igmp6: events 11-12
|
| 159 | static void read_igmp6(struct ma_info **result_p)
| | ^~~~~~~~~~
| | |
| | (11) entry to read_igmp6
|......
| 164 | if (!fp)
| | ~
| | |
| | (12) following false branch (when fp is non-NULL)...
|
read_igmp6: event 13
|
|cc1:
| (13): ...to here
|
read_igmp6: events 14-17
|
| 167 | while (fgets(buf, sizeof(buf), fp)) {
| | ^~~~~
| | |
| | (14) following true branch...
| 168 | char hexa[256];
| 169 | struct ma_info m = { .addr.family = AF_INET6 };
| | ~
| | |
| | (15) ...to here
|......
| 179 | struct ma_info *ma = malloc(sizeof(m));
| | ~~~~~~~~~~~~~~~~~
| | |
| | (16) this call could return NULL
| 180 |
| 181 | memcpy(ma, &m, sizeof(m));
| | ~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (17) ma could be NULL: unchecked value from (16)
|
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
ip/ipmaddr.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/ip/ipmaddr.c b/ip/ipmaddr.c
index f8d6b992..a8ef20ec 100644
--- a/ip/ipmaddr.c
+++ b/ip/ipmaddr.c
@@ -102,6 +102,8 @@ static void read_dev_mcast(struct ma_info **result_p)
if (len >= 0) {
struct ma_info *ma = malloc(sizeof(m));
+ if (ma == NULL)
+ break;
memcpy(ma, &m, sizeof(m));
ma->addr.bytelen = len;
ma->addr.bitlen = len<<3;
@@ -149,6 +151,9 @@ static void read_igmp(struct ma_info **result_p)
sscanf(buf, "%08x%d", (__u32 *)&m.addr.data, &m.users);
ma = malloc(sizeof(m));
+ if (ma == NULL)
+ break;
+
memcpy(ma, &m, sizeof(m));
maddr_ins(result_p, ma);
}
@@ -178,8 +183,10 @@ static void read_igmp6(struct ma_info **result_p)
if (len >= 0) {
struct ma_info *ma = malloc(sizeof(m));
- memcpy(ma, &m, sizeof(m));
+ if (ma == NULL)
+ break;
+ memcpy(ma, &m, sizeof(m));
ma->addr.bytelen = len;
ma->addr.bitlen = len<<3;
maddr_ins(result_p, ma);
--
2.27.0