]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
extensions: REJECT: Merge reject tables
authorPhil Sutter <phil@nwl.cc>
Mon, 10 Sep 2018 21:35:17 +0000 (23:35 +0200)
committerFlorian Westphal <fw@strlen.de>
Thu, 13 Sep 2018 08:48:46 +0000 (10:48 +0200)
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@nwl.cc>
Signed-off-by: Florian Westphal <fw@strlen.de>
extensions/libip6t_REJECT.c
extensions/libipt_REJECT.c

index c5b980d0e5d9e0a92b546f10966df9fcd3ef9410..e3929d18dee35681cfaf46a77bde5e4939947ebb 100644 (file)
 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;
 }
index ba815bae23252f77245be7c3bc95edf0cbdb42d6..743dfffc78069c9ae3056cc6b7a039a0d38c4b1d 100644 (file)
 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;
 }