[iptables PATCH 5/5] extensions: REJECT: Merge reject tables

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Initial motivation for this was a covscan report for potential array out
of bounds access in REJECT_xlate (a false-positive, because all possible
values of reject->with occur in reject_table_xlate).

Use reject types as array indices of reject_table so that reject->with
serves as array index. Also merge reject_table_xlate into it.

Signed-off-by: Phil Sutter <phil@xxxxxx>
---
 extensions/libip6t_REJECT.c | 107 +++++++++++++++++----------------
 extensions/libipt_REJECT.c  | 116 ++++++++++++++++++------------------
 2 files changed, 112 insertions(+), 111 deletions(-)

diff --git a/extensions/libip6t_REJECT.c b/extensions/libip6t_REJECT.c
index c5b980d0e5d9e..e3929d18dee35 100644
--- a/extensions/libip6t_REJECT.c
+++ b/extensions/libip6t_REJECT.c
@@ -13,13 +13,8 @@
 struct reject_names {
 	const char *name;
 	const char *alias;
-	enum ip6t_reject_with with;
 	const char *desc;
-};
-
-struct reject_names_xlate {
-	const char *name;
-	enum ip6t_reject_with with;
+	const char *xlate;
 };
 
 enum {
@@ -27,24 +22,50 @@ enum {
 };
 
 static const struct reject_names reject_table[] = {
-	{"icmp6-no-route", "no-route",
-		IP6T_ICMP6_NO_ROUTE, "ICMPv6 no route"},
-	{"icmp6-adm-prohibited", "adm-prohibited",
-		IP6T_ICMP6_ADM_PROHIBITED, "ICMPv6 administratively prohibited"},
+	[IP6T_ICMP6_NO_ROUTE] = {
+		"icmp6-no-route", "no-route",
+		"ICMPv6 no route",
+		"no-route",
+	},
+	[IP6T_ICMP6_ADM_PROHIBITED] = {
+		"icmp6-adm-prohibited", "adm-prohibited",
+		"ICMPv6 administratively prohibited",
+		"admin-prohibited",
+	},
 #if 0
-	{"icmp6-not-neighbor", "not-neighbor"},
-		IP6T_ICMP6_NOT_NEIGHBOR, "ICMPv6 not a neighbor"},
+	[IP6T_ICMP6_NOT_NEIGHBOR] = {
+		"icmp6-not-neighbor", "not-neighbor",
+		"ICMPv6 not a neighbor",
+	},
 #endif
-	{"icmp6-addr-unreachable", "addr-unreach",
-		IP6T_ICMP6_ADDR_UNREACH, "ICMPv6 address unreachable"},
-	{"icmp6-port-unreachable", "port-unreach",
-		IP6T_ICMP6_PORT_UNREACH, "ICMPv6 port unreachable"},
-	{"tcp-reset", "tcp-reset",
-		IP6T_TCP_RESET, "TCP RST packet"},
-	{"icmp6-policy-fail", "policy-fail",
-		IP6T_ICMP6_POLICY_FAIL, "ICMPv6 policy fail"},
-	{"icmp6-reject-route", "reject-route",
-		IP6T_ICMP6_REJECT_ROUTE, "ICMPv6 reject route"}
+	[IP6T_ICMP6_ADDR_UNREACH] = {
+		"icmp6-addr-unreachable", "addr-unreach",
+		"ICMPv6 address unreachable",
+		"addr-unreachable",
+	},
+	[IP6T_ICMP6_PORT_UNREACH] = {
+		"icmp6-port-unreachable", "port-unreach",
+		"ICMPv6 port unreachable",
+		"port-unreachable",
+	},
+#if 0
+	[IP6T_ICMP6_ECHOREPLY] = {},
+#endif
+	[IP6T_TCP_RESET] = {
+		"tcp-reset", "tcp-reset",
+		"TCP RST packet",
+		"tcp reset",
+	},
+	[IP6T_ICMP6_POLICY_FAIL] = {
+		"icmp6-policy-fail", "policy-fail",
+		"ICMPv6 policy fail",
+		"policy-fail",
+	},
+	[IP6T_ICMP6_REJECT_ROUTE] = {
+		"icmp6-reject-route", "reject-route",
+		"ICMPv6 reject route",
+		"reject-route",
+	},
 };
 
 static void
