summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Engelhardt <jengelh@medozas.de>2011-01-08 02:25:28 +0100
committerJan Engelhardt <jengelh@medozas.de>2011-01-08 02:25:28 +0100
commit1e128bd804b676ee91beca48312de9b251845d09 (patch)
tree1bfa22e4d173cd1774f2510acec84ca0124829f7
parent1dc27393b7ba401e6228a5ee2472a6eb72836c43 (diff)
ip[6]tables: only call match's parse function when option char is in range
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>
-rw-r--r--ip6tables.c3
-rw-r--r--iptables.c3
-rw-r--r--xshared.h4
-rw-r--r--xtables.c4
4 files changed, 12 insertions, 2 deletions
diff --git a/ip6tables.c b/ip6tables.c
index b8449f6e..4ca4bfec 100644
--- a/ip6tables.c
+++ b/ip6tables.c
@@ -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,
diff --git a/iptables.c b/iptables.c
index e0efbf1b..bcacd49f 100644
--- a/iptables.c
+++ b/iptables.c
@@ -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,
diff --git a/xshared.h b/xshared.h
index c53b618f..e5b2a02b 100644
--- 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 *);
diff --git a/xtables.c b/xtables.c
index b6309010..5b7526c8 100644
--- 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);