netfilter: xtables: ignore unassigned hooks in check_entry_size_and_hooks
authorJan Engelhardt <jengelh@medozas.de>
Sat, 18 Jul 2009 12:52:58 +0000 (14:52 +0200)
committerJan Engelhardt <jengelh@medozas.de>
Mon, 10 Aug 2009 11:35:28 +0000 (13:35 +0200)
The "hook_entry" and "underflow" array contains values even for hooks
not provided, such as PREROUTING in conjunction with the "filter"
table. Usually, the values point to whatever the next rule is. For
the upcoming unconditionality and underflow checking patches however,
we must not inspect that arbitrary rule.

Skipping unassigned hooks seems like a good idea, also because
newinfo->hook_entry and newinfo->underflow will then continue to have
the poison value for detecting abnormalities.

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_tables.c
net/ipv6/netfilter/ip6_tables.c

index b9f7243f42203b0dc4c36d47d58d56c86771ea7e..d91f0834d572a543cec926566966ea476ec90896 100644 (file)
@@ -539,6 +539,7 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
                                             unsigned char *limit,
                                             const unsigned int *hook_entries,
                                             const unsigned int *underflows,
+                                            unsigned int valid_hooks,
                                             unsigned int *i)
 {
        unsigned int h;
@@ -558,6 +559,8 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
 
        /* Check hooks & underflows */
        for (h = 0; h < NF_ARP_NUMHOOKS; h++) {
+               if (!(valid_hooks & (1 << h)))
+                       continue;
                if ((unsigned char *)e - base == hook_entries[h])
                        newinfo->hook_entry[h] = hook_entries[h];
                if ((unsigned char *)e - base == underflows[h])
@@ -626,7 +629,7 @@ static int translate_table(const char *name,
                                 newinfo,
                                 entry0,
                                 entry0 + size,
-                                hook_entries, underflows, &i);
+                                hook_entries, underflows, valid_hooks, &i);
        duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret);
        if (ret != 0)
                return ret;
index 3431a771ff1fdbdd7402c47fe79f8a720f13bde8..6e7b7e8b80b1430de9296709c4f9dcc24b34c233 100644 (file)
@@ -714,6 +714,7 @@ check_entry_size_and_hooks(struct ipt_entry *e,
                           unsigned char *limit,
                           const unsigned int *hook_entries,
                           const unsigned int *underflows,
+                          unsigned int valid_hooks,
                           unsigned int *i)
 {
        unsigned int h;
@@ -733,6 +734,8 @@ check_entry_size_and_hooks(struct ipt_entry *e,
 
        /* Check hooks & underflows */
        for (h = 0; h < NF_INET_NUMHOOKS; h++) {
+               if (!(valid_hooks & (1 << h)))
+                       continue;
                if ((unsigned char *)e - base == hook_entries[h])
                        newinfo->hook_entry[h] = hook_entries[h];
                if ((unsigned char *)e - base == underflows[h])
@@ -804,7 +807,7 @@ translate_table(const char *name,
                                newinfo,
                                entry0,
                                entry0 + size,
-                               hook_entries, underflows, &i);
+                               hook_entries, underflows, valid_hooks, &i);
        if (ret != 0)
                return ret;
 
index 1389ad904bc3884679a1c8ba167e62f75c354f00..8e4921a937ff94adad9551ac341b420f2b7cc52f 100644 (file)
@@ -747,6 +747,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
                           unsigned char *limit,
                           const unsigned int *hook_entries,
                           const unsigned int *underflows,
+                          unsigned int valid_hooks,
                           unsigned int *i)
 {
        unsigned int h;
@@ -766,6 +767,8 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
 
        /* Check hooks & underflows */
        for (h = 0; h < NF_INET_NUMHOOKS; h++) {
+               if (!(valid_hooks & (1 << h)))
+                       continue;
                if ((unsigned char *)e - base == hook_entries[h])
                        newinfo->hook_entry[h] = hook_entries[h];
                if ((unsigned char *)e - base == underflows[h])
@@ -837,7 +840,7 @@ translate_table(const char *name,
                                newinfo,
                                entry0,
                                entry0 + size,
-                               hook_entries, underflows, &i);
+                               hook_entries, underflows, valid_hooks, &i);
        if (ret != 0)
                return ret;