diff options
author | Rao Shoaib <Rao.Shoaib@oracle.com> | 2021-08-13 11:19:34 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-08-16 11:12:37 +0100 |
commit | 19eed721079336d515dd2d8fe1f0f4c292b78c70 (patch) | |
tree | 9ec9ec2db69039b1e05f0528e4e255ab7b21ceba /net/unix | |
parent | 6164659ff7acc16f3f37a9278f856fd1fb02a8f9 (diff) | |
download | linux-19eed721079336d515dd2d8fe1f0f4c292b78c70.tar.bz2 |
af_unix: check socket state when queuing OOB
edumazet@google.com pointed out that queue_oob
does not check socket state after acquiring
the lock. He also pointed to an incorrect usage
of kfree_skb and an unnecessary setting of skb
length. This patch addresses those issue.
Signed-off-by: Rao Shoaib <Rao.Shoaib@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/unix')
-rw-r--r-- | net/unix/af_unix.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 1c2224f05b51..4cf0b1c47f0f 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1908,7 +1908,6 @@ static int queue_oob(struct socket *sock, struct msghdr *msg, struct sock *other return err; skb_put(skb, 1); - skb->len = 1; err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, 1); if (err) { @@ -1917,11 +1916,19 @@ static int queue_oob(struct socket *sock, struct msghdr *msg, struct sock *other } unix_state_lock(other); + + if (sock_flag(other, SOCK_DEAD) || + (other->sk_shutdown & RCV_SHUTDOWN)) { + unix_state_unlock(other); + kfree_skb(skb); + return -EPIPE; + } + maybe_add_creds(skb, sock, other); skb_get(skb); if (ousk->oob_skb) - kfree_skb(ousk->oob_skb); + consume_skb(ousk->oob_skb); ousk->oob_skb = skb; |