]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
networking patches from DaveM for 2.6.18/19 queues
authorChris Wright <chrisw@sous-sol.org>
Fri, 1 Dec 2006 07:02:24 +0000 (23:02 -0800)
committerChris Wright <chrisw@sous-sol.org>
Fri, 1 Dec 2006 07:02:24 +0000 (23:02 -0800)
12 files changed:
queue-2.6.18/ebtables-deal-with-the-worst-case-behaviour-in-loop-checks.patch [new file with mode: 0644]
queue-2.6.18/ebtables-fix-wraparounds-in-ebt_entries-verification.patch [new file with mode: 0644]
queue-2.6.18/ebtables-prevent-wraparounds-in-checks-for-entry-components-sizes.patch [new file with mode: 0644]
queue-2.6.18/ebtables-verify-that-ebt_entries-have-zero-distinguisher.patch [new file with mode: 0644]
queue-2.6.18/net_sched-policer-restore-compatibility-with-old-iproute-binaries.patch [new file with mode: 0644]
queue-2.6.18/series
queue-2.6.19/ebtables-deal-with-the-worst-case-behaviour-in-loop-checks.patch [new file with mode: 0644]
queue-2.6.19/ebtables-fix-wraparounds-in-ebt_entries-verification.patch [new file with mode: 0644]
queue-2.6.19/ebtables-prevent-wraparounds-in-checks-for-entry-components-sizes.patch [new file with mode: 0644]
queue-2.6.19/ebtables-verify-that-ebt_entries-have-zero-distinguisher.patch [new file with mode: 0644]
queue-2.6.19/net_sched-policer-restore-compatibility-with-old-iproute-binaries.patch [new file with mode: 0644]
queue-2.6.19/series

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 (file)
index 0000000..f58d35b
--- /dev/null
@@ -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 <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: EBTABLES: Deal with the worst-case behaviour in loop checks.
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+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 <viro@zeniv.linux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+---
+ 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 (file)
index 0000000..621d832
--- /dev/null
@@ -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 <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: EBTABLES: Fix wraparounds in ebt_entries verification.
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+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 <viro@zeniv.linux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+---
+ 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 (file)
index 0000000..77edebb
--- /dev/null
@@ -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 <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: EBTABLES: Prevent wraparounds in checks for entry components' sizes.
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+---
+ 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 (file)
index 0000000..b172211
--- /dev/null
@@ -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 <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: EBTABLES: Verify that ebt_entries have zero ->distinguisher.
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+We need that for iterator to work; existing check had been too weak.
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+---
+ 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 (file)
index 0000000..9aee7c7
--- /dev/null
@@ -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 <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: NET_SCHED: policer: restore compatibility with old iproute binaries
+
+From: Patrick McHardy <kaber@trash.net>
+
+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 <kaber@trash.net>
+Acked-by: Jamal Hadi Salim <hadi@cyberus.ca>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+---
+ 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]);
index 385a37ff495111bc5940837b63b30c4ad16394e5..6e0bbc915aea03cb70752aee967abf57d0a9d7db 100644 (file)
@@ -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 (file)
index 0000000..99a96b4
--- /dev/null
@@ -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 <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: EBTABLES: Deal with the worst-case behaviour in loop checks.
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+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 <viro@zeniv.linux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+---
+ 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 (file)
index 0000000..b57679a
--- /dev/null
@@ -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 <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: EBTABLES: Fix wraparounds in ebt_entries verification.
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+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 <viro@zeniv.linux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+---
+ 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 (file)
index 0000000..c1f273c
--- /dev/null
@@ -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 <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: EBTABLES: Prevent wraparounds in checks for entry components' sizes.
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+---
+ 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 (file)
index 0000000..758ad4a
--- /dev/null
@@ -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 <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: EBTABLES: Verify that ebt_entries have zero ->distinguisher.
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+We need that for iterator to work; existing check had been too weak.
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+---
+ 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 (file)
index 0000000..5b8972f
--- /dev/null
@@ -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 <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: NET_SCHED: policer: restore compatibility with old iproute binaries
+
+From: Patrick McHardy <kaber@trash.net>
+
+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 <kaber@trash.net>
+Acked-by: Jamal Hadi Salim <hadi@cyberus.ca>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+---
+ 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]);
index 459513f1000fd028d7cad36da2a043dfa324edf2..50073be68da8bb381b0fce3c9198909330a60074 100644 (file)
@@ -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