]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
ip[6]tables: only call match's parse function when option char is in range
authorJan Engelhardt <jengelh@medozas.de>
Sat, 8 Jan 2011 01:25:28 +0000 (02:25 +0100)
committerJan Engelhardt <jengelh@medozas.de>
Sat, 8 Jan 2011 01:25:28 +0000 (02:25 +0100)
Normally, extensions use a "default:" case in switch(c) to just return
if they do not handle c. Apparently, libip6t_hl does that too late and
checks for hl-specific parsing state before it has established that c
refers to one of its own options.

Also affected: libipt_ttl, libxt_ipvs, libxt_policy, libxt_statistic.

One way to fix this is to move the flags checks into case '2', '3',
'4'. Doing this replication feels bad, so as an alternative, let's
just free extensions from having to deal with other extension's
options passing thru.

References: http://marc.info/?l=netfilter-devel&m=129444759532377&w=2
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
ip6tables.c
iptables.c
xshared.h
xtables.c

index b8449f6e6a47b93b190d69264900170e3d2f4865..4ca4bfeca089de9c1497541e667bab468fd0f2cf 100644 (file)
@@ -1714,6 +1714,9 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
                                        if (matchp->completed ||
                                            matchp->match->parse == NULL)
                                                continue;
+                                       if (c < matchp->match->option_offset ||
+                                           c >= matchp->match->option_offset + XT_OPTION_OFFSET_SCALE)
+                                               continue;
                                        if (matchp->match->parse(c - matchp->match->option_offset,
                                                     argv, invert,
                                                     &matchp->match->mflags,
index e0efbf1b7165f4f95e4989188de0e079e6f42fb9..bcacd49f29137c32b21ea3bc2f6405bdbd34d160 100644 (file)
@@ -1746,6 +1746,9 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle
                                        if (matchp->completed ||
                                            matchp->match->parse == NULL)
                                                continue;
+                                       if (c < matchp->match->option_offset ||
+                                           c >= matchp->match->option_offset + XT_OPTION_OFFSET_SCALE)
+                                               continue;
                                        if (matchp->match->parse(c - matchp->match->option_offset,
                                                     argv, invert,
                                                     &matchp->match->mflags,
index c53b618fb2d9e008efe5ca47fa6b6cdb2c620963..e5b2a02b9b764258f624a79beb8a6376881f55b1 100644 (file)
--- a/xshared.h
+++ b/xshared.h
@@ -4,6 +4,10 @@
 struct xtables_rule_match;
 struct xtables_target;
 
+enum {
+       XT_OPTION_OFFSET_SCALE = 256,
+};
+
 extern void print_extension_helps(const struct xtables_target *,
        const struct xtables_rule_match *);
 
index b63090100978e08c16754772c01c2ab2f5fa69b7..5b7526c83b2e1f0a91972e0c1a36f6e66fcb3fec 100644 (file)
--- a/xtables.c
+++ b/xtables.c
@@ -49,7 +49,7 @@
 #      define IP6T_SO_GET_REVISION_TARGET      69
 #endif
 #include <getopt.h>
-
+#include "xshared.h"
 
 #define NPROTO 255
 
@@ -111,7 +111,7 @@ struct option *xtables_merge_options(struct option *orig_opts,
        mp = merge + num_oold;
 
        /* Second, the new options */
-       xt_params->option_offset += 256;
+       xt_params->option_offset += XT_OPTION_OFFSET_SCALE;
        *option_offset = xt_params->option_offset;
        memcpy(mp, newopts, sizeof(*mp) * num_new);