Skip to content
Permalink
Browse files
ax25: Fix deadlock hang during concurrent read and write on socket.
Before this patch, this hangs, because the read(2) blocks the
write(2).

Before:
strace -f -eread,write ./examples/client_lockcheck M0THC-9 M0THC-0 M0THC-2
strace: Process 3888 attached
[pid  3888] read(3,  <unfinished ...>
[pid  3887] write(3, "hello world", 11
[hang]

After:
strace -f -eread,write ./examples/client_lockcheck M0THC-9 M0THC-0 M0THC-2
strace: Process 2433 attached
[pid  2433] read(3,  <unfinished ...>
[pid  2432] write(3, "hello world", 11) = 11
[pid  2433] <... read resumed> "yo", 1000) = 2
[pid  2433] write(1, "yo\n", 3yo
)         = 3
[successful exit]

Signed-off-by: Thomas Habets <thomas@habets.se>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
  • Loading branch information
ThomasHabets authored and intel-lab-lkp committed Oct 12, 2021
1 parent 5047212 commit 89cd241b1014e6501130d9116ea6ca367b10dc6a
Showing 1 changed file with 4 additions and 3 deletions.
@@ -1624,22 +1624,22 @@ static int ax25_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
int copied;
int err = 0;

lock_sock(sk);
/*
* This works for seqpacket too. The receiver has ordered the
* queue for us! We do one quick check first though
*/
if (sk->sk_type == SOCK_SEQPACKET && sk->sk_state != TCP_ESTABLISHED) {
err = -ENOTCONN;
goto out;
goto out_nolock;
}

/* Now we can treat all alike */
skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
flags & MSG_DONTWAIT, &err);
if (skb == NULL)
goto out;
goto out_nolock;

lock_sock(sk);
if (!sk_to_ax25(sk)->pidincl)
skb_pull(skb, 1); /* Remove PID */

@@ -1684,6 +1684,7 @@ static int ax25_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,

out:
release_sock(sk);
out_nolock:

return err;
}

0 comments on commit 89cd241

Please sign in to comment.