@@ -55,6 +76,8 @@ print_reject_types(void)
 	printf("Valid reject types:\n");
 
 	for (i = 0; i < ARRAY_SIZE(reject_table); ++i) {
+		if (!reject_table[i].name)
+			continue;
 		printf("    %-25s\t%s\n", reject_table[i].name, reject_table[i].desc);
 		printf("    %-25s\talias\n", reject_table[i].alias);
 	}
@@ -91,14 +114,17 @@ static void REJECT_parse(struct xt_option_call *cb)
 	unsigned int i;
 
 	xtables_option_parse(cb);
-	for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
+	for (i = 0; i < ARRAY_SIZE(reject_table); ++i) {
+		if (!reject_table[i].name)
+			continue;
 		if (strncasecmp(reject_table[i].name,
 		      cb->arg, strlen(cb->arg)) == 0 ||
 		    strncasecmp(reject_table[i].alias,
 		      cb->arg, strlen(cb->arg)) == 0) {
-			reject->with = reject_table[i].with;
+			reject->with = i;
 			return;
 		}
+	}
 	xtables_error(PARAMETER_PROBLEM,
 		"unknown reject type \"%s\"", cb->arg);
 }
@@ -108,55 +134,32 @@ static void REJECT_print(const void *ip, const struct xt_entry_target *target,
 {
 	const struct ip6t_reject_info *reject
 		= (const struct ip6t_reject_info *)target->data;
-	unsigned int i;
 
-	for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
-		if (reject_table[i].with == reject->with)
-			break;
-	printf(" reject-with %s", reject_table[i].name);
+	printf(" reject-with %s", reject_table[reject->with].name);
 }
 
 static void REJECT_save(const void *ip, const struct xt_entry_target *target)
 {
 	const struct ip6t_reject_info *reject
 		= (const struct ip6t_reject_info *)target->data;
-	unsigned int i;
 
-	for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
-		if (reject_table[i].with == reject->with)
-			break;
-
-	printf(" --reject-with %s", reject_table[i].name);
+	printf(" --reject-with %s", reject_table[reject->with].name);
 }
 
-static const struct reject_names_xlate reject_table_xlate[] = {
-	{"no-route",		IP6T_ICMP6_NO_ROUTE},
-	{"admin-prohibited",	IP6T_ICMP6_ADM_PROHIBITED},
-	{"addr-unreachable",	IP6T_ICMP6_ADDR_UNREACH},
-	{"port-unreachable",	IP6T_ICMP6_PORT_UNREACH},
-	{"tcp reset",		IP6T_TCP_RESET},
-	{"policy-fail",		IP6T_ICMP6_POLICY_FAIL},
-	{"reject-route",	IP6T_ICMP6_REJECT_ROUTE}
-};
-
 static int REJECT_xlate(struct xt_xlate *xl,
 			const struct xt_xlate_tg_params *params)
 {
 	const struct ip6t_reject_info *reject =
 		(const struct ip6t_reject_info *)params->target->data;
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(reject_table_xlate); ++i)
-		if (reject_table_xlate[i].with == reject->with)
-			break;
 
 	if (reject->with == IP6T_ICMP6_PORT_UNREACH)
 		xt_xlate_add(xl, "reject");
 	else if (reject->with == IP6T_TCP_RESET)
-		xt_xlate_add(xl, "reject with %s", reject_table_xlate[i].name);
+		xt_xlate_add(xl, "reject with %s",
+			     reject_table[reject->with].xlate);
 	else
 		xt_xlate_add(xl, "reject with icmpv6 type %s",
-			   reject_table_xlate[i].name);
+			     reject_table[reject->with].xlate);
 
 	return 1;
 }
