Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e400cfa

Browse files
q2venPaolo Abeni
authored andcommitted
af_unix: Fix wrong ioctl(SIOCATMARK) when consumed OOB skb is at the head.
Even if OOB data is recv()ed, ioctl(SIOCATMARK) must return 1 when the OOB skb is at the head of the receive queue and no new OOB data is queued. Without fix: # RUN msg_oob.no_peek.oob ... # msg_oob.c:305:oob:Expected answ[0] (0) == oob_head (1) # oob: Test terminated by assertion # FAIL msg_oob.no_peek.oob not ok 2 msg_oob.no_peek.oob With fix: # RUN msg_oob.no_peek.oob ... # OK msg_oob.no_peek.oob ok 2 msg_oob.no_peek.oob Fixes: 314001f ("af_unix: Add OOB support") Signed-off-by: Kuniyuki Iwashima <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 48a9983 commit e400cfa

File tree

2 files changed

+81
-2
lines changed

2 files changed

+81
-2
lines changed

net/unix/af_unix.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3107,12 +3107,23 @@ static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
31073107
#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
31083108
case SIOCATMARK:
31093109
{
3110+
struct unix_sock *u = unix_sk(sk);
31103111
struct sk_buff *skb;
31113112
int answ = 0;
31123113

3114+
mutex_lock(&u->iolock);
3115+
31133116
skb = skb_peek(&sk->sk_receive_queue);
3114-
if (skb && skb == READ_ONCE(unix_sk(sk)->oob_skb))
3115-
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+
31163127
err = put_user(answ, (int __user *)arg);
31173128
}
31183129
break;

tools/testing/selftests/net/af_unix/msg_oob.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,26 @@ static void __setinlinepair(struct __test_metadata *_metadata,
288288
}
289289
}
290290

291+
static void __siocatmarkpair(struct __test_metadata *_metadata,
292+
FIXTURE_DATA(msg_oob) *self,
293+
bool oob_head)
294+
{
295+
int answ[2] = {};
296+
int i;
297+
298+
for (i = 0; i < 2; i++) {
299+
int ret;
300+
301+
ret = ioctl(self->fd[i * 2 + 1], SIOCATMARK, &answ[i]);
302+
ASSERT_EQ(ret, 0);
303+
}
304+
305+
ASSERT_EQ(answ[0], oob_head);
306+
307+
if (self->tcp_compliant)
308+
ASSERT_EQ(answ[0], answ[1]);
309+
}
310+
291311
#define sendpair(buf, len, flags) \
292312
__sendpair(_metadata, self, buf, len, flags)
293313

@@ -304,6 +324,9 @@ static void __setinlinepair(struct __test_metadata *_metadata,
304324
#define epollpair(oob_remaining) \
305325
__epollpair(_metadata, self, oob_remaining)
306326

327+
#define siocatmarkpair(oob_head) \
328+
__siocatmarkpair(_metadata, self, oob_head)
329+
307330
#define setinlinepair() \
308331
__setinlinepair(_metadata, self)
309332

@@ -325,9 +348,11 @@ TEST_F(msg_oob, oob)
325348
{
326349
sendpair("x", 1, MSG_OOB);
327350
epollpair(true);
351+
siocatmarkpair(true);
328352

329353
recvpair("x", 1, 1, MSG_OOB);
330354
epollpair(false);
355+
siocatmarkpair(true);
331356
}
332357

333358
TEST_F(msg_oob, oob_drop)
@@ -481,18 +506,40 @@ TEST_F(msg_oob, ex_oob_ahead_break)
481506
epollpair(false);
482507
}
483508

509+
TEST_F(msg_oob, ex_oob_siocatmark)
510+
{
511+
sendpair("hello", 5, MSG_OOB);
512+
epollpair(true);
513+
siocatmarkpair(false);
514+
515+
recvpair("o", 1, 1, MSG_OOB);
516+
epollpair(false);
517+
siocatmarkpair(false);
518+
519+
sendpair("world", 5, MSG_OOB);
520+
epollpair(true);
521+
siocatmarkpair(false);
522+
523+
recvpair("hell", 4, 4, 0); /* Intentionally stop at ex-OOB. */
524+
epollpair(true);
525+
siocatmarkpair(false);
526+
}
527+
484528
TEST_F(msg_oob, inline_oob)
485529
{
486530
setinlinepair();
487531

488532
sendpair("x", 1, MSG_OOB);
489533
epollpair(true);
534+
siocatmarkpair(true);
490535

491536
recvpair("", -EINVAL, 1, MSG_OOB);
492537
epollpair(true);
538+
siocatmarkpair(true);
493539

494540
recvpair("x", 1, 1, 0);
495541
epollpair(false);
542+
siocatmarkpair(false);
496543
}
497544

498545
TEST_F(msg_oob, inline_oob_break)
@@ -591,4 +638,25 @@ TEST_F(msg_oob, inline_ex_oob_drop)
591638
}
592639
}
593640

641+
TEST_F(msg_oob, inline_ex_oob_siocatmark)
642+
{
643+
sendpair("hello", 5, MSG_OOB);
644+
epollpair(true);
645+
siocatmarkpair(false);
646+
647+
recvpair("o", 1, 1, MSG_OOB);
648+
epollpair(false);
649+
siocatmarkpair(false);
650+
651+
setinlinepair();
652+
653+
sendpair("world", 5, MSG_OOB);
654+
epollpair(true);
655+
siocatmarkpair(false);
656+
657+
recvpair("hell", 4, 4, 0); /* Intentionally stop at ex-OOB. */
658+
epollpair(true);
659+
siocatmarkpair(false);
660+
}
661+
594662
TEST_HARNESS_MAIN

0 commit comments

Comments
 (0)