!150 [sync] PR-148: backport patches to fix bugs

From: @openeuler-sync-bot 
Reviewed-by: @gebidelidaye 
Signed-off-by: @gebidelidaye
This commit is contained in:
openeuler-ci-bot 2023-08-21 08:45:01 +00:00 committed by Gitee
commit b2ec2c93fd
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
15 changed files with 2327 additions and 1 deletions

View File

@ -0,0 +1,317 @@
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

View File

@ -0,0 +1,49 @@
From 465e87a89c134d28a7fae540d26b27e6a2e1d6c0 Mon Sep 17 00:00:00 2001
From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Date: Thu, 11 May 2023 16:42:24 +0200
Subject: [PATCH] ipnetns: fix fd leak with 'ip netns set'
There is no reason to open this netns file. set_netnsid_from_name() uses
netns_get_fd() for this purpose and uses the returned fd.
Reported-by: Stephen Hemminger <stephen@networkplumber.org>
Fixes: d182ee1307c7 ("ipnetns: allow to get and set netns ids")
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
ip/ipnetns.c | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/ip/ipnetns.c b/ip/ipnetns.c
index 12035349..9d996832 100644
--- a/ip/ipnetns.c
+++ b/ip/ipnetns.c
@@ -967,9 +967,8 @@ int set_netnsid_from_name(const char *name, int nsid)
static int netns_set(int argc, char **argv)
{
- char netns_path[PATH_MAX];
const char *name;
- int netns, nsid;
+ int nsid;
if (argc < 1) {
fprintf(stderr, "No netns name specified\n");
@@ -988,14 +987,6 @@ static int netns_set(int argc, char **argv)
else if (nsid < 0)
invarg("\"netnsid\" value should be >= 0", argv[1]);
- snprintf(netns_path, sizeof(netns_path), "%s/%s", NETNS_RUN_DIR, name);
- netns = open(netns_path, O_RDONLY | O_CLOEXEC);
- if (netns < 0) {
- fprintf(stderr, "Cannot open network namespace \"%s\": %s\n",
- name, strerror(errno));
- return -1;
- }
-
return set_netnsid_from_name(name, nsid);
}
--
2.27.0

View File

@ -0,0 +1,309 @@
From 7e8cdfa2eac57c8c1c469681d5ee016fc432ee4d Mon Sep 17 00:00:00 2001
From: zhaoshuang <zhaoshuang@uniontech.com>
Date: Thu, 11 May 2023 08:37:26 +0800
Subject: [PATCH] iproute2: optimize code and fix some mem-leak risk
Conflict:contaxt adapt in devlink/devlink.c ip/ipnexthop.c,and remove modify in tc/tc_class.c because it
does not have leak
Reference:https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/commit?id=7e8cdfa2eac57c8c1c469681d5ee016fc432ee4d
Signed-off-by: zhaoshuang <izhaoshuang@163.com>
Reviewed-by: Pawel Chmielewski <pawel.chmielewski@intel.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
bridge/mdb.c | 4 ++++
devlink/devlink.c | 21 +++++++++------------
ip/ipaddrlabel.c | 1 +
ip/ipfou.c | 1 +
ip/ipila.c | 1 +
ip/ipnetconf.c | 1 +
ip/ipnexthop.c | 4 ++++
ip/iproute.c | 6 ++++++
ip/iprule.c | 1 +
ip/iptuntap.c | 1 +
ip/tunnel.c | 2 ++
tc/tc_filter.c | 1 +
tc/tc_qdisc.c | 1 +
13 files changed, 33 insertions(+), 12 deletions(-)
diff --git a/bridge/mdb.c b/bridge/mdb.c
index b427d87..c5f23d0 100644
--- a/bridge/mdb.c
+++ b/bridge/mdb.c
@@ -423,12 +423,14 @@ static int mdb_show(int argc, char **argv)
/* get mdb entries */
if (rtnl_mdbdump_req(&rth, PF_BRIDGE) < 0) {
perror("Cannot send dump request");
+ delete_json_obj();
return -1;
}
open_json_array(PRINT_JSON, "mdb");
if (rtnl_dump_filter(&rth, print_mdbs, stdout) < 0) {
fprintf(stderr, "Dump terminated\n");
+ delete_json_obj();
return -1;
}
close_json_array(PRINT_JSON, NULL);
@@ -436,12 +438,14 @@ static int mdb_show(int argc, char **argv)
/* get router ports */
if (rtnl_mdbdump_req(&rth, PF_BRIDGE) < 0) {
perror("Cannot send dump request");
+ delete_json_obj();
return -1;
}
open_json_object("router");
if (rtnl_dump_filter(&rth, print_rtrs, stdout) < 0) {
fprintf(stderr, "Dump terminated\n");
+ delete_json_obj();
return -1;
}
close_json_object();
diff --git a/devlink/devlink.c b/devlink/devlink.c
index 765e90d..9275ee5 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -209,6 +209,14 @@ struct ifname_map {
char *ifname;
};
+static void ifname_map_free(struct ifname_map *ifname_map)
+{
+ free(ifname_map->ifname);
+ free(ifname_map->dev_name);
+ free(ifname_map->bus_name);
+ free(ifname_map);
+}
+
static struct ifname_map *ifname_map_alloc(const char *bus_name,
const char *dev_name,
uint32_t port_index,
@@ -225,23 +233,12 @@ static struct ifname_map *ifname_map_alloc(const char *bus_name,
ifname_map->ifname = strdup(ifname);
if (!ifname_map->bus_name || !ifname_map->dev_name ||
!ifname_map->ifname) {
- free(ifname_map->ifname);
- free(ifname_map->dev_name);
- free(ifname_map->bus_name);
- free(ifname_map);
+ ifname_map_free(ifname_map);
return NULL;
}
return ifname_map;
}
-static void ifname_map_free(struct ifname_map *ifname_map)
-{
- free(ifname_map->ifname);
- free(ifname_map->dev_name);
- free(ifname_map->bus_name);
- free(ifname_map);
-}
-
#define DL_OPT_HANDLE BIT(0)
#define DL_OPT_HANDLEP BIT(1)
#define DL_OPT_PORT_TYPE BIT(2)
diff --git a/ip/ipaddrlabel.c b/ip/ipaddrlabel.c
index beb08da..9e468b0 100644
--- a/ip/ipaddrlabel.c
+++ b/ip/ipaddrlabel.c
@@ -127,6 +127,7 @@ static int ipaddrlabel_list(int argc, char **argv)
new_json_obj(json);
if (rtnl_dump_filter(&rth, print_addrlabel, stdout) < 0) {
fprintf(stderr, "Dump terminated\n");
+ delete_json_obj();
return 1;
}
delete_json_obj();
diff --git a/ip/ipfou.c b/ip/ipfou.c
index 9c69777..5db137d 100644
--- a/ip/ipfou.c
+++ b/ip/ipfou.c
@@ -322,6 +322,7 @@ static int do_show(int argc, char **argv)
new_json_obj(json);
if (rtnl_dump_filter(&genl_rth, print_fou_mapping, stdout) < 0) {
fprintf(stderr, "Dump terminated\n");
+ delete_json_obj();
return 1;
}
delete_json_obj();
diff --git a/ip/ipila.c b/ip/ipila.c
index 475c35b..cbc3dd3 100644
--- a/ip/ipila.c
+++ b/ip/ipila.c
@@ -154,6 +154,7 @@ static int do_list(int argc, char **argv)
new_json_obj(json);
if (rtnl_dump_filter(&genl_rth, print_ila_mapping, stdout) < 0) {
fprintf(stderr, "Dump terminated\n");
+ delete_json_obj();
return 1;
}
delete_json_obj();
diff --git a/ip/ipnetconf.c b/ip/ipnetconf.c
index bb0ebe1..f5ebb1a 100644
--- a/ip/ipnetconf.c
+++ b/ip/ipnetconf.c
@@ -214,6 +214,7 @@ dump:
*/
if (errno == EOPNOTSUPP &&
filter.family == AF_UNSPEC) {
+ delete_json_obj();
filter.family = AF_INET;
goto dump;
}
diff --git a/ip/ipnexthop.c b/ip/ipnexthop.c
index 9478aa5..36dafa1 100644
--- a/ip/ipnexthop.c
+++ b/ip/ipnexthop.c
@@ -732,6 +732,7 @@ static int ipnh_get_id(__u32 id)
new_json_obj(json);
if (print_nexthop(answer, (void *)stdout) < 0) {
+ delete_json_obj();
free(answer);
return -1;
}
@@ -817,6 +818,7 @@ static int ipnh_list_flush(int argc, char **argv, int action)
new_json_obj(json);
if (rtnl_dump_filter(&rth, print_nexthop, stdout) < 0) {
+ delete_json_obj();
fprintf(stderr, "Dump terminated\n");
return -2;
}
@@ -892,6 +894,7 @@ static int ipnh_bucket_list(int argc, char **argv)
new_json_obj(json);
if (rtnl_dump_filter(&rth, print_nexthop_bucket, stdout) < 0) {
+ delete_json_obj();
fprintf(stderr, "Dump terminated\n");
return -2;
}
@@ -932,6 +935,7 @@ static int ipnh_bucket_get_id(__u32 id, __u16 bucket_index)
new_json_obj(json);
if (print_nexthop_bucket(answer, (void *)stdout) < 0) {
+ delete_json_obj();
free(answer);
return -1;
}
diff --git a/ip/iproute.c b/ip/iproute.c
index 9922cb0..6e359fa 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -1962,6 +1962,7 @@ static int iproute_list_flush_or_save(int argc, char **argv, int action)
if (rtnl_dump_filter_errhndlr(&rth, filter_fn, stdout,
save_route_errhndlr, NULL) < 0) {
fprintf(stderr, "Dump terminated\n");
+ delete_json_obj();
return -2;
}
@@ -2157,18 +2158,21 @@ static int iproute_get(int argc, char **argv)
if (print_route(answer, (void *)stdout) < 0) {
fprintf(stderr, "An error :-)\n");
+ delete_json_obj();
free(answer);
return -1;
}
if (answer->nlmsg_type != RTM_NEWROUTE) {
fprintf(stderr, "Not a route?\n");
+ delete_json_obj();
free(answer);
return -1;
}
len -= NLMSG_LENGTH(sizeof(*r));
if (len < 0) {
fprintf(stderr, "Wrong len %d\n", len);
+ delete_json_obj();
free(answer);
return -1;
}
@@ -2180,6 +2184,7 @@ static int iproute_get(int argc, char **argv)
r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]);
} else if (!tb[RTA_SRC]) {
fprintf(stderr, "Failed to connect the route\n");
+ delete_json_obj();
free(answer);
return -1;
}
@@ -2202,6 +2207,7 @@ static int iproute_get(int argc, char **argv)
if (print_route(answer, (void *)stdout) < 0) {
fprintf(stderr, "An error :-)\n");
+ delete_json_obj();
free(answer);
return -1;
}
diff --git a/ip/iprule.c b/ip/iprule.c
index 4166073..7307908 100644
--- a/ip/iprule.c
+++ b/ip/iprule.c
@@ -718,6 +718,7 @@ static int iprule_list_flush_or_save(int argc, char **argv, int action)
new_json_obj(json);
if (rtnl_dump_filter(&rth, filter_fn, stdout) < 0) {
fprintf(stderr, "Dump terminated\n");
+ delete_json_obj();
return 1;
}
delete_json_obj();
diff --git a/ip/iptuntap.c b/ip/iptuntap.c
index 385d2bd..ff88844 100644
--- a/ip/iptuntap.c
+++ b/ip/iptuntap.c
@@ -444,6 +444,7 @@ static int do_show(int argc, char **argv)
if (rtnl_dump_filter(&rth, print_tuntap, NULL) < 0) {
fprintf(stderr, "Dump terminated\n");
+ delete_json_obj();
return -1;
}
diff --git a/ip/tunnel.c b/ip/tunnel.c
index 88585cf..51a0016 100644
--- a/ip/tunnel.c
+++ b/ip/tunnel.c
@@ -439,11 +439,13 @@ int do_tunnels_list(struct tnl_print_nlmsg_info *info)
new_json_obj(json);
if (rtnl_linkdump_req(&rth, preferred_family) < 0) {
perror("Cannot send dump request\n");
+ delete_json_obj();
return -1;
}
if (rtnl_dump_filter(&rth, print_nlmsg_tunnel, info) < 0) {
fprintf(stderr, "Dump terminated\n");
+ delete_json_obj();
return -1;
}
delete_json_obj();
diff --git a/tc/tc_filter.c b/tc/tc_filter.c
index 71be2e8..5a2a6ba 100644
--- a/tc/tc_filter.c
+++ b/tc/tc_filter.c
@@ -738,6 +738,7 @@ static int tc_filter_list(int cmd, int argc, char **argv)
new_json_obj(json);
if (rtnl_dump_filter(&rth, print_filter, stdout) < 0) {
fprintf(stderr, "Dump terminated\n");
+ delete_json_obj();
return 1;
}
delete_json_obj();
diff --git a/tc/tc_qdisc.c b/tc/tc_qdisc.c
index b79029d..77f4d97 100644
--- a/tc/tc_qdisc.c
+++ b/tc/tc_qdisc.c
@@ -435,6 +435,7 @@ static int tc_qdisc_list(int argc, char **argv)
new_json_obj(json);
if (rtnl_dump_filter(&rth, print_qdisc, stdout) < 0) {
fprintf(stderr, "Dump terminated\n");
+ delete_json_obj();
return 1;
}
delete_json_obj();
--
2.27.0

