mirror of
https://github.com/torvalds/linux.git
synced 2026-09-11 20:13:02 +02:00
Merge branch 'af_unix-minor-fixes-for-msg_oob-and-msg_peek'
Kuniyuki Iwashima says: ==================== af_unix: Minor fixes for MSG_OOB and MSG_PEEK. Fahad Alharbi reported blocking recv(MSG_PEEK) could hog CPU due to OOB skb. Patch 1 and 2 fixes the issues and Patch 3 adds tests. ==================== Link: https://patch.msgid.link/20260902202202.892676-1-kuniyu@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
dead0c41db
|
|
@ -2812,8 +2812,8 @@ static int unix_stream_recv_urg(struct unix_stream_read_state *state)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
|
||||
int flags, int copied)
|
||||
static struct sk_buff *manage_oob(struct sk_buff *skb, struct sk_buff **last,
|
||||
struct sock *sk, int flags, int copied)
|
||||
{
|
||||
struct sk_buff *read_skb = NULL, *unread_skb = NULL;
|
||||
struct unix_sock *u = unix_sk(sk);
|
||||
|
|
@ -2827,11 +2827,13 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
|
|||
if (copied && (!u->oob_skb || skb == u->oob_skb)) {
|
||||
skb = NULL;
|
||||
} else if (flags & MSG_PEEK) {
|
||||
*last = skb;
|
||||
skb = skb_peek_next(skb, &sk->sk_receive_queue);
|
||||
} else {
|
||||
read_skb = skb;
|
||||
skb = skb_peek_next(skb, &sk->sk_receive_queue);
|
||||
__skb_unlink(read_skb, &sk->sk_receive_queue);
|
||||
*last = skb;
|
||||
}
|
||||
|
||||
if (!skb)
|
||||
|
|
@ -2850,8 +2852,10 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
|
|||
__skb_unlink(skb, &sk->sk_receive_queue);
|
||||
unread_skb = skb;
|
||||
skb = skb_peek(&sk->sk_receive_queue);
|
||||
*last = skb;
|
||||
}
|
||||
} else if (!sock_flag(sk, SOCK_URGINLINE)) {
|
||||
*last = skb;
|
||||
skb = skb_peek_next(skb, &sk->sk_receive_queue);
|
||||
}
|
||||
|
||||
|
|
@ -2971,8 +2975,8 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
|
|||
again:
|
||||
#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
|
||||
if (skb) {
|
||||
skb = manage_oob(skb, sk, flags, copied);
|
||||
if (!skb && copied) {
|
||||
skb = manage_oob(skb, &last, sk, flags, copied);
|
||||
if (!skb && (copied || !state->size)) {
|
||||
unix_state_unlock(sk);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -290,6 +290,25 @@ static void __setinlinepair(struct __test_metadata *_metadata,
|
|||
}
|
||||
}
|
||||
|
||||
static void __setblockingpair(struct __test_metadata *_metadata,
|
||||
FIXTURE_DATA(msg_oob) *self)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
int ret, old_flags, flags;
|
||||
|
||||
old_flags = fcntl(self->fd[i * 2 + 1], F_GETFL, 0);
|
||||
ASSERT_NE(-1, old_flags);
|
||||
|
||||
ret = fcntl(self->fd[i * 2 + 1], F_SETFL, old_flags & ~O_NONBLOCK);
|
||||
ASSERT_EQ(0, ret);
|
||||
|
||||
flags = fcntl(self->fd[i * 2 + 1], F_GETFL, 0);
|
||||
ASSERT_EQ(old_flags & ~O_NONBLOCK, flags);
|
||||
}
|
||||
}
|
||||
|
||||
static void __siocatmarkpair(struct __test_metadata *_metadata,
|
||||
FIXTURE_DATA(msg_oob) *self,
|
||||
bool oob_head)
|
||||
|
|
@ -347,6 +366,9 @@ static void __resetpair(struct __test_metadata *_metadata,
|
|||
#define setinlinepair() \
|
||||
__setinlinepair(_metadata, self)
|
||||
|
||||
#define setblockingpair() \
|
||||
__setblockingpair(_metadata, self)
|
||||
|
||||
#define resetpair(reset) \
|
||||
__resetpair(_metadata, self, variant, reset)
|
||||
|
||||
|
|
@ -888,4 +910,49 @@ TEST_F(msg_oob, inline_ex_oob_siocatmark)
|
|||
resetpair(true);
|
||||
}
|
||||
|
||||
TEST_F(msg_oob, zero_buf_oob)
|
||||
{
|
||||
sendpair("a", 1, MSG_OOB);
|
||||
recvpair("", 0, 0, 0);
|
||||
}
|
||||
|
||||
TEST_F(msg_oob, zero_buf_oob_blocking)
|
||||
{
|
||||
sendpair("a", 1, MSG_OOB);
|
||||
setblockingpair();
|
||||
recvpair("", 0, 0, 0);
|
||||
}
|
||||
|
||||
TEST_F(msg_oob, zero_buf_non_oob_oob)
|
||||
{
|
||||
sendpair("ab", 2, MSG_OOB);
|
||||
recvpair("", 0, 0, 0);
|
||||
}
|
||||
|
||||
TEST_F(msg_oob, zero_buf_non_oob_oob_blocking)
|
||||
{
|
||||
sendpair("ab", 2, MSG_OOB);
|
||||
setblockingpair();
|
||||
recvpair("", 0, 0, 0);
|
||||
}
|
||||
|
||||
TEST_F(msg_oob, zero_buf_ex_oob_oob)
|
||||
{
|
||||
sendpair("a", 1, MSG_OOB);
|
||||
recvpair("a", 1, 1, MSG_OOB);
|
||||
|
||||
sendpair("b", 1, MSG_OOB);
|
||||
recvpair("", 0, 0, 0);
|
||||
}
|
||||
|
||||
TEST_F(msg_oob, zero_buf_ex_oob_oob_blocking)
|
||||
{
|
||||
sendpair("a", 1, MSG_OOB);
|
||||
recvpair("a", 1, 1, MSG_OOB);
|
||||
|
||||
sendpair("b", 1, MSG_OOB);
|
||||
setblockingpair();
|
||||
recvpair("", 0, 0, 0);
|
||||
}
|
||||
|
||||
TEST_HARNESS_MAIN
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user