diff options
author | Sasha Levin <sasha.levin@oracle.com> | 2013-12-07 17:26:27 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-10 21:45:15 -0500 |
commit | 12663bfc97c8b3fdb292428105dd92d563164050 (patch) | |
tree | 3cfc0b33e9c96636e397c9c19806208735556b14 /net/unix | |
parent | 88b07b3660362049769f36c94f2c5a623424c992 (diff) | |
download | linux-stable-12663bfc97c8b3fdb292428105dd92d563164050.tar.gz linux-stable-12663bfc97c8b3fdb292428105dd92d563164050.tar.bz2 linux-stable-12663bfc97c8b3fdb292428105dd92d563164050.zip |
net: unix: allow set_peek_off to fail
unix_dgram_recvmsg() will hold the readlock of the socket until recv
is complete.
In the same time, we may try to setsockopt(SO_PEEK_OFF) which will hang until
unix_dgram_recvmsg() will complete (which can take a while) without allowing
us to break out of it, triggering a hung task spew.
Instead, allow set_peek_off to fail, this way userspace will not hang.
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/unix')
-rw-r--r-- | net/unix/af_unix.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 01625ccc3ae6..a0ca162e5bd5 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -530,13 +530,17 @@ static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *, static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *, struct msghdr *, size_t, int); -static void unix_set_peek_off(struct sock *sk, int val) +static int unix_set_peek_off(struct sock *sk, int val) { struct unix_sock *u = unix_sk(sk); - mutex_lock(&u->readlock); + if (mutex_lock_interruptible(&u->readlock)) + return -EINTR; + sk->sk_peek_off = val; mutex_unlock(&u->readlock); + + return 0; } |