View File

@ -0,0 +1,34 @@
From 1cf50a1f2723764eb53fad7c5ff8754835806df0 Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Mon, 29 May 2023 23:42:16 +0200
Subject: [PATCH] iproute_lwtunnel: fix array boundary check
seg6_mode_types is made up of 5 elements, so ARRAY_SIZE(seg6_mode_types)
evaluates to 5. Thus, when mode = 5, this function returns
seg6_mode_types[5], resulting in an out-of-bound access.
Fix this bailing out when mode is equal to or greater than 5.
Fixes: cf87da417bb4 ("iproute: add support for seg6 l2encap mode")
Signed-off-by: Andrea Claudi <aclaudi@redhat.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
ip/iproute_lwtunnel.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
index 96de3b20..94985972 100644
--- a/ip/iproute_lwtunnel.c
+++ b/ip/iproute_lwtunnel.c
@@ -140,7 +140,7 @@ static const char *seg6_mode_types[] = {
static const char *format_seg6mode_type(int mode)
{
- if (mode < 0 || mode > ARRAY_SIZE(seg6_mode_types))
+ if (mode < 0 || mode >= ARRAY_SIZE(seg6_mode_types))
return "<unknown>";
return seg6_mode_types[mode];
--
2.27.0

View File

@ -0,0 +1,178 @@
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

View File

@ -0,0 +1,67 @@
From 8cc2eac60d5f1f5ec2c40d02c0003731c8b610dc Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Mon, 10 Apr 2023 16:22:51 -0700
Subject: [PATCH] iptunnel: detect protocol mismatch on tunnel change
If attempt is made to change an IPv6 tunnel by using IPv4
parameters, a stack overflow would happen and garbage request
would be passed to kernel.
Example:
ip tunnel add gre1 mode ip6gre local 2001:db8::1 remote 2001:db8::2 ttl 255
ip tunnel change gre1 mode gre local 192.168.0.0 remote 192.168.0.1 ttl 255
The second command should fail because it attempting set IPv4 addresses
on a GRE tunnel that is IPv6.
Do best effort detection of this mismatch by giving a bigger buffer to get
tunnel request, and checking that the IP header is IPv4. It is still possible
but unlikely that byte would match in IPv6 tunnel paramater, but good enough
to catch the obvious cases.
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1032642
Tested-by: Luca Boccassi <bluca@debian.org>
Reported-by: Robin <imer@imer.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
ip/iptunnel.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/ip/iptunnel.c b/ip/iptunnel.c
index 02c3670b..b6da1459 100644
--- a/ip/iptunnel.c
+++ b/ip/iptunnel.c
@@ -17,6 +17,7 @@
#include <net/if_arp.h>
#include <linux/ip.h>
#include <linux/if_tunnel.h>
+#include <linux/ip6_tunnel.h>
#include "rt_names.h"
#include "utils.h"
@@ -172,11 +173,20 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
if (get_ifname(p->name, *argv))
invarg("\"name\" not a valid ifname", *argv);
if (cmd == SIOCCHGTUNNEL && count == 0) {
- struct ip_tunnel_parm old_p = {};
+ union {
+ struct ip_tunnel_parm ip_tnl;
+ struct ip6_tnl_parm2 ip6_tnl;
+ } old_p = {};
if (tnl_get_ioctl(*argv, &old_p))
return -1;
- *p = old_p;
+
+ if (old_p.ip_tnl.iph.version != 4 ||
+ old_p.ip_tnl.iph.ihl != 5)
+ invarg("\"name\" is not an ip tunnel",
+ *argv);
+
+ *p = old_p.ip_tnl;
}
}
count++;
--
2.27.0

View File

@ -0,0 +1,162 @@
From b134c2c344582f12d3e350168334e50b91a99c7d Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Mon, 8 May 2023 19:25:33 -0700
Subject: [PATCH] m_action: fix warning of overwrite of const string
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The function get_action_kind() searches first for the given
action, then rescans on failure for "gact". In the process,
it would overwrite the argument. Avoid the warning
by using a const argument and not copying.
The problem dates back to pre-git history.
m_action.c: In function get_action_kind:
m_action.c:126:17: warning: write to string literal [-Wanalyzer-write-to-string-literal]
126 | strcpy(str, "gact");
| ^~~~~~~~~~~~~~~~~~~
do_action: events 1-6
|
| 853 | int do_action(int argc, char **argv)
| | ^~~~~~~~~
| | |
| | (1) entry to do_action
|......
| 858 | while (argc > 0) {
| | ~~~~~~~~
| | |
| | (2) following true branch...
| 859 |
| 860 | if (matches(*argv, "add") == 0) {
| | ~~~~~~~~~~~~~~~~~~~~~~
| | ||
| | |(3) ...to here
| | (4) following false branch...
| 861 | ret = tc_action_modify(RTM_NEWACTION,
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (5) ...to here
| | (6) calling tc_action_modify from do_action
| 862 | NLM_F_EXCL | NLM_F_CREATE,
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~
| 863 | &argc, &argv);
| | ~~~~~~~~~~~~~
|
+--> tc_action_modify: events 7-8
|
| 715 | static int tc_action_modify(int cmd, unsigned int flags,
| | ^~~~~~~~~~~~~~~~
| | |
| | (7) entry to tc_action_modify
|......
| 735 | if (parse_action(&argc, &argv, TCA_ACT_TAB, &req.n)) {
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (8) calling parse_action from tc_action_modify
|
+--> parse_action: events 9-18
|
| 203 | int parse_action(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n)
| | ^~~~~~~~~~~~
| | |
| | (9) entry to parse_action
|......
| 217 | if (argc <= 0)
| | ~
| | |
| | (10) following false branch...
|......
| 220 | tail2 = addattr_nest(n, MAX_MSG, tca_id);
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (11) ...to here
| 221 |
| 222 | while (argc > 0) {
| | ~~~~~~~~
| | |
| | (12) following true branch...
| 223 |
| 224 | memset(k, 0, sizeof(k));
| | ~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (13) ...to here
| 225 |
| 226 | if (strcmp(*argv, "action") == 0) {
| | ~
| | |
| | (14) following true branch (when the strings are equal)...
| 227 | argc--;
| | ~~~~~~
| | |
| | (15) ...to here
|......
| 231 | if (!gact_ld)
| | ~
| | |
| | (16) following true branch...
| 232 | get_action_kind("gact");
| | ~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (17) ...to here
| | (18) calling get_action_kind from parse_action
|
+--> get_action_kind: events 19-24
|
| 86 | static struct action_util *get_action_kind(char *str)
| | ^~~~~~~~~~~~~~~
| | |
| | (19) entry to get_action_kind
|......
| 114 | if (a == NULL)
| | ~
| | |
| | (20) following true branch (when a is NULL)...
| 115 | goto noexist;
| | ~~~~
| | |
| | (21) ...to here
|......
| 124 | if (!looked4gact) {
| | ~
| | |
| | (22) following true branch (when looked4gact == 0)...
| 125 | looked4gact = 1;
| 126 | strcpy(str, "gact");
| | ~~~~~~~~~~~~~~~~~~~
| | |
| | (23) ...to here
| | (24) write to string literal here
|
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
tc/m_action.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tc/m_action.c b/tc/m_action.c
index a446cabd..16474c56 100644
--- a/tc/m_action.c
+++ b/tc/m_action.c
@@ -83,7 +83,7 @@ static int parse_noaopt(struct action_util *au, int *argc_p,
return -1;
}
-static struct action_util *get_action_kind(char *str)
+static struct action_util *get_action_kind(const char *str)
{
static void *aBODY;
void *dlh;
@@ -123,7 +123,7 @@ noexist:
#ifdef CONFIG_GACT
if (!looked4gact) {
looked4gact = 1;
- strcpy(str, "gact");
+ str = "gact";
goto restart_s;
}
#endif
--
2.27.0

View File

@ -0,0 +1,197 @@
From 6c266d7c22a8f4f631d278ba6102f1b1d2bca148 Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Mon, 8 May 2023 19:36:14 -0700
Subject: [PATCH] netem: fix NULL deref on allocation failure
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
q_netem.c: In function get_distribution:
q_netem.c:159:35: warning: dereference of possibly-NULL data [CWE-690] [-Wanalyzer-possible-null-dereference]
159 | data[n++] = x;
| ~~~~~~~~~~^~~
netem_parse_opt: events 1-24
|
| 192 | static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv,
| | ^~~~~~~~~~~~~~~
| | |
| | (1) entry to netem_parse_opt
|......
| 212 | for ( ; argc > 0; --argc, ++argv) {
| | ~~~~~~~~
| | |
| | (2) following true branch (when argc > 0)...
| 213 | if (matches(*argv, "limit") == 0) {
| | ~~~~~~~~~~~~~~~~~~~~~~~~
| | ||
| | |(3) ...to here
| | (4) following true branch...
|......
| 219 | } else if (matches(*argv, "latency") == 0 ||
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | || |
| | |(5) ...to here (8) following true branch...
| | (6) following true branch...
| 220 | matches(*argv, "delay") == 0) {
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (7) ...to here
|......
| 243 | } else if (matches(*argv, "loss") == 0 ||
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | || |
| | |(9) ...to here (12) following true branch...
| | (10) following true branch...
| 244 | matches(*argv, "drop") == 0) {
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (11) ...to here
|......
| 366 | } else if (matches(*argv, "ecn") == 0) {
| | ~~~~~~~~~~~~~~~~~~~~~~
| | ||
| | |(13) ...to here
| | (14) following true branch...
| 367 | present[TCA_NETEM_ECN] = 1;
| 368 | } else if (matches(*argv, "reorder") == 0) {
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~
| | ||
| | |(15) ...to here
| | (16) following true branch...
|......
| 383 | } else if (matches(*argv, "corrupt") == 0) {
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~
| | ||
| | |(17) ...to here
| | (18) following true branch...
|......
| 398 | } else if (matches(*argv, "gap") == 0) {
| | ~~~~~~~~~~~~~~~~~~~~~~
| | ||
| | |(19) ...to here
| | (20) following true branch...
|......
| 404 | } else if (matches(*argv, "duplicate") == 0) {
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | ||
| | |(21) ...to here
| | (22) following true branch...
|......
| 417 | } else if (matches(*argv, "distribution") == 0) {
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | ||
| | |(23) ...to here
| | (24) following false branch...
|
netem_parse_opt: event 25
|
|../include/utils.h:50:29:
| 50 | #define NEXT_ARG() do { argv++; if (--argc <= 0) incomplete_command(); } while(0)
| | ~~~~^~
| | |
| | (25) ...to here
q_netem.c:418:25: note: in expansion of macro NEXT_ARG
| 418 | NEXT_ARG();
| | ^~~~~~~~
|
netem_parse_opt: event 26
|
|../include/utils.h:50:36:
| 50 | #define NEXT_ARG() do { argv++; if (--argc <= 0) incomplete_command(); } while(0)
| | ^
| | |
| | (26) following false branch (when argc != 0)...
q_netem.c:418:25: note: in expansion of macro NEXT_ARG
| 418 | NEXT_ARG();
| | ^~~~~~~~
|
netem_parse_opt: events 27-29
|
| 419 | dist_data = calloc(sizeof(dist_data[0]), MAX_DIST);
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (27) ...to here
| | (28) this call could return NULL
| 420 | dist_size = get_distribution(*argv, dist_data, MAX_DIST);
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (29) calling get_distribution from netem_parse_opt
|
+--> get_distribution: events 30-31
|
| 124 | static int get_distribution(const char *type, __s16 *data, int maxdata)
| | ^~~~~~~~~~~~~~~~
| | |
| | (30) entry to get_distribution
|......
| 135 | if (f == NULL) {
| | ~
| | |
| | (31) following false branch (when f is non-NULL)...
|
get_distribution: event 32
|
|cc1:
| (32): ...to here
|
get_distribution: events 33-35
|
| 142 | while (getline(&line, &len, f) != -1) {
| | ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
| | |
| | (33) following true branch...
|......
| 145 | if (*line == '\n' || *line == '#')
| | ~~~~~~
| | ||
| | |(34) ...to here
| | (35) following false branch...
|
get_distribution: event 36
|
|cc1:
| (36): ...to here
|
get_distribution: events 37-41
|
| 150 | if (endp == p)
| | ^
| | |
| | (37) following false branch...
|......
| 153 | if (n >= maxdata) {
| | ~
| | |
| | (38) ...to here
| | (39) following false branch (when n < maxdata)...
|......
| 159 | data[n++] = x;
| | ~~~~~~~~~~~~~
| | | |
| | | (41) data + (long unsigned int)n * 2 could be NULL: unchecked value from (28)
| | (40) ...to here
|
Fixes: c1b81cb5fe92 ("netem potential dist table overflow")
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
tc/q_netem.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tc/q_netem.c b/tc/q_netem.c
index 26402e9a..d1d79b0b 100644
--- a/tc/q_netem.c
+++ b/tc/q_netem.c
@@ -417,6 +417,9 @@ random_loss_model:
} else if (matches(*argv, "distribution") == 0) {
NEXT_ARG();
dist_data = calloc(sizeof(dist_data[0]), MAX_DIST);
+ if (dist_data == NULL)
+ return -1;
+
dist_size = get_distribution(*argv, dist_data, MAX_DIST);
if (dist_size <= 0) {
free(dist_data);
--
2.27.0

View File

@ -0,0 +1,364 @@
From d348d1d6466a4a712b47612c1e9388161334fc7a Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Mon, 8 May 2023 19:42:03 -0700
Subject: [PATCH] nstat: fix potential NULL deref
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reported as:
CC nstat
nstat.c: In function load_ugly_table:
nstat.c:205:24: warning: dereference of NULL p [CWE-476] [-Wanalyzer-null-dereference]
205 | while (*p) {
| ^~
main: events 1-14
|
| 575 | int main(int argc, char *argv[])
| | ^~~~
| | |
| | (1) entry to main
|......
| 635 | if (scan_interval > 0) {
| | ~
| | |
| | (2) following true branch...
| 636 | if (time_constant == 0)
| | ~~~~~~~~~~~~~~~~~~
| | |
| | (3) ...to here
|......
| 640 | if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
| | ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | | |
| | | (4) when socket succeeds
| | (5) following false branch (when fd >= 0)...
|......
| 644 | if (bind(fd, (struct sockaddr *)&sun, 2+1+strlen(sun.sun_path+1)) < 0) {
| | ~ ~~~~~~~~~~~~~~~~~~~~~~
| | | |
| | (7) following false branch... (6) ...to here
|......
| 648 | if (listen(fd, 5) < 0) {
| | ~~~~~~~~~~~~~~
| | ||
| | |(8) ...to here
| | |(9) when listen succeeds
| | (10) following false branch...
|......
| 652 | if (daemon(0, 0)) {
| | ~~~~~~~~~~~~~
| | ||
| | |(11) ...to here
| | (12) following false branch...
|......
| 656 | signal(SIGPIPE, SIG_IGN);
| | ~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (13) ...to here
| 657 | signal(SIGCHLD, sigchild);
| 658 | server_loop(fd);
| | ~~~~~~~~~~~~~~~
| | |
| | (14) calling server_loop from main
|
+--> server_loop: events 15-16
|
| 472 | static void server_loop(int fd)
| | ^~~~~~~~~~~
| | |
| | (15) entry to server_loop
|......
| 483 | load_netstat();
| | ~~~~~~~~~~~~~~
| | |
| | (16) calling load_netstat from server_loop
|
+--> load_netstat: events 17-20
|
| 302 | static void load_netstat(void)
| | ^~~~~~~~~~~~
| | |
| | (17) entry to load_netstat
|......
| 306 | if (fp) {
| | ~
| | |
| | (18) following true branch (when fp is non-NULL)...
| 307 | load_ugly_table(fp);
| | ~~~~~~~~~~~~~~~~~~~
| | |
| | (19) ...to here
| | (20) calling load_ugly_table from load_netstat
|
+--> load_ugly_table: events 21-26
|
| 178 | static void load_ugly_table(FILE *fp)
| | ^~~~~~~~~~~~~~~
| | |
| | (21) entry to load_ugly_table
| 179 | {
| 180 | char *buf = NULL;
| | ~~~
| | |
| | (22) buf is NULL
|......
| 186 | while ((nread = getline(&buf, &buflen, fp)) != -1) {
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (23) following true branch...
|......
| 192 | p = strchr(buf, ':');
| | ~~~~~~~~~~~~~~~~
| | |
| | (24) ...to here
| | (25) when strchr returns non-NULL
| 193 | if (!p) {
| | ~
| | |
| | (26) following false branch (when p is non-NULL)...
|
load_ugly_table: event 27
|
|cc1:
| (27): ...to here
|
load_ugly_table: events 28-40
|
| 205 | while (*p) {
| | ^~
| | |
| | (28) following true branch...
| | (40) dereference of NULL p
|......
| 208 | if ((next = strchr(p, ' ')) != NULL)
| | ~ ~~~~~~~~~~~~~~
| | | |
| | | (29) ...to here
| | | (30) when strchr returns NULL
| | (31) following false branch (when next is NULL)...
| 209 | *next++ = 0;
| 210 | else if ((next = strchr(p, '\n')) != NULL)
| | ~ ~~~~~~~~~~~~~~~
| | | |
| | | (32) ...to here
| | | (33) when strchr returns NULL
| | (34) following false branch (when next is NULL)...
| 211 | *next++ = 0;
| 212 | if (off < sizeof(idbuf)) {
| | ~~~~~~~~~~~~~~~~~~~~
| | | |
| | | (35) ...to here
| | (36) following false branch...
|......
| 216 | n = malloc(sizeof(*n));
| | ~~~~~~~~~~~~~~~~~~
| | |
| | (37) ...to here
| 217 | if (!n) {
| | ~
| | |
| | (38) following false branch (when n is non-NULL)...
|......
| 221 | n->id = strdup(idbuf);
| | ~~~~~~~~~~~~~
| | |
| | (39) ...to here
|
nstat.c:254:35: warning: dereference of NULL n [CWE-476] [-Wanalyzer-null-dereference]
254 | n = n->next;
| ~~^~~~~~~~~
main: events 1-14
|
| 575 | int main(int argc, char *argv[])
| | ^~~~
| | |
| | (1) entry to main
|......
| 635 | if (scan_interval > 0) {
| | ~
| | |
| | (2) following true branch...
| 636 | if (time_constant == 0)
| | ~~~~~~~~~~~~~~~~~~
| | |
| | (3) ...to here
|......
| 640 | if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
| | ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | | |
| | | (4) when socket succeeds
| | (5) following false branch (when fd >= 0)...
|......
| 644 | if (bind(fd, (struct sockaddr *)&sun, 2+1+strlen(sun.sun_path+1)) < 0) {
| | ~ ~~~~~~~~~~~~~~~~~~~~~~
| | | |
| | (7) following false branch... (6) ...to here
|......
| 648 | if (listen(fd, 5) < 0) {
| | ~~~~~~~~~~~~~~
| | ||
| | |(8) ...to here
| | |(9) when listen succeeds
| | (10) following false branch...
|......
| 652 | if (daemon(0, 0)) {
| | ~~~~~~~~~~~~~
| | ||
| | |(11) ...to here
| | (12) following false branch...
|......
| 656 | signal(SIGPIPE, SIG_IGN);
| | ~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (13) ...to here
| 657 | signal(SIGCHLD, sigchild);
| 658 | server_loop(fd);
| | ~~~~~~~~~~~~~~~
| | |
| | (14) calling server_loop from main
|
+--> server_loop: events 15-16
|
| 472 | static void server_loop(int fd)
| | ^~~~~~~~~~~
| | |
| | (15) entry to server_loop
|......
| 483 | load_netstat();
| | ~~~~~~~~~~~~~~
| | |
| | (16) calling load_netstat from server_loop
|
+--> load_netstat: events 17-20
|
| 302 | static void load_netstat(void)
| | ^~~~~~~~~~~~
| | |
| | (17) entry to load_netstat
|......
| 306 | if (fp) {
| | ~
| | |
| | (18) following true branch (when fp is non-NULL)...
| 307 | load_ugly_table(fp);
| | ~~~~~~~~~~~~~~~~~~~
| | |
| | (19) ...to here
| | (20) calling load_ugly_table from load_netstat
|
+--> load_ugly_table: events 21-25
|
| 178 | static void load_ugly_table(FILE *fp)
| | ^~~~~~~~~~~~~~~
| | |
| | (21) entry to load_ugly_table
|......
| 186 | while ((nread = getline(&buf, &buflen, fp)) != -1) {
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (22) following true branch...
|......
| 192 | p = strchr(buf, ':');
| | ~~~~~~~~~~~~~~~~
| | |
| | (23) ...to here
| | (24) when strchr returns non-NULL
| 193 | if (!p) {
| | ~
| | |
| | (25) following false branch (when p is non-NULL)...
|
load_ugly_table: event 26
|
|cc1:
| (26): ...to here
|
load_ugly_table: events 27-28
|
| 205 | while (*p) {
| | ^
| | |
| | (27) following false branch...
|......
| 228 | nread = getline(&buf, &buflen, fp);
| | ~
| | |
| | (28) inlined call to getline from load_ugly_table
|
+--> getline: event 29
|
|/usr/include/bits/stdio.h:120:10:
| 120 | return __getdelim (__lineptr, __n, '\n', __stream);
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (29) ...to here
|
<------+
|
load_ugly_table: events 30-36
|
|nstat.c:229:20:
| 229 | if (nread == -1) {
| | ^
| | |
| | (30) following false branch...
|......
| 234 | count2 = count_spaces(buf);
| | ~~~~~~~~~~~~~~~~~
| | |
| | (31) ...to here
|......
| 239 | if (!p) {
| | ~
| | |
| | (32) following false branch (when p is non-NULL)...
|......
| 244 | *p = 0;
| | ~~~~~~
| | |
| | (33) ...to here
| 245 | if (sscanf(p+1, "%llu", &n->val) != 1) {
| | ~
| | |
| | (34) following false branch...
|......
| 251 | if (skip)
| | ~
| | |
| | (35) ...to here
|......
| 254 | n = n->next;
| | ~~~~~~~~~~~
| | |
| | (36) dereference of NULL n
|
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
misc/nstat.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/misc/nstat.c b/misc/nstat.c
index 0ab92ecb..2c10feaa 100644
--- a/misc/nstat.c
+++ b/misc/nstat.c
@@ -219,9 +219,15 @@ static void load_ugly_table(FILE *fp)
exit(-1);
}
n->id = strdup(idbuf);
+ if (n->id == NULL) {
+ perror("nstat: strdup");
+ exit(-1);
+ }
n->rate = 0;
n->next = db;
db = n;
+ if (next == NULL)
+ break;
p = next;
}
n = db;
--
2.27.0

View File

@ -0,0 +1,87 @@
From 33722349feb9ac8ea77cf658f79940a42261f44d Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Mon, 8 May 2023 20:15:52 -0700
Subject: [PATCH] rdma/utils: fix some analyzer warnings
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add error checks for cases where analyzer thinks it is possible
to us a possibly NULL value.
utils.c: In function get_port_from_argv:
utils.c:76:17: warning: use of NULL where non-null expected [CWE-476] [-Wanalyzer-null-argument]
76 | slash = strchr(rd_argv(rd), '/');
| ^~~~~~~~~~~~~~~~~~~~~~~~
get_port_from_argv: events 1-2
|
| 68 | static int get_port_from_argv(struct rd *rd, uint32_t *port,
| | ^~~~~~~~~~~~~~~~~~
| | |
| | (1) entry to get_port_from_argv
|......
| 76 | slash = strchr(rd_argv(rd), '/');
| | ~
| | |
| | (2) inlined call to rd_argv from get_port_from_argv
|
+--> rd_argv: event 3
|
| 18 | if (!rd_argc(rd))
| | ^
| | |
| | (3) following true branch...
|
<------+
|
get_port_from_argv: events 4-5
|
| 76 | slash = strchr(rd_argv(rd), '/');
| | ^~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (4) ...to here
| | (5) argument 1 (<unknown>) NULL where non-null expected
|
In file included from rdma.h:10,
from utils.c:7:
/usr/include/string.h:246:14: note: argument 1 of strchr must be non-null
246 | extern char *strchr (const char *__s, int __c)
| ^~~~~~
Fixes: 40df8263a0f0 ("rdma: Add dev object")
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
rdma/utils.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/rdma/utils.c b/rdma/utils.c
index 21177b56..a33ff420 100644
--- a/rdma/utils.c
+++ b/rdma/utils.c
@@ -75,6 +75,13 @@ static int get_port_from_argv(struct rd *rd, uint32_t *port,
slash = strchr(rd_argv(rd), '/');
/* if no port found, return 0 */
+ if (slash == NULL) {
+ if (strict_port)
+ return -EINVAL;
+ else
+ return 0;
+ }
+
if (slash++) {
if (*slash == '-') {
if (strict_port)
@@ -747,6 +754,9 @@ struct dev_map *dev_map_lookup(struct rd *rd, bool allow_port_index)
return NULL;
dev_name = strdup(rd_argv(rd));
+ if (!dev_name)
+ return NULL;
+
if (allow_port_index) {
slash = strrchr(dev_name, '/');
if (slash)
--
2.27.0

View File

@ -0,0 +1,30 @@
From 507fe042181c8e481e4463ab66b3f7af897a5500 Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Wed, 7 Jun 2023 18:33:49 -0700
Subject: [PATCH] rt_names: check for malloc() failure
Fixes issue reported by Gcc 13 analayzer.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/rt_names.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lib/rt_names.c b/lib/rt_names.c
index b441e98f..68db74e3 100644
--- a/lib/rt_names.c
+++ b/lib/rt_names.c
@@ -81,6 +81,10 @@ rtnl_hash_initialize(const char *file, struct rtnl_hash_entry **hash, int size)
continue;
entry = malloc(sizeof(*entry));
+ if (entry == NULL) {
+ fprintf(stderr, "malloc error: for entry\n");
+ break;
+ }
entry->id = id;
entry->name = strdup(namebuf);
entry->next = hash[id & (size - 1)];
--
2.27.0

View File

@ -0,0 +1,74 @@
From c90d25e96b010c5837b5db9eaa57f5063f0c2aeb Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Mon, 8 May 2023 20:17:50 -0700
Subject: [PATCH] tc/prio: handle possible truncated kernel response
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reported by -fanalyzer. If kernel did not send full qdisc
info, then uninitialized or null data could be referenced.
q_prio.c: In function prio_print_opt:
q_prio.c:105:57: warning: dereference of NULL 0 [CWE-476] [-Wanalyzer-null-dereference]
105 | print_uint(PRINT_ANY, "bands", "bands %u ", qopt->bands);
| ~~~~^~~~~~~
prio_print_opt: event 1
|
| 98 | if (opt == NULL)
| | ^
| | |
| | (1) following false branch (when opt is non-NULL)...
|
prio_print_opt: event 2
|
|../include/uapi/linux/rtnetlink.h:228:38:
| 228 | #define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
| | ~~~~~~^~~~~~~~~~
| | |
| | (2) ...to here
../include/libnetlink.h:236:19: note: in expansion of macro RTA_PAYLOAD
| 236 | ({ data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
| | ^~~~~~~~~~~
q_prio.c:101:13: note: in expansion of macro parse_rtattr_nested_compat
| 101 | if (parse_rtattr_nested_compat(tb, TCA_PRIO_MAX, opt, qopt,
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~
|
prio_print_opt: event 3
|
|../include/libnetlink.h:236:59:
| 236 | ({ data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
q_prio.c:101:13: note: in expansion of macro parse_rtattr_nested_compat
| 101 | if (parse_rtattr_nested_compat(tb, TCA_PRIO_MAX, opt, qopt,
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~
|
prio_print_opt: events 4-5
|
| 105 | print_uint(PRINT_ANY, "bands", "bands %u ", qopt->bands);
| | ~~~~^~~~~~~
| | |
| | (4) ...to here
| | (5) dereference of NULL <unknown>
|
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
tc/q_prio.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tc/q_prio.c b/tc/q_prio.c
index c8c6477e..a3781ffe 100644
--- a/tc/q_prio.c
+++ b/tc/q_prio.c
@@ -101,6 +101,8 @@ int prio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if (parse_rtattr_nested_compat(tb, TCA_PRIO_MAX, opt, qopt,
sizeof(*qopt)))
return -1;
+ if (qopt == NULL)
+ return -1; /* missing data from kernel */
print_uint(PRINT_ANY, "bands", "bands %u ", qopt->bands);
open_json_array(PRINT_ANY, "priomap");
--
2.27.0

View File

@ -0,0 +1,106 @@
From 0b9b9d659880a3084ec0a5b49f07f387de7b0f0c Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Mon, 8 May 2023 19:21:27 -0700
Subject: [PATCH] tc_exec: don't dereference NULL on calloc failure
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reported as:
tc_exec.c: In function do_exec:
tc_exec.c:103:18: warning: dereference of NULL eu [CWE-476] [-Wanalyzer-null-dereference]
103 | return eu->parse_eopt(eu, argc, argv);
| ~~^~~~~~~~~~~~
do_exec: events 1-6
|
| 81 | int do_exec(int argc, char **argv)
| | ^~~~~~~
| | |
| | (1) entry to do_exec
|......
| 86 | if (argc < 1) {
| | ~
| | |
| | (2) following false branch (when argc > 0)...
|......
| 91 | if (matches(*argv, "help") == 0) {
| | ~~~~~~~~~~~~~~~~~~~~~~~
| | ||
| | |(3) ...to here
| | (4) following true branch...
|......
| 96 | strncpy(kind, *argv, sizeof(kind) - 1);
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (5) ...to here
| 97 |
| 98 | eu = get_exec_kind(kind);
| | ~~~~~~~~~~~~~~~~~~~
| | |
| | (6) calling get_exec_kind from do_exec
|
+--> get_exec_kind: events 7-10
|
| 40 | static struct exec_util *get_exec_kind(const char *name)
| | ^~~~~~~~~~~~~
| | |
| | (7) entry to get_exec_kind
|......
| 63 | if (eu == NULL)
| | ~
| | |
| | (8) following true branch (when eu is NULL)...
| 64 | goto noexist;
| | ~~~~
| | |
| | (9) ...to here
|......
| 72 | if (eu) {
| | ~
| | |
| | (10) following false branch (when eu is NULL)...
|
get_exec_kind: event 11
|
|cc1:
| (11): ...to here
|
<------+
|
do_exec: events 12-13
|
| 98 | eu = get_exec_kind(kind);
| | ^~~~~~~~~~~~~~~~~~~
| | |
| | (12) return of NULL to do_exec from get_exec_kind
|......
| 103 | return eu->parse_eopt(eu, argc, argv);
| | ~~~~~~~~~~~~~~
| | |
| | (13) dereference of NULL eu
|
Fixes: 4bd624467bc6 ("tc: built-in eBPF exec proxy")
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
tc/tc_exec.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/tc/tc_exec.c b/tc/tc_exec.c
index 5d883402..182fbb4c 100644
--- a/tc/tc_exec.c
+++ b/tc/tc_exec.c
@@ -96,6 +96,10 @@ int do_exec(int argc, char **argv)
strncpy(kind, *argv, sizeof(kind) - 1);
eu = get_exec_kind(kind);
+ if (eu == NULL) {
+ fprintf(stderr, "Allocation failed finding exec\n");
+ return -1;
+ }
argc--;
argv++;
--
2.27.0

View File

@ -0,0 +1,318 @@
From c9c1c9d59a6cfe52f380805a3e91a13ab1a28482 Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Mon, 8 May 2023 19:15:43 -0700
Subject: [PATCH] tc_util fix unitialized warning
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
tc_util.c: In function parse_action_control_slash_spaces:
tc_util.c:488:28: warning: use of uninitialized value result2 [CWE-457] [-Wanalyzer-use-of-uninitialized-value]
488 | *result2_p = result2;
| ~~~~~~~~~~~^~~~~~~~~
parse_action_control_slash_spaces: events 1-5
|
| 455 | static int parse_action_control_slash_spaces(int *argc_p, char ***argv_p,
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (1) entry to parse_action_control_slash_spaces
|......
| 461 | int result1 = -1, result2;
| | ~~~~~~~
| | |
| | (2) region created on stack here
| | (3) capacity: 4 bytes
|......
| 467 | switch (ok) {
| | ~~~~~~
| | |
| | (4) following case 0: branch...
|......
| 475 | ret = parse_action_control(&argc, &argv,
| | ~
| | |
| | (5) inlined call to parse_action_control from parse_action_control_slash_spaces
|
+--> parse_action_control: events 6-7
|
| 432 | return __parse_action_control(argc_p, argv_p, result_p,
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (6) ...to here
| | (7) calling __parse_action_control from parse_action_control_slash_spaces
| 433 | allow_num, false);
| | ~~~~~~~~~~~~~~~~~
|
__parse_action_control: events 8-11
|
| 371 | static int __parse_action_control(int *argc_p, char ***argv_p, int *result_p,
| | ^~~~~~~~~~~~~~~~~~~~~~
| | |
| | (8) entry to __parse_action_control
|......
| 378 | if (!argc)
| | ~
| | |
| | (9) following false branch (when argc != 0)...
| 379 | return -1;
| 380 | if (action_a2n(*argv, &result, allow_num) == -1) {
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (10) ...to here
| | (11) calling action_a2n from __parse_action_control
|
+--> action_a2n: events 12-16
|
| 335 | int action_a2n(char *arg, int *result, bool allow_num)
| | ^~~~~~~~~~
| | |
| | (12) entry to action_a2n
|......
| 356 | for (iter = a2n; iter->a; iter++) {
| | ~~~~
| | |
| | (13) following true branch...
| 357 | if (matches(arg, iter->a) != 0)
| | ~~~~~~~~~~~~~~~~~~~~~
| | |
| | (14) ...to here
|......
| 366 | if (result)
| | ~
| | |
| | (15) following true branch (when result is non-NULL)...
| 367 | *result = n;
| | ~~~~~~~~~~~
| | |
| | (16) ...to here
|
<------+
|
__parse_action_control: event 17
|
| 380 | if (action_a2n(*argv, &result, allow_num) == -1) {
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (17) returning to __parse_action_control from action_a2n
|
<------+
|
parse_action_control_slash_spaces: event 18
|
| 475 | ret = parse_action_control(&argc, &argv,
| | ^
| | |
| | (18) inlined call to parse_action_control from parse_action_control_slash_spaces
|
+--> parse_action_control: event 19
|
| 432 | return __parse_action_control(argc_p, argv_p, result_p,
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (19) returning to parse_action_control_slash_spaces from __parse_action_control
| 433 | allow_num, false);
| | ~~~~~~~~~~~~~~~~~
|
<------+
|
parse_action_control_slash_spaces: events 20-24
|
| 477 | if (ret)
| | ^
| | |
| | (20) following false branch...
| 478 | return ret;
| 479 | ok++;
| | ~~~~
| | |
| | (21) ...to here
|......
| 487 | if (ok == 2)
| | ~
| | |
| | (22) following true branch (when ok == 2)...
| 488 | *result2_p = result2;
| | ~~~~~~~~~~~~~~~~~~~~
| | |
| | (23) ...to here
| | (24) use of uninitialized value result2 here
|
tc_util.c:488:28: warning: use of uninitialized value result2 [CWE-457] [-Wanalyzer-use-of-uninitialized-value]
488 | *result2_p = result2;
| ~~~~~~~~~~~^~~~~~~~~
parse_action_control_slash: events 1-5
|
| 505 | int parse_action_control_slash(int *argc_p, char ***argv_p,
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (1) entry to parse_action_control_slash
|......
| 510 | char *p = strchr(*argv, '/');
| | ~~~~~~~~~~~~~~~~~~
| | |
| | (2) when strchr returns NULL
| 511 |
| 512 | if (!p)
| | ~
| | |
| | (3) following true branch (when p is NULL)...
| 513 | return parse_action_control_slash_spaces(argc_p, argv_p,
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (4) ...to here
| | (5) calling parse_action_control_slash_spaces from parse_action_control_slash
| 514 | result1_p, result2_p,
| | ~~~~~~~~~~~~~~~~~~~~~
| 515 | allow_num);
| | ~~~~~~~~~~
|
+--> parse_action_control_slash_spaces: events 6-10
|
| 455 | static int parse_action_control_slash_spaces(int *argc_p, char ***argv_p,
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (6) entry to parse_action_control_slash_spaces
|......
| 461 | int result1 = -1, result2;
| | ~~~~~~~
| | |
| | (7) region created on stack here
| | (8) capacity: 4 bytes
|......
| 467 | switch (ok) {
| | ~~~~~~
| | |
| | (9) following case 0: branch...
|......
| 475 | ret = parse_action_control(&argc, &argv,
| | ~
| | |
| | (10) inlined call to parse_action_control from parse_action_control_slash_spaces
|
+--> parse_action_control: events 11-12
|
| 432 | return __parse_action_control(argc_p, argv_p, result_p,
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (11) ...to here
| | (12) calling __parse_action_control from parse_action_control_slash_spaces
| 433 | allow_num, false);
| | ~~~~~~~~~~~~~~~~~
|
__parse_action_control: events 13-16
|
| 371 | static int __parse_action_control(int *argc_p, char ***argv_p, int *result_p,
| | ^~~~~~~~~~~~~~~~~~~~~~
| | |
| | (13) entry to __parse_action_control
|......
| 378 | if (!argc)
| | ~
| | |
| | (14) following false branch (when argc != 0)...
| 379 | return -1;
| 380 | if (action_a2n(*argv, &result, allow_num) == -1) {
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (15) ...to here
| | (16) calling action_a2n from __parse_action_control
|
+--> action_a2n: events 17-21
|
| 335 | int action_a2n(char *arg, int *result, bool allow_num)
| | ^~~~~~~~~~
| | |
| | (17) entry to action_a2n
|......
| 356 | for (iter = a2n; iter->a; iter++) {
| | ~~~~
| | |
| | (18) following true branch...
| 357 | if (matches(arg, iter->a) != 0)
| | ~~~~~~~~~~~~~~~~~~~~~
| | |
| | (19) ...to here
|......
| 366 | if (result)
| | ~
| | |
| | (20) following true branch (when result is non-NULL)...
| 367 | *result = n;
| | ~~~~~~~~~~~
| | |
| | (21) ...to here
|
<------+
|
__parse_action_control: event 22
|
| 380 | if (action_a2n(*argv, &result, allow_num) == -1) {
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (22) returning to __parse_action_control from action_a2n
|
<------+
|
parse_action_control_slash_spaces: event 23
|
| 475 | ret = parse_action_control(&argc, &argv,
| | ^
| | |
| | (23) inlined call to parse_action_control from parse_action_control_slash_spaces
|
+--> parse_action_control: event 24
|
| 432 | return __parse_action_control(argc_p, argv_p, result_p,
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (24) returning to parse_action_control_slash_spaces from __parse_action_control
| 433 | allow_num, false);
| | ~~~~~~~~~~~~~~~~~
|
<------+
|
parse_action_control_slash_spaces: events 25-29
|
| 477 | if (ret)
| | ^
| | |
| | (25) following false branch...
| 478 | return ret;
| 479 | ok++;
| | ~~~~
| | |
| | (26) ...to here
|......
| 487 | if (ok == 2)
| | ~
| | |
| | (27) following true branch (when ok == 2)...
| 488 | *result2_p = result2;
| | ~~~~~~~~~~~~~~~~~~~~
| | |
| | (28) ...to here
| | (29) use of uninitialized value result2 here
|
Fixes: e67aba559581 ("tc: actions: add helpers to parse and print control actions")
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
tc/tc_util.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tc/tc_util.c b/tc/tc_util.c
index 0714134e..ed9efa70 100644
--- a/tc/tc_util.c
+++ b/tc/tc_util.c
@@ -458,7 +458,7 @@ static int parse_action_control_slash_spaces(int *argc_p, char ***argv_p,
{
int argc = *argc_p;
char **argv = *argv_p;
- int result1 = -1, result2;
+ int result1 = -1, result2 = -1;
int *result_p = &result1;
int ok = 0;
int ret;
--
2.27.0

View File

@ -2,7 +2,7 @@
Name: iproute
Version: 5.15.0
Epoch: 1
Release: 13
Release: 14
Summary: Linux network configuration utilities
License: GPLv2+ and Public Domain
URL: https://kernel.org/pub/linux/utils/net/iproute2/
@ -29,6 +29,21 @@ Patch6013: backport-ip-address-Fix-memory-leak-when-specifying-device.patch
Patch6014: backport-ip-neigh-Fix-memory-leak-when-doing-get.patch
Patch6015: backport-mptcp-Fix-memory-leak-when-doing-endpoint-show.patch
Patch6016: backport-mptcp-Fix-memory-leak-when-getting-limits.patch
Patch6017: backport-iptunnel-detect-protocol-mismatch-on-tunnel-change.patch
Patch6018: backport-ipnetns-fix-fd-leak-with-ip-netns-set.patch
Patch6019: backport-iproute2-optimize-code-and-fix-some-mem-leak-risk.patch
Patch6020: backport-ipmaddr-fix-dereference-of-NULL-on-malloc-failure.patch
Patch6021: backport-iproute_lwtunnel-fix-possible-use-of-NULL-when-mallo.patch
Patch6022: backport-tc_util-fix-unitialized-warning.patch
Patch6023: backport-tc_exec-don-t-dereference-NULL-on-calloc-failure.patch
Patch6024: backport-m_action-fix-warning-of-overwrite-of-const-string.patch
Patch6025: backport-netem-fix-NULL-deref-on-allocation-failure.patch
Patch6026: backport-nstat-fix-potential-NULL-deref.patch
Patch6027: backport-rdma-utils-fix-some-analyzer-warnings.patch
Patch6028: backport-tc-prio-handle-possible-truncated-kernel-response.patch
Patch6029: backport-iproute_lwtunnel-fix-array-boundary-check.patch
Patch6030: backport-rt_names-check-for-malloc-failure.patch
Patch9000: feature-iproute-add-support-for-ipvlan-l2e-mode.patch
Patch9001: bugfix-iproute2-cancel-some-test-cases.patch
@ -107,6 +122,25 @@ install -m 0644 lib/libnetlink.a %{buildroot}%{_libdir}/libnetlink.a
%{_mandir}/*
%changelog
* Thu Aug 17 2023 gaoxingwang <gaoxingwang1@huawei.com> - 1:5.15.0-14
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:ipnetns: fix fd leak with 'ip netns set'
iproute2: optimize code and fix some mem-leak risk
iproute_lwtunnel: fix array boundary check
iproute_lwtunnel: fix possible use of NULL when malloc()
m_action: fix warning of overwrite of const string
netem: fix NULL deref on allocation failure
nstat: fix potential NULL deref
rdma/utils: fix some analyzer warnings
rt_names: check for malloc() failure
tc/prio: handle possible truncated kernel response
tc_exec: don't dereference NULL on calloc failure
tc_util fix unitialized warning
iptunnel: detect protocol mismatch on tunnel change
ipmaddr: fix dereference of NULL on malloc() failure
* Thu Mar 02 2023 jiangheng <jiangheng14@huawei.com> - 1:5.15.0-13
- Type:bugfix
- ID:NA