summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'tags/2.6.18-5/30003_netlink-infinite-recursion.patch')
-rw-r--r--tags/2.6.18-5/30003_netlink-infinite-recursion.patch65
1 files changed, 65 insertions, 0 deletions
diff --git a/tags/2.6.18-5/30003_netlink-infinite-recursion.patch b/tags/2.6.18-5/30003_netlink-infinite-recursion.patch
new file mode 100644
index 0000000..df76325
--- /dev/null
+++ b/tags/2.6.18-5/30003_netlink-infinite-recursion.patch
@@ -0,0 +1,65 @@
+From: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
+Date: Wed, 25 Apr 2007 20:59:03 +0000 (+0000)
+Subject: [PATCH] NETLINK: Infinite recursion in netlink.
+X-Git-Tag: v2.6.20.8~1
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fstable%2Flinux-2.6.20.y.git;a=commitdiff_plain;h=9bc1779885f4ce1a4257c5640c70b75d2ae124ad
+
+[PATCH] NETLINK: Infinite recursion in netlink.
+
+[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>
+---
+
+diff -urN linux-source-2.6.18.orig/net/ipv4/fib_frontend.c linux-source-2.6.18/net/ipv4/fib_frontend.c
+--- linux-source-2.6.18.orig/net/ipv4/fib_frontend.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/net/ipv4/fib_frontend.c 2007-05-01 15:21:37.000000000 -0600
+@@ -524,6 +524,8 @@
+ .fwmark = frn->fl_fwmark,
+ .tos = frn->fl_tos,
+ .scope = frn->fl_scope } } };
++
++ frn->err = -ENOENT;
+ if (tb) {
+ local_bh_disable();
+
+@@ -535,6 +537,7 @@
+ frn->nh_sel = res.nh_sel;
+ frn->type = res.type;
+ frn->scope = res.scope;
++ fib_res_put(&res);
+ }
+ local_bh_enable();
+ }
+@@ -549,6 +552,9 @@
+ 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))) {
+@@ -561,7 +567,7 @@
+
+ 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_pid = pid;
+ NETLINK_CB(skb).dst_group = 0; /* unicast */