lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Fri,  9 Feb 2024 09:06:17 -0800
From: Stephen Hemminger <stephen@...workplumber.org>
To: netdev@...r.kernel.org
Cc: Stephen Hemminger <stephen@...workplumber.org>
Subject: [RFC iproute2] tc/u32: use standard flexible array

The code to parse selectors was depending on C extension to implement
the array of keys. This would cause warnings if built with clang.
Instead use ISO C99 flexible array.

Also the maximum number of keys was hardcoded already in two places.

Signed-off-by: Stephen Hemminger <stephen@...workplumber.org>
---
 tc/f_u32.c | 46 +++++++++++++++++++++++++++-------------------
 1 file changed, 27 insertions(+), 19 deletions(-)

diff --git a/tc/f_u32.c b/tc/f_u32.c
index 913ec1de435d..a6e699d53d24 100644
--- a/tc/f_u32.c
+++ b/tc/f_u32.c
@@ -21,6 +21,8 @@
 #include "utils.h"
 #include "tc_util.h"
 
+#define SEL_MAX_KEYS	128
+
 static void explain(void)
 {
 	fprintf(stderr,
@@ -129,7 +131,7 @@ static int pack_key(struct tc_u32_sel *sel, __u32 key, __u32 mask,
 		}
 	}
 
-	if (hwm >= 128)
+	if (hwm >= SEL_MAX_KEYS)
 		return -1;
 	if (off % 4)
 		return -1;
@@ -1017,10 +1019,7 @@ static __u32 u32_hash_fold(struct tc_u32_key *key)
 static int u32_parse_opt(struct filter_util *qu, char *handle,
 			 int argc, char **argv, struct nlmsghdr *n)
 {
-	struct {
-		struct tc_u32_sel sel;
-		struct tc_u32_key keys[128];
-	} sel = {};
+	struct tc_u32_sel *sel;
 	struct tcmsg *t = NLMSG_DATA(n);
 	struct rtattr *tail;
 	int sel_ok = 0, terminal_ok = 0;
@@ -1037,12 +1036,18 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
 	if (argc == 0)
 		return 0;
 
+	sel = alloca(sizeof(*sel) + SEL_MAX_KEYS * sizeof(struct tc_u32_key));
+	if (sel == NULL)
+		return -1;
+
+	memset(sel, 0, sizeof(*sel) + SEL_MAX_KEYS * sizeof(struct tc_u32_key));
+
 	tail = addattr_nest(n, MAX_MSG, TCA_OPTIONS);
 
 	while (argc > 0) {
 		if (matches(*argv, "match") == 0) {
 			NEXT_ARG();
-			if (parse_selector(&argc, &argv, &sel.sel, n)) {
+			if (parse_selector(&argc, &argv, sel, n)) {
 				fprintf(stderr, "Illegal \"match\"\n");
 				return -1;
 			}
@@ -1050,14 +1055,14 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
 			continue;
 		} else if (matches(*argv, "offset") == 0) {
 			NEXT_ARG();
-			if (parse_offset(&argc, &argv, &sel.sel)) {
+			if (parse_offset(&argc, &argv, sel)) {
 				fprintf(stderr, "Illegal \"offset\"\n");
 				return -1;
 			}
 			continue;
 		} else if (matches(*argv, "hashkey") == 0) {
 			NEXT_ARG();
-			if (parse_hashkey(&argc, &argv, &sel.sel)) {
+			if (parse_hashkey(&argc, &argv, sel)) {
 				fprintf(stderr, "Illegal \"hashkey\"\n");
 				return -1;
 			}
@@ -1072,7 +1077,7 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
 				return -1;
 			}
 			addattr_l(n, MAX_MSG, TCA_U32_CLASSID, &flowid, 4);
-			sel.sel.flags |= TC_U32_TERMINAL;
+			sel->flags |= TC_U32_TERMINAL;
 		} else if (matches(*argv, "divisor") == 0) {
 			unsigned int divisor;
 
@@ -1122,17 +1127,21 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
 		} else if (strcmp(*argv, "sample") == 0) {
 			__u32 hash;
 			unsigned int divisor = 0x100;
-			struct {
-				struct tc_u32_sel sel;
-				struct tc_u32_key keys[4];
-			} sel2 = {};
+			struct tc_u32_sel *sel2;
 
 			NEXT_ARG();
-			if (parse_selector(&argc, &argv, &sel2.sel, n)) {
+
+			sel2 = alloca(sizeof(*sel) + 4 * sizeof(struct tc_u32_key));
+			if (sel2 == NULL)
+				return -1;
+
+			memset(sel2, 0, sizeof(*sel2));
+
+			if (parse_selector(&argc, &argv, sel2, n)) {
 				fprintf(stderr, "Illegal \"sample\"\n");
 				return -1;
 			}
-			if (sel2.sel.nkeys != 1) {
+			if (sel2->nkeys != 1) {
 				fprintf(stderr, "\"sample\" must contain exactly ONE key.\n");
 				return -1;
 			}
@@ -1146,7 +1155,7 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
 				}
 				NEXT_ARG();
 			}
-			hash = u32_hash_fold(&sel2.keys[0]);
+			hash = u32_hash_fold(&sel2->keys[0]);
 			htid = ((hash % divisor) << 12) | (htid & 0xFFF00000);
 			sample_ok = 1;
 			continue;
@@ -1197,7 +1206,7 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
 
 	/* We don't necessarily need class/flowids */
 	if (terminal_ok)
-		sel.sel.flags |= TC_U32_TERMINAL;
+		sel->flags |= TC_U32_TERMINAL;
 
 	if (order) {
 		if (TC_U32_NODE(t->tcm_handle) &&
@@ -1212,8 +1221,7 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
 		addattr_l(n, MAX_MSG, TCA_U32_HASH, &htid, 4);
 	if (sel_ok)
 		addattr_l(n, MAX_MSG, TCA_U32_SEL, &sel,
-			  sizeof(sel.sel) +
-			  sel.sel.nkeys * sizeof(struct tc_u32_key));
+			  sizeof(*sel) + sel->nkeys * sizeof(struct tc_u32_key));
 	if (flags) {
 		if (!(flags ^ (TCA_CLS_FLAGS_SKIP_HW |
 			       TCA_CLS_FLAGS_SKIP_SW))) {
-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