From: Chris Wright Date: Fri, 1 Dec 2006 07:02:24 +0000 (-0800) Subject: networking patches from DaveM for 2.6.18/19 queues X-Git-Tag: v2.6.18.5~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=afc1766e7858e2d8b7e08b4ef3b41e4305d8b37a;p=thirdparty%2Fkernel%2Fstable-queue.git networking patches from DaveM for 2.6.18/19 queues --- diff --git a/queue-2.6.18/ebtables-deal-with-the-worst-case-behaviour-in-loop-checks.patch b/queue-2.6.18/ebtables-deal-with-the-worst-case-behaviour-in-loop-checks.patch new file mode 100644 index 00000000000..f58d35b68f8 --- /dev/null +++ b/queue-2.6.18/ebtables-deal-with-the-worst-case-behaviour-in-loop-checks.patch @@ -0,0 +1,36 @@ +From stable-bounces@linux.kernel.org Thu Nov 30 19:52:58 2006 +Date: Thu, 30 Nov 2006 19:47:58 -0800 (PST) +Message-Id: <20061130.194758.42773919.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: EBTABLES: Deal with the worst-case behaviour in loop checks. + +From: Al Viro + +No need to revisit a chain we'd already finished with during +the check for current hook. It's either instant loop (which +we'd just detected) or a duplicate work. + +Signed-off-by: Al Viro +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright + +--- +--- + net/bridge/netfilter/ebtables.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- linux-2.6.18.5.orig/net/bridge/netfilter/ebtables.c ++++ linux-2.6.18.5/net/bridge/netfilter/ebtables.c +@@ -739,7 +739,9 @@ static int check_chainloops(struct ebt_e + BUGPRINT("loop\n"); + return -1; + } +- /* this can't be 0, so the above test is correct */ ++ if (cl_s[i].hookmask & (1 << hooknr)) ++ goto letscontinue; ++ /* this can't be 0, so the loop test is correct */ + cl_s[i].cs.n = pos + 1; + pos = 0; + cl_s[i].cs.e = ((void *)e + e->next_offset); diff --git a/queue-2.6.18/ebtables-fix-wraparounds-in-ebt_entries-verification.patch b/queue-2.6.18/ebtables-fix-wraparounds-in-ebt_entries-verification.patch new file mode 100644 index 00000000000..621d83249de --- /dev/null +++ b/queue-2.6.18/ebtables-fix-wraparounds-in-ebt_entries-verification.patch @@ -0,0 +1,87 @@ +From stable-bounces@linux.kernel.org Thu Nov 30 19:52:50 2006 +Date: Thu, 30 Nov 2006 19:47:52 -0800 (PST) +Message-Id: <20061130.194752.45874935.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: EBTABLES: Fix wraparounds in ebt_entries verification. + +From: Al Viro + +We need to verify that + a) we are not too close to the end of buffer to dereference + b) next entry we'll be checking won't be _before_ our + +While we are at it, don't subtract unrelated pointers... + +Signed-off-by: Al Viro +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright + +--- +--- + net/bridge/netfilter/ebtables.c | 23 ++++++++++++++++------- + 1 file changed, 16 insertions(+), 7 deletions(-) + +--- linux-2.6.18.5.orig/net/bridge/netfilter/ebtables.c ++++ linux-2.6.18.5/net/bridge/netfilter/ebtables.c +@@ -423,13 +423,17 @@ ebt_check_entry_size_and_hooks(struct eb + struct ebt_entries **hook_entries, unsigned int *n, unsigned int *cnt, + unsigned int *totalcnt, unsigned int *udc_cnt, unsigned int valid_hooks) + { ++ unsigned int offset = (char *)e - newinfo->entries; ++ size_t left = (limit - base) - offset; + int i; + ++ if (left < sizeof(unsigned int)) ++ goto Esmall; ++ + for (i = 0; i < NF_BR_NUMHOOKS; i++) { + if ((valid_hooks & (1 << i)) == 0) + continue; +- if ( (char *)hook_entries[i] - base == +- (char *)e - newinfo->entries) ++ if ((char *)hook_entries[i] == base + offset) + break; + } + /* beginning of a new chain +@@ -450,11 +454,8 @@ ebt_check_entry_size_and_hooks(struct eb + return -EINVAL; + } + /* before we look at the struct, be sure it is not too big */ +- if ((char *)hook_entries[i] + sizeof(struct ebt_entries) +- > limit) { +- BUGPRINT("entries_size too small\n"); +- return -EINVAL; +- } ++ if (left < sizeof(struct ebt_entries)) ++ goto Esmall; + if (((struct ebt_entries *)e)->policy != EBT_DROP && + ((struct ebt_entries *)e)->policy != EBT_ACCEPT) { + /* only RETURN from udc */ +@@ -477,6 +478,8 @@ ebt_check_entry_size_and_hooks(struct eb + return 0; + } + /* a plain old entry, heh */ ++ if (left < sizeof(struct ebt_entry)) ++ goto Esmall; + if (sizeof(struct ebt_entry) > e->watchers_offset || + e->watchers_offset > e->target_offset || + e->target_offset >= e->next_offset) { +@@ -488,10 +491,16 @@ ebt_check_entry_size_and_hooks(struct eb + BUGPRINT("target size too small\n"); + return -EINVAL; + } ++ if (left < e->next_offset) ++ goto Esmall; + + (*cnt)++; + (*totalcnt)++; + return 0; ++ ++Esmall: ++ BUGPRINT("entries_size too small\n"); ++ return -EINVAL; + } + + struct ebt_cl_stack diff --git a/queue-2.6.18/ebtables-prevent-wraparounds-in-checks-for-entry-components-sizes.patch b/queue-2.6.18/ebtables-prevent-wraparounds-in-checks-for-entry-components-sizes.patch new file mode 100644 index 00000000000..77edebbe33d --- /dev/null +++ b/queue-2.6.18/ebtables-prevent-wraparounds-in-checks-for-entry-components-sizes.patch @@ -0,0 +1,77 @@ +From stable-bounces@linux.kernel.org Thu Nov 30 19:52:58 2006 +Date: Thu, 30 Nov 2006 19:47:59 -0800 (PST) +Message-Id: <20061130.194759.54187107.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: EBTABLES: Prevent wraparounds in checks for entry components' sizes. + +From: Al Viro + +Signed-off-by: Al Viro +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright + +--- +--- + net/bridge/netfilter/ebtables.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +--- linux-2.6.18.5.orig/net/bridge/netfilter/ebtables.c ++++ linux-2.6.18.5/net/bridge/netfilter/ebtables.c +@@ -360,10 +360,11 @@ ebt_check_match(struct ebt_entry_match * + const char *name, unsigned int hookmask, unsigned int *cnt) + { + struct ebt_match *match; ++ size_t left = ((char *)e + e->watchers_offset) - (char *)m; + int ret; + +- if (((char *)m) + m->match_size + sizeof(struct ebt_entry_match) > +- ((char *)e) + e->watchers_offset) ++ if (left < sizeof(struct ebt_entry_match) || ++ left - sizeof(struct ebt_entry_match) < m->match_size) + return -EINVAL; + match = find_match_lock(m->u.name, &ret, &ebt_mutex); + if (!match) +@@ -389,10 +390,11 @@ ebt_check_watcher(struct ebt_entry_watch + const char *name, unsigned int hookmask, unsigned int *cnt) + { + struct ebt_watcher *watcher; ++ size_t left = ((char *)e + e->target_offset) - (char *)w; + int ret; + +- if (((char *)w) + w->watcher_size + sizeof(struct ebt_entry_watcher) > +- ((char *)e) + e->target_offset) ++ if (left < sizeof(struct ebt_entry_watcher) || ++ left - sizeof(struct ebt_entry_watcher) < w->watcher_size) + return -EINVAL; + watcher = find_watcher_lock(w->u.name, &ret, &ebt_mutex); + if (!watcher) +@@ -595,6 +597,7 @@ ebt_check_entry(struct ebt_entry *e, str + struct ebt_entry_target *t; + struct ebt_target *target; + unsigned int i, j, hook = 0, hookmask = 0; ++ size_t gap = e->next_offset - e->target_offset; + int ret; + + /* don't mess with the struct ebt_entries */ +@@ -656,8 +659,7 @@ ebt_check_entry(struct ebt_entry *e, str + + t->u.target = target; + if (t->u.target == &ebt_standard_target) { +- if (e->target_offset + sizeof(struct ebt_standard_target) > +- e->next_offset) { ++ if (gap < sizeof(struct ebt_standard_target)) { + BUGPRINT("Standard target size too big\n"); + ret = -EFAULT; + goto cleanup_watchers; +@@ -668,8 +670,7 @@ ebt_check_entry(struct ebt_entry *e, str + ret = -EFAULT; + goto cleanup_watchers; + } +- } else if ((e->target_offset + t->target_size + +- sizeof(struct ebt_entry_target) > e->next_offset) || ++ } else if (t->target_size > gap - sizeof(struct ebt_entry_target) || + (t->u.target->check && + t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){ + module_put(t->u.target->me); diff --git a/queue-2.6.18/ebtables-verify-that-ebt_entries-have-zero-distinguisher.patch b/queue-2.6.18/ebtables-verify-that-ebt_entries-have-zero-distinguisher.patch new file mode 100644 index 00000000000..b1722119c8c --- /dev/null +++ b/queue-2.6.18/ebtables-verify-that-ebt_entries-have-zero-distinguisher.patch @@ -0,0 +1,68 @@ +From stable-bounces@linux.kernel.org Thu Nov 30 19:52:51 2006 +Date: Thu, 30 Nov 2006 19:47:56 -0800 (PST) +Message-Id: <20061130.194756.57443738.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: EBTABLES: Verify that ebt_entries have zero ->distinguisher. + +From: Al Viro + +We need that for iterator to work; existing check had been too weak. + +Signed-off-by: Al Viro +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright + +--- +--- + net/bridge/netfilter/ebtables.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- linux-2.6.18.5.orig/net/bridge/netfilter/ebtables.c ++++ linux-2.6.18.5/net/bridge/netfilter/ebtables.c +@@ -439,7 +439,7 @@ ebt_check_entry_size_and_hooks(struct eb + /* beginning of a new chain + if i == NF_BR_NUMHOOKS it must be a user defined chain */ + if (i != NF_BR_NUMHOOKS || !(e->bitmask & EBT_ENTRY_OR_ENTRIES)) { +- if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) != 0) { ++ if (e->bitmask != 0) { + /* we make userspace set this right, + so there is no misunderstanding */ + BUGPRINT("EBT_ENTRY_OR_ENTRIES shouldn't be set " +@@ -522,7 +522,7 @@ ebt_get_udc_positions(struct ebt_entry * + int i; + + /* we're only interested in chain starts */ +- if (e->bitmask & EBT_ENTRY_OR_ENTRIES) ++ if (e->bitmask) + return 0; + for (i = 0; i < NF_BR_NUMHOOKS; i++) { + if ((valid_hooks & (1 << i)) == 0) +@@ -572,7 +572,7 @@ ebt_cleanup_entry(struct ebt_entry *e, u + { + struct ebt_entry_target *t; + +- if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0) ++ if (e->bitmask == 0) + return 0; + /* we're done */ + if (cnt && (*cnt)-- == 0) +@@ -598,7 +598,7 @@ ebt_check_entry(struct ebt_entry *e, str + int ret; + + /* don't mess with the struct ebt_entries */ +- if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0) ++ if (e->bitmask == 0) + return 0; + + if (e->bitmask & ~EBT_F_MASK) { +@@ -1316,7 +1316,7 @@ static inline int ebt_make_names(struct + char *hlp; + struct ebt_entry_target *t; + +- if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0) ++ if (e->bitmask == 0) + return 0; + + hlp = ubase - base + (char *)e + e->target_offset; diff --git a/queue-2.6.18/net_sched-policer-restore-compatibility-with-old-iproute-binaries.patch b/queue-2.6.18/net_sched-policer-restore-compatibility-with-old-iproute-binaries.patch new file mode 100644 index 00000000000..9aee7c78408 --- /dev/null +++ b/queue-2.6.18/net_sched-policer-restore-compatibility-with-old-iproute-binaries.patch @@ -0,0 +1,85 @@ +From stable-bounces@linux.kernel.org Thu Nov 30 20:11:29 2006 +Date: Thu, 30 Nov 2006 20:06:33 -0800 (PST) +Message-Id: <20061130.200633.94556709.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: NET_SCHED: policer: restore compatibility with old iproute binaries + +From: Patrick McHardy + +The tc actions increased the size of struct tc_police, which broke +compatibility with old iproute binaries since both the act_police +and the old NET_CLS_POLICE code check for an exact size match. + +Since the new members are not even used, the simple fix is to also +accept the size of the old structure. Dumping is not affected since +old userspace will receive a bigger structure, which is handled fine. + +Signed-off-by: Patrick McHardy +Acked-by: Jamal Hadi Salim +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright + +--- +--- + net/sched/act_police.c | 26 ++++++++++++++++++++++---- + 1 file changed, 22 insertions(+), 4 deletions(-) + +--- linux-2.6.18.5.orig/net/sched/act_police.c ++++ linux-2.6.18.5/net/sched/act_police.c +@@ -44,6 +44,18 @@ static struct tcf_police *tcf_police_ht[ + /* Policer hash table lock */ + static DEFINE_RWLOCK(police_lock); + ++/* old policer structure from before tc actions */ ++struct tc_police_compat ++{ ++ u32 index; ++ int action; ++ u32 limit; ++ u32 burst; ++ u32 mtu; ++ struct tc_ratespec rate; ++ struct tc_ratespec peakrate; ++}; ++ + /* Each policer is serialized by its individual spinlock */ + + static __inline__ unsigned tcf_police_hash(u32 index) +@@ -169,12 +181,15 @@ static int tcf_act_police_locate(struct + struct tc_police *parm; + struct tcf_police *p; + struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL; ++ int size; + + if (rta == NULL || rtattr_parse_nested(tb, TCA_POLICE_MAX, rta) < 0) + return -EINVAL; + +- if (tb[TCA_POLICE_TBF-1] == NULL || +- RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]) != sizeof(*parm)) ++ if (tb[TCA_POLICE_TBF-1] == NULL) ++ return -EINVAL; ++ size = RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]); ++ if (size != sizeof(*parm) && size != sizeof(struct tc_police_compat)) + return -EINVAL; + parm = RTA_DATA(tb[TCA_POLICE_TBF-1]); + +@@ -413,12 +428,15 @@ struct tcf_police * tcf_police_locate(st + struct tcf_police *p; + struct rtattr *tb[TCA_POLICE_MAX]; + struct tc_police *parm; ++ int size; + + if (rtattr_parse_nested(tb, TCA_POLICE_MAX, rta) < 0) + return NULL; + +- if (tb[TCA_POLICE_TBF-1] == NULL || +- RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]) != sizeof(*parm)) ++ if (tb[TCA_POLICE_TBF-1] == NULL) ++ return NULL; ++ size = RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]); ++ if (size != sizeof(*parm) && size != sizeof(struct tc_police_compat)) + return NULL; + + parm = RTA_DATA(tb[TCA_POLICE_TBF-1]); diff --git a/queue-2.6.18/series b/queue-2.6.18/series index 385a37ff495..6e0bbc915ae 100644 --- a/queue-2.6.18/series +++ b/queue-2.6.18/series @@ -1 +1,6 @@ softmac-remove-netif_tx_disable-when-scanning.patch +ebtables-fix-wraparounds-in-ebt_entries-verification.patch +ebtables-verify-that-ebt_entries-have-zero-distinguisher.patch +ebtables-deal-with-the-worst-case-behaviour-in-loop-checks.patch +ebtables-prevent-wraparounds-in-checks-for-entry-components-sizes.patch +net_sched-policer-restore-compatibility-with-old-iproute-binaries.patch diff --git a/queue-2.6.19/ebtables-deal-with-the-worst-case-behaviour-in-loop-checks.patch b/queue-2.6.19/ebtables-deal-with-the-worst-case-behaviour-in-loop-checks.patch new file mode 100644 index 00000000000..99a96b44ac3 --- /dev/null +++ b/queue-2.6.19/ebtables-deal-with-the-worst-case-behaviour-in-loop-checks.patch @@ -0,0 +1,36 @@ +From stable-bounces@linux.kernel.org Thu Nov 30 19:52:58 2006 +Date: Thu, 30 Nov 2006 19:47:58 -0800 (PST) +Message-Id: <20061130.194758.42773919.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: EBTABLES: Deal with the worst-case behaviour in loop checks. + +From: Al Viro + +No need to revisit a chain we'd already finished with during +the check for current hook. It's either instant loop (which +we'd just detected) or a duplicate work. + +Signed-off-by: Al Viro +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright + +--- +--- + net/bridge/netfilter/ebtables.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- linux-2.6.19.orig/net/bridge/netfilter/ebtables.c ++++ linux-2.6.19/net/bridge/netfilter/ebtables.c +@@ -717,7 +717,9 @@ static int check_chainloops(struct ebt_e + BUGPRINT("loop\n"); + return -1; + } +- /* this can't be 0, so the above test is correct */ ++ if (cl_s[i].hookmask & (1 << hooknr)) ++ goto letscontinue; ++ /* this can't be 0, so the loop test is correct */ + cl_s[i].cs.n = pos + 1; + pos = 0; + cl_s[i].cs.e = ((void *)e + e->next_offset); diff --git a/queue-2.6.19/ebtables-fix-wraparounds-in-ebt_entries-verification.patch b/queue-2.6.19/ebtables-fix-wraparounds-in-ebt_entries-verification.patch new file mode 100644 index 00000000000..b57679a313c --- /dev/null +++ b/queue-2.6.19/ebtables-fix-wraparounds-in-ebt_entries-verification.patch @@ -0,0 +1,87 @@ +From stable-bounces@linux.kernel.org Thu Nov 30 19:52:50 2006 +Date: Thu, 30 Nov 2006 19:47:52 -0800 (PST) +Message-Id: <20061130.194752.45874935.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: EBTABLES: Fix wraparounds in ebt_entries verification. + +From: Al Viro + +We need to verify that + a) we are not too close to the end of buffer to dereference + b) next entry we'll be checking won't be _before_ our + +While we are at it, don't subtract unrelated pointers... + +Signed-off-by: Al Viro +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright + +--- +--- + net/bridge/netfilter/ebtables.c | 23 ++++++++++++++++------- + 1 file changed, 16 insertions(+), 7 deletions(-) + +--- linux-2.6.19.orig/net/bridge/netfilter/ebtables.c ++++ linux-2.6.19/net/bridge/netfilter/ebtables.c +@@ -401,13 +401,17 @@ ebt_check_entry_size_and_hooks(struct eb + struct ebt_entries **hook_entries, unsigned int *n, unsigned int *cnt, + unsigned int *totalcnt, unsigned int *udc_cnt, unsigned int valid_hooks) + { ++ unsigned int offset = (char *)e - newinfo->entries; ++ size_t left = (limit - base) - offset; + int i; + ++ if (left < sizeof(unsigned int)) ++ goto Esmall; ++ + for (i = 0; i < NF_BR_NUMHOOKS; i++) { + if ((valid_hooks & (1 << i)) == 0) + continue; +- if ( (char *)hook_entries[i] - base == +- (char *)e - newinfo->entries) ++ if ((char *)hook_entries[i] == base + offset) + break; + } + /* beginning of a new chain +@@ -428,11 +432,8 @@ ebt_check_entry_size_and_hooks(struct eb + return -EINVAL; + } + /* before we look at the struct, be sure it is not too big */ +- if ((char *)hook_entries[i] + sizeof(struct ebt_entries) +- > limit) { +- BUGPRINT("entries_size too small\n"); +- return -EINVAL; +- } ++ if (left < sizeof(struct ebt_entries)) ++ goto Esmall; + if (((struct ebt_entries *)e)->policy != EBT_DROP && + ((struct ebt_entries *)e)->policy != EBT_ACCEPT) { + /* only RETURN from udc */ +@@ -455,6 +456,8 @@ ebt_check_entry_size_and_hooks(struct eb + return 0; + } + /* a plain old entry, heh */ ++ if (left < sizeof(struct ebt_entry)) ++ goto Esmall; + if (sizeof(struct ebt_entry) > e->watchers_offset || + e->watchers_offset > e->target_offset || + e->target_offset >= e->next_offset) { +@@ -466,10 +469,16 @@ ebt_check_entry_size_and_hooks(struct eb + BUGPRINT("target size too small\n"); + return -EINVAL; + } ++ if (left < e->next_offset) ++ goto Esmall; + + (*cnt)++; + (*totalcnt)++; + return 0; ++ ++Esmall: ++ BUGPRINT("entries_size too small\n"); ++ return -EINVAL; + } + + struct ebt_cl_stack diff --git a/queue-2.6.19/ebtables-prevent-wraparounds-in-checks-for-entry-components-sizes.patch b/queue-2.6.19/ebtables-prevent-wraparounds-in-checks-for-entry-components-sizes.patch new file mode 100644 index 00000000000..c1f273c709d --- /dev/null +++ b/queue-2.6.19/ebtables-prevent-wraparounds-in-checks-for-entry-components-sizes.patch @@ -0,0 +1,77 @@ +From stable-bounces@linux.kernel.org Thu Nov 30 19:52:58 2006 +Date: Thu, 30 Nov 2006 19:47:59 -0800 (PST) +Message-Id: <20061130.194759.54187107.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: EBTABLES: Prevent wraparounds in checks for entry components' sizes. + +From: Al Viro + +Signed-off-by: Al Viro +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright + +--- +--- + net/bridge/netfilter/ebtables.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +--- linux-2.6.19.orig/net/bridge/netfilter/ebtables.c ++++ linux-2.6.19/net/bridge/netfilter/ebtables.c +@@ -338,10 +338,11 @@ ebt_check_match(struct ebt_entry_match * + const char *name, unsigned int hookmask, unsigned int *cnt) + { + struct ebt_match *match; ++ size_t left = ((char *)e + e->watchers_offset) - (char *)m; + int ret; + +- if (((char *)m) + m->match_size + sizeof(struct ebt_entry_match) > +- ((char *)e) + e->watchers_offset) ++ if (left < sizeof(struct ebt_entry_match) || ++ left - sizeof(struct ebt_entry_match) < m->match_size) + return -EINVAL; + match = find_match_lock(m->u.name, &ret, &ebt_mutex); + if (!match) +@@ -367,10 +368,11 @@ ebt_check_watcher(struct ebt_entry_watch + const char *name, unsigned int hookmask, unsigned int *cnt) + { + struct ebt_watcher *watcher; ++ size_t left = ((char *)e + e->target_offset) - (char *)w; + int ret; + +- if (((char *)w) + w->watcher_size + sizeof(struct ebt_entry_watcher) > +- ((char *)e) + e->target_offset) ++ if (left < sizeof(struct ebt_entry_watcher) || ++ left - sizeof(struct ebt_entry_watcher) < w->watcher_size) + return -EINVAL; + watcher = find_watcher_lock(w->u.name, &ret, &ebt_mutex); + if (!watcher) +@@ -573,6 +575,7 @@ ebt_check_entry(struct ebt_entry *e, str + struct ebt_entry_target *t; + struct ebt_target *target; + unsigned int i, j, hook = 0, hookmask = 0; ++ size_t gap = e->next_offset - e->target_offset; + int ret; + + /* don't mess with the struct ebt_entries */ +@@ -634,8 +637,7 @@ ebt_check_entry(struct ebt_entry *e, str + + t->u.target = target; + if (t->u.target == &ebt_standard_target) { +- if (e->target_offset + sizeof(struct ebt_standard_target) > +- e->next_offset) { ++ if (gap < sizeof(struct ebt_standard_target)) { + BUGPRINT("Standard target size too big\n"); + ret = -EFAULT; + goto cleanup_watchers; +@@ -646,8 +648,7 @@ ebt_check_entry(struct ebt_entry *e, str + ret = -EFAULT; + goto cleanup_watchers; + } +- } else if ((e->target_offset + t->target_size + +- sizeof(struct ebt_entry_target) > e->next_offset) || ++ } else if (t->target_size > gap - sizeof(struct ebt_entry_target) || + (t->u.target->check && + t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){ + module_put(t->u.target->me); diff --git a/queue-2.6.19/ebtables-verify-that-ebt_entries-have-zero-distinguisher.patch b/queue-2.6.19/ebtables-verify-that-ebt_entries-have-zero-distinguisher.patch new file mode 100644 index 00000000000..758ad4afc67 --- /dev/null +++ b/queue-2.6.19/ebtables-verify-that-ebt_entries-have-zero-distinguisher.patch @@ -0,0 +1,68 @@ +From stable-bounces@linux.kernel.org Thu Nov 30 19:52:51 2006 +Date: Thu, 30 Nov 2006 19:47:56 -0800 (PST) +Message-Id: <20061130.194756.57443738.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: EBTABLES: Verify that ebt_entries have zero ->distinguisher. + +From: Al Viro + +We need that for iterator to work; existing check had been too weak. + +Signed-off-by: Al Viro +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright + +--- +--- + net/bridge/netfilter/ebtables.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- linux-2.6.19.orig/net/bridge/netfilter/ebtables.c ++++ linux-2.6.19/net/bridge/netfilter/ebtables.c +@@ -417,7 +417,7 @@ ebt_check_entry_size_and_hooks(struct eb + /* beginning of a new chain + if i == NF_BR_NUMHOOKS it must be a user defined chain */ + if (i != NF_BR_NUMHOOKS || !(e->bitmask & EBT_ENTRY_OR_ENTRIES)) { +- if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) != 0) { ++ if (e->bitmask != 0) { + /* we make userspace set this right, + so there is no misunderstanding */ + BUGPRINT("EBT_ENTRY_OR_ENTRIES shouldn't be set " +@@ -500,7 +500,7 @@ ebt_get_udc_positions(struct ebt_entry * + int i; + + /* we're only interested in chain starts */ +- if (e->bitmask & EBT_ENTRY_OR_ENTRIES) ++ if (e->bitmask) + return 0; + for (i = 0; i < NF_BR_NUMHOOKS; i++) { + if ((valid_hooks & (1 << i)) == 0) +@@ -550,7 +550,7 @@ ebt_cleanup_entry(struct ebt_entry *e, u + { + struct ebt_entry_target *t; + +- if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0) ++ if (e->bitmask == 0) + return 0; + /* we're done */ + if (cnt && (*cnt)-- == 0) +@@ -576,7 +576,7 @@ ebt_check_entry(struct ebt_entry *e, str + int ret; + + /* don't mess with the struct ebt_entries */ +- if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0) ++ if (e->bitmask == 0) + return 0; + + if (e->bitmask & ~EBT_F_MASK) { +@@ -1309,7 +1309,7 @@ static inline int ebt_make_names(struct + char *hlp; + struct ebt_entry_target *t; + +- if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0) ++ if (e->bitmask == 0) + return 0; + + hlp = ubase - base + (char *)e + e->target_offset; diff --git a/queue-2.6.19/net_sched-policer-restore-compatibility-with-old-iproute-binaries.patch b/queue-2.6.19/net_sched-policer-restore-compatibility-with-old-iproute-binaries.patch new file mode 100644 index 00000000000..5b8972f711c --- /dev/null +++ b/queue-2.6.19/net_sched-policer-restore-compatibility-with-old-iproute-binaries.patch @@ -0,0 +1,85 @@ +From stable-bounces@linux.kernel.org Thu Nov 30 20:11:29 2006 +Date: Thu, 30 Nov 2006 20:06:33 -0800 (PST) +Message-Id: <20061130.200633.94556709.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: NET_SCHED: policer: restore compatibility with old iproute binaries + +From: Patrick McHardy + +The tc actions increased the size of struct tc_police, which broke +compatibility with old iproute binaries since both the act_police +and the old NET_CLS_POLICE code check for an exact size match. + +Since the new members are not even used, the simple fix is to also +accept the size of the old structure. Dumping is not affected since +old userspace will receive a bigger structure, which is handled fine. + +Signed-off-by: Patrick McHardy +Acked-by: Jamal Hadi Salim +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright + +--- +--- + net/sched/act_police.c | 26 ++++++++++++++++++++++---- + 1 file changed, 22 insertions(+), 4 deletions(-) + +--- linux-2.6.19.orig/net/sched/act_police.c ++++ linux-2.6.19/net/sched/act_police.c +@@ -46,6 +46,18 @@ static struct tcf_hashinfo police_hash_i + .lock = &police_lock, + }; + ++/* old policer structure from before tc actions */ ++struct tc_police_compat ++{ ++ u32 index; ++ int action; ++ u32 limit; ++ u32 burst; ++ u32 mtu; ++ struct tc_ratespec rate; ++ struct tc_ratespec peakrate; ++}; ++ + /* Each policer is serialized by its individual spinlock */ + + #ifdef CONFIG_NET_CLS_ACT +@@ -131,12 +143,15 @@ static int tcf_act_police_locate(struct + struct tc_police *parm; + struct tcf_police *police; + struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL; ++ int size; + + if (rta == NULL || rtattr_parse_nested(tb, TCA_POLICE_MAX, rta) < 0) + return -EINVAL; + +- if (tb[TCA_POLICE_TBF-1] == NULL || +- RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]) != sizeof(*parm)) ++ if (tb[TCA_POLICE_TBF-1] == NULL) ++ return -EINVAL; ++ size = RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]); ++ if (size != sizeof(*parm) && size != sizeof(struct tc_police_compat)) + return -EINVAL; + parm = RTA_DATA(tb[TCA_POLICE_TBF-1]); + +@@ -415,12 +430,15 @@ struct tcf_police *tcf_police_locate(str + struct tcf_police *police; + struct rtattr *tb[TCA_POLICE_MAX]; + struct tc_police *parm; ++ int size; + + if (rtattr_parse_nested(tb, TCA_POLICE_MAX, rta) < 0) + return NULL; + +- if (tb[TCA_POLICE_TBF-1] == NULL || +- RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]) != sizeof(*parm)) ++ if (tb[TCA_POLICE_TBF-1] == NULL) ++ return NULL; ++ size = RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]); ++ if (size != sizeof(*parm) && size != sizeof(struct tc_police_compat)) + return NULL; + + parm = RTA_DATA(tb[TCA_POLICE_TBF-1]); diff --git a/queue-2.6.19/series b/queue-2.6.19/series index 459513f1000..50073be68da 100644 --- a/queue-2.6.19/series +++ b/queue-2.6.19/series @@ -1,2 +1,7 @@ ndisc-calculate-packet-length-correctly-for-allocation.patch softmac-remove-netif_tx_disable-when-scanning.patch +ebtables-fix-wraparounds-in-ebt_entries-verification.patch +ebtables-verify-that-ebt_entries-have-zero-distinguisher.patch +ebtables-deal-with-the-worst-case-behaviour-in-loop-checks.patch +ebtables-prevent-wraparounds-in-checks-for-entry-components-sizes.patch +net_sched-policer-restore-compatibility-with-old-iproute-binaries.patch