Skip to content

Commit 0146240

Browse files
jiribohacdavem330
authored andcommitted
ipx: fix locking regression in ipx_sendmsg and ipx_recvmsg
This fixes an old regression introduced by commit b0d0d91 (ipx: remove the BKL). When a recvmsg syscall blocks waiting for new data, no data can be sent on the same socket with sendmsg because ipx_recvmsg() sleeps with the socket locked. This breaks mars-nwe (NetWare emulator): - the ncpserv process reads the request using recvmsg - ncpserv forks and spawns nwconn - ncpserv calls a (blocking) recvmsg and waits for new requests - nwconn deadlocks in sendmsg on the same socket Commit b0d0d91 has simply replaced BKL locking with lock_sock/release_sock. Unlike now, BKL got unlocked while sleeping, so a blocking recvmsg did not block a concurrent sendmsg. Only keep the socket locked while actually working with the socket data and release it prior to calling skb_recv_datagram(). Signed-off-by: Jiri Bohac <[email protected]> Reviewed-by: Arnd Bergmann <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d3052bb commit 0146240

File tree

1 file changed

+5
-1
lines changed

1 file changed

+5
-1
lines changed

net/ipx/af_ipx.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -1764,6 +1764,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
17641764
struct ipxhdr *ipx = NULL;
17651765
struct sk_buff *skb;
17661766
int copied, rc;
1767+
bool locked = true;
17671768

17681769
lock_sock(sk);
17691770
/* put the autobinding in */
@@ -1790,6 +1791,8 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
17901791
if (sock_flag(sk, SOCK_ZAPPED))
17911792
goto out;
17921793

1794+
release_sock(sk);
1795+
locked = false;
17931796
skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
17941797
flags & MSG_DONTWAIT, &rc);
17951798
if (!skb) {
@@ -1826,7 +1829,8 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
18261829
out_free:
18271830
skb_free_datagram(sk, skb);
18281831
out:
1829-
release_sock(sk);
1832+
if (locked)
1833+
release_sock(sk);
18301834
return rc;
18311835
}
18321836

0 commit comments

Comments
 (0)