Commit 56ac11cf authored by Radu Iliescu's avatar Radu Iliescu Committed by David S. Miller

llc: Fix race condition in llc_ui_recvmsg

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.
Signed-off-by: default avatarRadu Iliescu <riliescu@ixiacom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 90b9a545
...@@ -713,6 +713,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -713,6 +713,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
struct sk_buff *skb = NULL; struct sk_buff *skb = NULL;
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
unsigned long cpu_flags;
size_t copied = 0; size_t copied = 0;
u32 peek_seq = 0; u32 peek_seq = 0;
u32 *seq; u32 *seq;
...@@ -838,7 +839,9 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -838,7 +839,9 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
goto copy_uaddr; goto copy_uaddr;
if (!(flags & MSG_PEEK)) { if (!(flags & MSG_PEEK)) {
spin_lock_irqsave(&sk->sk_receive_queue.lock, cpu_flags);
sk_eat_skb(sk, skb, 0); sk_eat_skb(sk, skb, 0);
spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags);
*seq = 0; *seq = 0;
} }
...@@ -859,7 +862,9 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -859,7 +862,9 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
llc_cmsg_rcv(msg, skb); llc_cmsg_rcv(msg, skb);
if (!(flags & MSG_PEEK)) { if (!(flags & MSG_PEEK)) {
spin_lock_irqsave(&sk->sk_receive_queue.lock, cpu_flags);
sk_eat_skb(sk, skb, 0); sk_eat_skb(sk, skb, 0);
spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags);
*seq = 0; *seq = 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment