[NETFILTER]: Fix deadlock with ip_queue and tcp local input path.

When we have ip_queue being used from LOCAL_IN, then we end up with a
situation where the verdicts coming back from userspace traverse the TCP
input path from syscall context. While this seems to work most of the
time, there's an ugly deadlock:

syscall context is interrupted by the timer interrupt. When the timer
interrupt leaves, the timer softirq get's scheduled and calls
tcp_delack_timer() and alike. They themselves do bh_lock_sock(sk),
which is already held from somewhere else -> boom.

I've now tested the suggested solution by Patrick McHardy and Herbert Xu to
simply use local_bh_{en,dis}able().

Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Harald Welte and committed by
David S. Miller
9bb7bc94 5e485b79

+10
+10
net/ipv4/netfilter/ip_queue.c
··· 3 3 * communicating with userspace via netlink. 4 4 * 5 5 * (C) 2000-2002 James Morris <jmorris@intercode.com.au> 6 + * (C) 2003-2005 Netfilter Core Team <coreteam@netfilter.org> 6 7 * 7 8 * This program is free software; you can redistribute it and/or modify 8 9 * it under the terms of the GNU General Public License version 2 as ··· 18 17 * 2005-01-10: Added /proc counter for dropped packets; fixed so 19 18 * packets aren't delivered to user space if they're going 20 19 * to be dropped. 20 + * 2005-05-26: local_bh_{disable,enable} around nf_reinject (Harald Welte) 21 21 * 22 22 */ 23 23 #include <linux/module.h> ··· 73 71 static void 74 72 ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict) 75 73 { 74 + /* TCP input path (and probably other bits) assume to be called 75 + * from softirq context, not from syscall, like ipq_issue_verdict is 76 + * called. TCP input path deadlocks with locks taken from timer 77 + * softirq, e.g. We therefore emulate this by local_bh_disable() */ 78 + 79 + local_bh_disable(); 76 80 nf_reinject(entry->skb, entry->info, verdict); 81 + local_bh_enable(); 82 + 77 83 kfree(entry); 78 84 } 79 85