iproute/backport-netem-fix-NULL-deref-on-allocation-failure.patch
gaoxingwang 552d5e248f backport patches to fix bugs
(cherry picked from commit 2e9232daaeeab8917abc9a7830b7a9195d7a1da0)
2023-08-17 17:20:22 +08:00

198 lines
9.3 KiB
Diff
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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