summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Hemminger <stephen@networkplumber.org>2023-05-08 19:05:38 -0700
committerStephen Hemminger <stephen@networkplumber.org>2023-05-13 19:02:41 -0700
commitfa44c2d6f1dab40ad615bcb16fdbdb189d617ed6 (patch)
tree8c3834ad365be650eecdcee6193dc1f74522a349
parent8cda7a24a971170b833009f392579cfea87711bf (diff)
downloadiproute2-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.c18
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;