From 14162f779c5b11149432e454af08b1c5e8ecf711 Mon Sep 17 00:00:00 2001 From: Bart De Schuymer Date: Thu, 25 Jul 2002 17:23:36 +0000 Subject: deal with --xxxx-target RETURN on base chain --- kernel/linux/net/bridge/netfilter/ebt_dnat.c | 4 ++++ kernel/linux/net/bridge/netfilter/ebt_mark.c | 4 ++++ kernel/linux/net/bridge/netfilter/ebt_redirect.c | 4 ++++ kernel/linux/net/bridge/netfilter/ebt_snat.c | 4 ++++ kernel/linux/net/bridge/netfilter/ebtables.c | 22 +++++++++++----------- 5 files changed, 27 insertions(+), 11 deletions(-) (limited to 'kernel') diff --git a/kernel/linux/net/bridge/netfilter/ebt_dnat.c b/kernel/linux/net/bridge/netfilter/ebt_dnat.c index 28ce793..a910d77 100644 --- a/kernel/linux/net/bridge/netfilter/ebt_dnat.c +++ b/kernel/linux/net/bridge/netfilter/ebt_dnat.c @@ -31,6 +31,10 @@ static int ebt_target_dnat_check(const char *tablename, unsigned int hookmask, { struct ebt_nat_info *infostuff = (struct ebt_nat_info *) data; + if ((hookmask & (1 << NF_BR_NUMHOOKS)) && + infostuff->target == EBT_RETURN) + return -EINVAL; + hookmask &= ~(1 << NF_BR_NUMHOOKS); if ( (strcmp(tablename, "nat") || (hookmask & ~((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT)))) && (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) ) diff --git a/kernel/linux/net/bridge/netfilter/ebt_mark.c b/kernel/linux/net/bridge/netfilter/ebt_mark.c index 1e4d98b..75edcf7 100644 --- a/kernel/linux/net/bridge/netfilter/ebt_mark.c +++ b/kernel/linux/net/bridge/netfilter/ebt_mark.c @@ -40,6 +40,10 @@ static int ebt_target_mark_check(const char *tablename, unsigned int hookmask, { struct ebt_mark_t_info *infostuff = (struct ebt_mark_t_info *) data; + if ((hookmask & (1 << NF_BR_NUMHOOKS)) && + infostuff->target == EBT_RETURN) + return -EINVAL; + hookmask &= ~(1 << NF_BR_NUMHOOKS); if (datalen != sizeof(struct ebt_mark_t_info)) return -EINVAL; if (infostuff->target < -NUM_STANDARD_TARGETS || infostuff->target >= 0) diff --git a/kernel/linux/net/bridge/netfilter/ebt_redirect.c b/kernel/linux/net/bridge/netfilter/ebt_redirect.c index 1b8d696..d7c51ba 100644 --- a/kernel/linux/net/bridge/netfilter/ebt_redirect.c +++ b/kernel/linux/net/bridge/netfilter/ebt_redirect.c @@ -38,6 +38,10 @@ static int ebt_target_redirect_check(const char *tablename, unsigned int hookmas { struct ebt_redirect_info *infostuff = (struct ebt_redirect_info *) data; + if ((hookmask & (1 << NF_BR_NUMHOOKS)) && + infostuff->target == EBT_RETURN) + return -EINVAL; + hookmask &= ~(1 << NF_BR_NUMHOOKS); if ( (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING)) && (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) ) return -EINVAL; diff --git a/kernel/linux/net/bridge/netfilter/ebt_snat.c b/kernel/linux/net/bridge/netfilter/ebt_snat.c index aaaa7f0..5b2554e 100644 --- a/kernel/linux/net/bridge/netfilter/ebt_snat.c +++ b/kernel/linux/net/bridge/netfilter/ebt_snat.c @@ -31,6 +31,10 @@ static int ebt_target_snat_check(const char *tablename, unsigned int hookmask, { struct ebt_nat_info *infostuff = (struct ebt_nat_info *) data; + if ((hookmask & (1 << NF_BR_NUMHOOKS)) && + infostuff->target == EBT_RETURN) + return -EINVAL; + hookmask &= ~(1 << NF_BR_NUMHOOKS); if (strcmp(tablename, "nat")) return -EINVAL; if (datalen != sizeof(struct ebt_nat_info)) diff --git a/kernel/linux/net/bridge/netfilter/ebtables.c b/kernel/linux/net/bridge/netfilter/ebtables.c index d5c5d1a..953c870 100644 --- a/kernel/linux/net/bridge/netfilter/ebtables.c +++ b/kernel/linux/net/bridge/netfilter/ebtables.c @@ -77,10 +77,8 @@ static struct ebt_target ebt_standard_target = { {NULL, NULL}, EBT_STANDARD_TARGET, NULL, NULL, NULL, NULL}; static inline int ebt_do_watcher (struct ebt_entry_watcher *w, - const struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - const struct ebt_counter *c) + const struct sk_buff *skb, const struct net_device *in, + const struct net_device *out, const struct ebt_counter *c) { w->u.watcher->watcher(skb, in, out, w->data, w->watcher_size, c); @@ -89,10 +87,8 @@ static inline int ebt_do_watcher (struct ebt_entry_watcher *w, } static inline int ebt_do_match (struct ebt_entry_match *m, - const struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - const struct ebt_counter *c) + const struct sk_buff *skb, const struct net_device *in, + const struct net_device *out, const struct ebt_counter *c) { return m->u.match->match(skb, in, out, m->data, m->match_size, c); @@ -214,9 +210,11 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb, } if (verdict == EBT_RETURN) { letsreturn: - if (sp == 0) + if (sp == 0) { + BUGPRINT("RETURN on base chain"); // act like this is EBT_CONTINUE goto letscontinue; + } sp--; // put all the local variables right i = cs[sp].n; @@ -571,14 +569,16 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, else break; } + // (1 << NF_BR_NUMHOOKS) tells the check functions the rule is on + // a base chain if (i < NF_BR_NUMHOOKS) - hookmask = (1 << hook); + hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS); else { for (i = 0; i < udc_cnt; i++) if ((char *)(cl_s[i].cs.chaininfo) > (char *)e) break; if (i == 0) - hookmask = (1 << hook); + hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS); else hookmask = cl_s[i - 1].hookmask; } -- cgit v1.2.3