summaryrefslogtreecommitdiff
path: root/net/unix
diff options
context:
space:
mode:
authorRao Shoaib <Rao.Shoaib@oracle.com>2021-08-13 11:19:34 -0700
committerDavid S. Miller <davem@davemloft.net>2021-08-16 11:12:37 +0100
commit19eed721079336d515dd2d8fe1f0f4c292b78c70 (patch)
tree9ec9ec2db69039b1e05f0528e4e255ab7b21ceba /net/unix
parent6164659ff7acc16f3f37a9278f856fd1fb02a8f9 (diff)
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.c11
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;