diff options
author | Stephen Hemminger <stephen@networkplumber.org> | 2023-05-08 19:05:38 -0700 |
---|---|---|
committer | Stephen Hemminger <stephen@networkplumber.org> | 2023-05-13 19:02:41 -0700 |
commit | fa44c2d6f1dab40ad615bcb16fdbdb189d617ed6 (patch) | |
tree | 8c3834ad365be650eecdcee6193dc1f74522a349 | |
parent | 8cda7a24a971170b833009f392579cfea87711bf (diff) | |
download | iproute2-fa44c2d6f1dab40ad615bcb16fdbdb189d617ed6.tar.gz |
iproute_lwtunnel: fix possible use of NULL when malloc() fails
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>
-rw-r--r-- | ip/iproute_lwtunnel.c | 18 |
1 files 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; |