179 lines
6.4 KiB
Diff
179 lines
6.4 KiB
Diff
From fa44c2d6f1dab40ad615bcb16fdbdb189d617ed6 Mon Sep 17 00:00:00 2001
|
||
From: Stephen Hemminger <stephen@networkplumber.org>
|
||
Date: Mon, 8 May 2023 19:05:38 -0700
|
||
Subject: [PATCH] iproute_lwtunnel: fix possible use of NULL when malloc()
|
||
fails
|
||
MIME-Version: 1.0
|
||
Content-Type: text/plain; charset=UTF-8
|
||
Content-Transfer-Encoding: 8bit
|
||
|
||
iproute_lwtunnel.c: In function ‘parse_srh’:
|
||
iproute_lwtunnel.c:903:9: warning: use of possibly-NULL ‘srh’ where non-null expected [CWE-690] [-Wanalyzer-possible-null-argument]
|
||
903 | memset(srh, 0, srhlen);
|
||
| ^~~~~~~~~~~~~~~~~~~~~~
|
||
‘parse_srh’: events 1-2
|
||
|
|
||
| 902 | srh = malloc(srhlen);
|
||
| | ^~~~~~~~~~~~~~
|
||
| | |
|
||
| | (1) this call could return NULL
|
||
| 903 | memset(srh, 0, srhlen);
|
||
| | ~~~~~~~~~~~~~~~~~~~~~~
|
||
| | |
|
||
| | (2) argument 1 (‘srh’) from (1) could be NULL where non-null expected
|
||
|
|
||
In file included from iproute_lwtunnel.c:13:
|
||
/usr/include/string.h:61:14: note: argument 1 of ‘memset’ must be non-null
|
||
61 | extern void *memset (void *__s, int __c, size_t __n) __THROW __nonnull ((1));
|
||
| ^~~~~~
|
||
iproute_lwtunnel.c: In function ‘parse_encap_seg6’:
|
||
iproute_lwtunnel.c:980:9: warning: use of possibly-NULL ‘tuninfo’ where non-null expected [CWE-690] [-Wanalyzer-possible-null-argument]
|
||
980 | memset(tuninfo, 0, sizeof(*tuninfo) + srhlen);
|
||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
‘parse_encap_seg6’: events 1-2
|
||
|
|
||
| 934 | static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
|
||
| | ^~~~~~~~~~~~~~~~
|
||
| | |
|
||
| | (1) entry to ‘parse_encap_seg6’
|
||
|......
|
||
| 976 | srh = parse_srh(segbuf, hmac, encap);
|
||
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
| | |
|
||
| | (2) calling ‘parse_srh’ from ‘parse_encap_seg6’
|
||
|
|
||
+--> ‘parse_srh’: events 3-5
|
||
|
|
||
| 882 | static struct ipv6_sr_hdr *parse_srh(char *segbuf, int hmac, bool encap)
|
||
| | ^~~~~~~~~
|
||
| | |
|
||
| | (3) entry to ‘parse_srh’
|
||
|......
|
||
| 922 | if (hmac) {
|
||
| | ~
|
||
| | |
|
||
| | (4) following ‘false’ branch (when ‘hmac == 0’)...
|
||
|......
|
||
| 931 | return srh;
|
||
| | ~~~
|
||
| | |
|
||
| | (5) ...to here
|
||
|
|
||
<------+
|
||
|
|
||
‘parse_encap_seg6’: events 6-8
|
||
|
|
||
| 976 | srh = parse_srh(segbuf, hmac, encap);
|
||
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
| | |
|
||
| | (6) returning to ‘parse_encap_seg6’ from ‘parse_srh’
|
||
|......
|
||
| 979 | tuninfo = malloc(sizeof(*tuninfo) + srhlen);
|
||
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
| | |
|
||
| | (7) this call could return NULL
|
||
| 980 | memset(tuninfo, 0, sizeof(*tuninfo) + srhlen);
|
||
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
| | |
|
||
| | (8) argument 1 (‘tuninfo’) from (7) could be NULL where non-null expected
|
||
|
|
||
/usr/include/string.h:61:14: note: argument 1 of ‘memset’ must be non-null
|
||
61 | extern void *memset (void *__s, int __c, size_t __n) __THROW __nonnull ((1));
|
||
| ^~~~~~
|
||
iproute_lwtunnel.c: In function ‘parse_rpl_srh’:
|
||
iproute_lwtunnel.c:1018:21: warning: dereference of possibly-NULL ‘srh’ [CWE-690] [-Wanalyzer-possible-null-dereference]
|
||
1018 | srh->hdrlen = (srhlen >> 3) - 1;
|
||
| ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
|
||
‘parse_rpl_srh’: events 1-2
|
||
|
|
||
| 1016 | srh = calloc(1, srhlen);
|
||
| | ^~~~~~~~~~~~~~~~~
|
||
| | |
|
||
| | (1) this call could return NULL
|
||
| 1017 |
|
||
| 1018 | srh->hdrlen = (srhlen >> 3) - 1;
|
||
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
| | |
|
||
| | (2) ‘srh’ could be NULL: unchecked value from (1)
|
||
|
|
||
|
||
Fixes: 00e76d4da37f ("iproute: add helper functions for SRH processing")
|
||
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
|
||
---
|
||
ip/iproute_lwtunnel.c | 18 +++++++++++++-----
|
||
1 file changed, 13 insertions(+), 5 deletions(-)
|
||
|
||
diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
|
||
index 308178ef..96de3b20 100644
|
||
--- a/ip/iproute_lwtunnel.c
|
||
+++ b/ip/iproute_lwtunnel.c
|
||
@@ -900,6 +900,9 @@ static struct ipv6_sr_hdr *parse_srh(char *segbuf, int hmac, bool encap)
|
||
srhlen += 40;
|
||
|
||
srh = malloc(srhlen);
|
||
+ if (srh == NULL)
|
||
+ return NULL;
|
||
+
|
||
memset(srh, 0, srhlen);
|
||
|
||
srh->hdrlen = (srhlen >> 3) - 1;
|
||
@@ -935,14 +938,14 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
|
||
char ***argvp)
|
||
{
|
||
int mode_ok = 0, segs_ok = 0, hmac_ok = 0;
|
||
- struct seg6_iptunnel_encap *tuninfo;
|
||
+ struct seg6_iptunnel_encap *tuninfo = NULL;
|
||
struct ipv6_sr_hdr *srh;
|
||
char **argv = *argvp;
|
||
char segbuf[1024] = "";
|
||
int argc = *argcp;
|
||
int encap = -1;
|
||
__u32 hmac = 0;
|
||
- int ret = 0;
|
||
+ int ret = -1;
|
||
int srhlen;
|
||
|
||
while (argc > 0) {
|
||
@@ -974,9 +977,13 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
|
||
}
|
||
|
||
srh = parse_srh(segbuf, hmac, encap);
|
||
+ if (srh == NULL)
|
||
+ goto out;
|
||
srhlen = (srh->hdrlen + 1) << 3;
|
||
|
||
tuninfo = malloc(sizeof(*tuninfo) + srhlen);
|
||
+ if (tuninfo == NULL)
|
||
+ goto out;
|
||
memset(tuninfo, 0, sizeof(*tuninfo) + srhlen);
|
||
|
||
tuninfo->mode = encap;
|
||
@@ -984,13 +991,12 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
|
||
memcpy(tuninfo->srh, srh, srhlen);
|
||
|
||
if (rta_addattr_l(rta, len, SEG6_IPTUNNEL_SRH, tuninfo,
|
||
- sizeof(*tuninfo) + srhlen)) {
|
||
- ret = -1;
|
||
+ sizeof(*tuninfo) + srhlen))
|
||
goto out;
|
||
- }
|
||
|
||
*argcp = argc + 1;
|
||
*argvp = argv - 1;
|
||
+ ret = 0;
|
||
|
||
out:
|
||
free(tuninfo);
|
||
@@ -1014,6 +1020,8 @@ static struct ipv6_rpl_sr_hdr *parse_rpl_srh(char *segbuf)
|
||
srhlen = 8 + 16 * nsegs;
|
||
|
||
srh = calloc(1, srhlen);
|
||
+ if (srh == NULL)
|
||
+ return NULL;
|
||
|
||
srh->hdrlen = (srhlen >> 3) - 1;
|
||
srh->type = 3;
|
||
--
|
||
2.27.0
|
||
|