summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Dichtel <nicolas.dichtel@6wind.com>2013-11-08 11:13:55 +0100
committerWilly Tarreau <w@1wt.eu>2014-05-19 07:54:19 +0200
commit8663707a797e6a473c32cf08eb7597543bbdae79 (patch)
tree645f35090c28c2fbc47ba85eacdd142bf11aa59c
parent8753987aa676b02e907d72713d78ff3a9de8a5ad (diff)
sctp: unbalanced rcu lock in ip_queue_xmit()
The bug was introduced in 2.6.32.61 by commit b8710128e201 ("inet: add RCU protection to inet->opt") (it's a backport of upstream commit f6d8bd051c39). In SCTP case, packet is already routed, hence we jump to the label 'packet_routed', but without rcu_read_lock(). After this label, rcu_read_unlock() is called unconditionally. Spotted-by: Guo Fengtian <fengtian.guo@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Signed-off-by: Willy Tarreau <w@1wt.eu>
-rw-r--r--net/ipv4/ip_output.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 7dde039374e4..2cd69e3497ad 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -320,13 +320,13 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
/* Skip all of this if the packet is already routed,
* f.e. by something like SCTP.
*/
+ rcu_read_lock();
rt = skb_rtable(skb);
if (rt != NULL)
goto packet_routed;
/* Make sure we can route this packet. */
rt = (struct rtable *)__sk_dst_check(sk, 0);
- rcu_read_lock();
inet_opt = rcu_dereference(inet->inet_opt);
if (rt == NULL) {
__be32 daddr;