Skip to content

Commit 3f4d9e4

Browse files
author
Paolo Abeni
committed
Merge branch 'af_unix-fix-bunch-of-msg_oob-bugs-and-add-new-tests'
Kuniyuki Iwashima says: ==================== af_unix: Fix bunch of MSG_OOB bugs and add new tests. This series rewrites the selftest for AF_UNIX MSG_OOB and fixes bunch of bugs that AF_UNIX behaves differently compared to TCP. Note that the test discovered few more bugs in TCP side, which will be fixed in another series. ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
2 parents bab4923 + 91b7186 commit 3f4d9e4

File tree

5 files changed

+766
-444
lines changed

5 files changed

+766
-444
lines changed

net/unix/af_unix.c

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2613,10 +2613,24 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
26132613
{
26142614
struct unix_sock *u = unix_sk(sk);
26152615

2616-
if (!unix_skb_len(skb) && !(flags & MSG_PEEK)) {
2617-
skb_unlink(skb, &sk->sk_receive_queue);
2618-
consume_skb(skb);
2619-
skb = NULL;
2616+
if (!unix_skb_len(skb)) {
2617+
struct sk_buff *unlinked_skb = NULL;
2618+
2619+
spin_lock(&sk->sk_receive_queue.lock);
2620+
2621+
if (copied && (!u->oob_skb || skb == u->oob_skb)) {
2622+
skb = NULL;
2623+
} else if (flags & MSG_PEEK) {
2624+
skb = skb_peek_next(skb, &sk->sk_receive_queue);
2625+
} else {
2626+
unlinked_skb = skb;
2627+
skb = skb_peek_next(skb, &sk->sk_receive_queue);
2628+
__skb_unlink(unlinked_skb, &sk->sk_receive_queue);
2629+
}
2630+
2631+
spin_unlock(&sk->sk_receive_queue.lock);
2632+
2633+
consume_skb(unlinked_skb);
26202634
} else {
26212635
struct sk_buff *unlinked_skb = NULL;
26222636

@@ -3093,12 +3107,23 @@ static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
30933107
#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
30943108
case SIOCATMARK:
30953109
{
3110+
struct unix_sock *u = unix_sk(sk);
30963111
struct sk_buff *skb;
30973112
int answ = 0;
30983113

3114+
mutex_lock(&u->iolock);
3115+
30993116
skb = skb_peek(&sk->sk_receive_queue);
3100-
if (skb && skb == READ_ONCE(unix_sk(sk)->oob_skb))
3101-
answ = 1;
3117+
if (skb) {
3118+
struct sk_buff *oob_skb = READ_ONCE(u->oob_skb);
3119+
3120+
if (skb == oob_skb ||
3121+
(!oob_skb && !unix_skb_len(skb)))
3122+
answ = 1;
3123+
}
3124+
3125+
mutex_unlock(&u->iolock);
3126+
31023127
err = put_user(answ, (int __user *)arg);
31033128
}
31043129
break;

tools/testing/selftests/net/.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ tap
4343
tcp_fastopen_backup_key
4444
tcp_inq
4545
tcp_mmap
46-
test_unix_oob
4746
timestamping
4847
tls
4948
toeplitz
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
CFLAGS += $(KHDR_INCLUDES)
2-
TEST_GEN_PROGS := diag_uid test_unix_oob unix_connect scm_pidfd scm_rights
2+
TEST_GEN_PROGS := diag_uid msg_oob scm_pidfd scm_rights unix_connect
33

44
include ../../lib.mk

0 commit comments

Comments
 (0)