diff --git a/extensions/libipt_REJECT.c b/extensions/libipt_REJECT.c
index ba815bae23252..743dfffc78069 100644
--- a/extensions/libipt_REJECT.c
+++ b/extensions/libipt_REJECT.c
@@ -20,13 +20,8 @@
 struct reject_names {
 	const char *name;
 	const char *alias;
-	enum ipt_reject_with with;
 	const char *desc;
-};
-
-struct reject_names_xlate {
-	const char *name;
-	enum ipt_reject_with with;
+	const char *xlate;
 };
 
 enum {
@@ -34,26 +29,53 @@ enum {
 };
 
 static const struct reject_names reject_table[] = {
-	{"icmp-net-unreachable", "net-unreach",
-		IPT_ICMP_NET_UNREACHABLE, "ICMP network unreachable"},
-	{"icmp-host-unreachable", "host-unreach",
-		IPT_ICMP_HOST_UNREACHABLE, "ICMP host unreachable"},
-	{"icmp-proto-unreachable", "proto-unreach",
-		IPT_ICMP_PROT_UNREACHABLE, "ICMP protocol unreachable"},
-	{"icmp-port-unreachable", "port-unreach",
-		IPT_ICMP_PORT_UNREACHABLE, "ICMP port unreachable (default)"},
+	[IPT_ICMP_NET_UNREACHABLE] = {
+		"icmp-net-unreachable", "net-unreach",
+		"ICMP network unreachable",
+		"net-unreachable",
+	},
+	[IPT_ICMP_HOST_UNREACHABLE] = {
+		"icmp-host-unreachable", "host-unreach",
+		"ICMP host unreachable",
+		"host-unreachable",
+	},
+	[IPT_ICMP_PROT_UNREACHABLE] = {
+		"icmp-proto-unreachable", "proto-unreach",
+		"ICMP protocol unreachable",
+		"prot-unreachable",
+	},
+	[IPT_ICMP_PORT_UNREACHABLE] = {
+		"icmp-port-unreachable", "port-unreach",
+		"ICMP port unreachable (default)",
+		"port-unreachable",
+	},
 #if 0
-	{"echo-reply", "echoreply",
-	 IPT_ICMP_ECHOREPLY, "for ICMP echo only: faked ICMP echo reply"},
+	[IPT_ICMP_ECHOREPLY] = {
+		"echo-reply", "echoreply",
+		"for ICMP echo only: faked ICMP echo reply",
+		"echo-reply",
+	},
 #endif
-	{"icmp-net-prohibited", "net-prohib",
-	 IPT_ICMP_NET_PROHIBITED, "ICMP network prohibited"},
-	{"icmp-host-prohibited", "host-prohib",
-	 IPT_ICMP_HOST_PROHIBITED, "ICMP host prohibited"},
-	{"tcp-reset", "tcp-rst",
-	 IPT_TCP_RESET, "TCP RST packet"},
-	{"icmp-admin-prohibited", "admin-prohib",
-	 IPT_ICMP_ADMIN_PROHIBITED, "ICMP administratively prohibited (*)"}
+	[IPT_ICMP_NET_PROHIBITED] = {
+		"icmp-net-prohibited", "net-prohib",
+		"ICMP network prohibited",
+		"net-prohibited",
+	},
+	[IPT_ICMP_HOST_PROHIBITED] = {
+		"icmp-host-prohibited", "host-prohib",
+		"ICMP host prohibited",
+		"host-prohibited",
+	},
+	[IPT_TCP_RESET] = {
+		"tcp-reset", "tcp-rst",
+		"TCP RST packet",
+		"tcp reset",
+	},
+	[IPT_ICMP_ADMIN_PROHIBITED] = {
+		"icmp-admin-prohibited", "admin-prohib",
+		"ICMP administratively prohibited (*)",
+		"admin-prohibited",
+	},
 };
 
 static void
@@ -64,6 +86,8 @@ print_reject_types(void)
 	printf("Valid reject types:\n");
 
 	for (i = 0; i < ARRAY_SIZE(reject_table); ++i) {
+		if (!reject_table[i].name)
+			continue;
 		printf("    %-25s\t%s\n", reject_table[i].name, reject_table[i].desc);
 		printf("    %-25s\talias\n", reject_table[i].alias);
 	}
@@ -102,14 +126,17 @@ static void REJECT_parse(struct xt_option_call *cb)
 	unsigned int i;
 
 	xtables_option_parse(cb);
-	for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
+	for (i = 0; i < ARRAY_SIZE(reject_table); ++i) {
+		if (!reject_table[i].name)
+			continue;
 		if (strncasecmp(reject_table[i].name,
 		      cb->arg, strlen(cb->arg)) == 0 ||
 		    strncasecmp(reject_table[i].alias,
 		      cb->arg, strlen(cb->arg)) == 0) {
-			reject->with = reject_table[i].with;
+			reject->with = i;
 			return;
 		}
+	}
 	/* This due to be dropped late in 2.4 pre-release cycle --RR */
 	if (strncasecmp("echo-reply", cb->arg, strlen(cb->arg)) == 0 ||
 	    strncasecmp("echoreply", cb->arg, strlen(cb->arg)) == 0)
@@ -124,61 +151,32 @@ static void REJECT_print(const void *ip, const struct xt_entry_target *target,
 {
 	const struct ipt_reject_info *reject
 		= (const struct ipt_reject_info *)target->data;
-	unsigned int i;
 
-	for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
-		if (reject_table[i].with == reject->with)
-			break;
-	printf(" reject-with %s", reject_table[i].name);
+	printf(" reject-with %s", reject_table[reject->with].name);
 }
 
 static void REJECT_save(const void *ip, const struct xt_entry_target *target)
 {
 	const struct ipt_reject_info *reject =
 		(const struct ipt_reject_info *)target->data;
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
-		if (reject_table[i].with == reject->with)
-			break;
 
-	printf(" --reject-with %s", reject_table[i].name);
+	printf(" --reject-with %s", reject_table[reject->with].name);
 }
 
-static const struct reject_names_xlate reject_table_xlate[] = {
-	{"net-unreachable",	IPT_ICMP_NET_UNREACHABLE},
-	{"host-unreachable",	IPT_ICMP_HOST_UNREACHABLE},
-	{"prot-unreachable",	IPT_ICMP_PROT_UNREACHABLE},
-	{"port-unreachable",	IPT_ICMP_PORT_UNREACHABLE},
-#if 0
-	{"echo-reply",		IPT_ICMP_ECHOREPLY},
-#endif
-	{"net-prohibited",	IPT_ICMP_NET_PROHIBITED},
-	{"host-prohibited",	IPT_ICMP_HOST_PROHIBITED},
-	{"tcp reset",		IPT_TCP_RESET},
-	{"admin-prohibited",	IPT_ICMP_ADMIN_PROHIBITED}
-};
-
 static int REJECT_xlate(struct xt_xlate *xl,
 			const struct xt_xlate_tg_params *params)
 {
 	const struct ipt_reject_info *reject =
 		(const struct ipt_reject_info *)params->target->data;
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(reject_table_xlate); ++i) {
-		if (reject_table_xlate[i].with == reject->with)
-			break;
-	}
 
 	if (reject->with == IPT_ICMP_PORT_UNREACHABLE)
 		xt_xlate_add(xl, "reject");
 	else if (reject->with == IPT_TCP_RESET)
 		xt_xlate_add(xl, "reject with %s",
-			   reject_table_xlate[i].name);
+			     reject_table[reject->with].xlate);
 	else
 		xt_xlate_add(xl, "reject with icmp type %s",
-			   reject_table_xlate[i].name);
+			     reject_table[reject->with].xlate);
 
 	return 1;
 }
-- 
2.18.0




[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux