DORMANTno replies

[PATCH] llc: Fix race condition in llc_ui_recvmsg

From: Radu Iliescu <hidden>
Date: 2012-01-19 13:59:13
Subsystem: llc (802.2), networking [general], the rest · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

There is a race on sk_receive_queue between llc_ui_recvmsg and
sock_queue_rcv_skb.

Our current solution is to protect skb_eat in llc_ui_recvmsg
with the queue spinlock.

Perhaps there is a better solution.
Maybe there is a lock missing in llc_sap_state_process or above.
I've tried to follow the locking in tcp on sk_receive_queue,
but is not clear how is done.

Please take a look and comment.

Signed-off-by: Radu Iliescu <redacted>
---
 net/llc/af_llc.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index a18e6c3..46a60a4 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -719,6 +719,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
 	unsigned long used;
 	int target;	/* Read at least this many bytes */
 	long timeo;
+	long cpu_flags;
 
 	lock_sock(sk);
 	copied = -ENOTCONN;
@@ -838,7 +839,9 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
 			goto copy_uaddr;
 
 		if (!(flags & MSG_PEEK)) {
+			spin_lock_irqsave(&sk->sk_receive_queue.lock, cpu_flags);
 			sk_eat_skb(sk, skb, 0);
+			spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags);
 			*seq = 0;
 		}
 
@@ -859,7 +862,9 @@ copy_uaddr:
 		llc_cmsg_rcv(msg, skb);
 
 	if (!(flags & MSG_PEEK)) {
+			spin_lock_irqsave(&sk->sk_receive_queue.lock, cpu_flags);
 			sk_eat_skb(sk, skb, 0);
+			spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags);
 			*seq = 0;
 	}
 
-- 
1.7.0.4
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help