diff mbox series

[iproute2,03/11] iproute_lwtunnel: fix possible use of NULL when malloc() fails

Message ID 20230509212125.15880-4-stephen@networkplumber.org (mailing list archive)
State Accepted
Commit fa44c2d6f1dab40ad615bcb16fdbdb189d617ed6
Delegated to: Stephen Hemminger
Headers show
Series fix analyzer warnings | expand

Checks

Context Check Description
netdev/tree_selection success Not a local patch

Commit Message

Stephen Hemminger May 9, 2023, 9:21 p.m. UTC
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 mbox series

Patch

diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
index 308178efe054..96de3b207ef4 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;