]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
linux 2.6.20.8 release v2.6.20.8
authorGreg Kroah-Hartman <gregkh@suse.de>
Wed, 25 Apr 2007 22:17:57 +0000 (15:17 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 25 Apr 2007 22:17:57 +0000 (15:17 -0700)
releases/2.6.20.8/netlink-infinite-recursion-in-netlink.patch [new file with mode: 0644]

diff --git a/releases/2.6.20.8/netlink-infinite-recursion-in-netlink.patch b/releases/2.6.20.8/netlink-infinite-recursion-in-netlink.patch
new file mode 100644 (file)
index 0000000..59f6536
--- /dev/null
@@ -0,0 +1,68 @@
+From git-commits-head-owner@vger.kernel.org Wed Apr 25 14:00:42 2007
+From: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
+Date: Wed, 25 Apr 2007 20:59:03 GMT
+Subject: NETLINK: Infinite recursion in netlink.
+To: git-commits-head@vger.kernel.org
+Message-ID: <200704252059.l3PKx3h7031374@hera.kernel.org>
+
+From: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
+
+[NETLINK]: Infinite recursion in netlink.
+
+Reply to NETLINK_FIB_LOOKUP messages were misrouted back to kernel,
+which resulted in infinite recursion and stack overflow.
+
+The bug is present in all kernel versions since the feature appeared.
+
+The patch also makes some minimal cleanup:
+
+1. Return something consistent (-ENOENT) when fib table is missing
+2. Do not crash when queue is empty (does not happen, but yet)
+3. Put result of lookup
+
+Signed-off-by: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv4/fib_frontend.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/net/ipv4/fib_frontend.c
++++ b/net/ipv4/fib_frontend.c
+@@ -772,6 +772,8 @@ static void nl_fib_lookup(struct fib_res
+                                      .nl_u = { .ip4_u = { .daddr = frn->fl_addr,
+                                                           .tos = frn->fl_tos,
+                                                           .scope = frn->fl_scope } } };
++
++      frn->err = -ENOENT;
+       if (tb) {
+               local_bh_disable();
+@@ -783,6 +785,7 @@ static void nl_fib_lookup(struct fib_res
+                       frn->nh_sel = res.nh_sel;
+                       frn->type = res.type;
+                       frn->scope = res.scope;
++                      fib_res_put(&res);
+               }
+               local_bh_enable();
+       }
+@@ -797,6 +800,9 @@ static void nl_fib_input(struct sock *sk
+       struct fib_table *tb;
+       
+       skb = skb_dequeue(&sk->sk_receive_queue);
++      if (skb == NULL)
++              return;
++
+       nlh = (struct nlmsghdr *)skb->data;
+       if (skb->len < NLMSG_SPACE(0) || skb->len < nlh->nlmsg_len ||
+           nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*frn))) {
+@@ -809,7 +815,7 @@ static void nl_fib_input(struct sock *sk
+       nl_fib_lookup(frn, tb);
+       
+-      pid = nlh->nlmsg_pid;           /*pid of sending process */
++      pid = NETLINK_CB(skb).pid;       /* pid of sending process */
+       NETLINK_CB(skb).pid = 0;         /* from kernel */
+       NETLINK_CB(skb).dst_group = 0;  /* unicast */
+       netlink_unicast(sk, skb, pid, MSG_DONTWAIT);