aboutsummaryrefslogtreecommitdiff
path: root/net/ipv4
diff options
context:
space:
mode:
authorAdrian Bunk <bunk@stusta.de>2007-05-01 01:11:29 +0200
committerAdrian Bunk <bunk@stusta.de>2007-05-01 01:11:29 +0200
commitca80e5b5767e8a2bf0714f9797b872258e500ee6 (patch)
treeb6b8daf2688deeff078278c8edc838ee80cfc74c /net/ipv4
parent0ea2b4b19d3bc0d4075a4f176a9da5797be73304 (diff)
[NETLINK]: Infinite recursion in netlink (CVE-2007-1861)
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 Sergey Vlasov: Oops fix Signed-off-by: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> Signed-off-by: Sergey Vlasov <vsu@altlinux.ru> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Adrian Bunk <bunk@stusta.de>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/fib_frontend.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 4e3d3811dea..5ca2af0a1c2 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -525,6 +525,12 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb )
.fwmark = frn->fl_fwmark,
.tos = frn->fl_tos,
.scope = frn->fl_scope } } };
+
+#ifdef CONFIG_IP_MULTIPLE_TABLES
+ res.r = NULL;
+#endif
+
+ frn->err = -ENOENT;
if (tb) {
local_bh_disable();
@@ -536,6 +542,7 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb )
frn->nh_sel = res.nh_sel;
frn->type = res.type;
frn->scope = res.scope;
+ fib_res_put(&res);
}
local_bh_enable();
}
@@ -550,6 +557,9 @@ static void nl_fib_input(struct sock *sk, int len)
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))) {
@@ -562,7 +572,7 @@ static void nl_fib_input(struct sock *sk, int len)
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 */