Skip to content

Commit

Permalink
ax25: Fix deadlock hang during concurrent read and write on socket.
Browse files Browse the repository at this point in the history
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 89cd241
Showing 1 changed file with 4 additions and 3 deletions.
7 changes: 4 additions & 3 deletions net/ax25/af_ax25.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 89cd241

Please sign in to comment.