lkml.org 
[lkml]   [2020]   [Jun]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.7 367/388] bpf/sockmap: Fix kernel panic at __tcp_bpf_recvmsg
    Date
    From: dihu <anny.hu@linux.alibaba.com>

    [ Upstream commit 487082fb7bd2a32b66927d2b22e3a81b072b44f0 ]

    When user application calls read() with MSG_PEEK flag to read data
    of bpf sockmap socket, kernel panic happens at
    __tcp_bpf_recvmsg+0x12c/0x350. sk_msg is not removed from ingress_msg
    queue after read out under MSG_PEEK flag is set. Because it's not
    judged whether sk_msg is the last msg of ingress_msg queue, the next
    sk_msg may be the head of ingress_msg queue, whose memory address of
    sg page is invalid. So it's necessary to add check codes to prevent
    this problem.

    [20759.125457] BUG: kernel NULL pointer dereference, address:
    0000000000000008
    [20759.132118] CPU: 53 PID: 51378 Comm: envoy Tainted: G E
    5.4.32 #1
    [20759.140890] Hardware name: Inspur SA5212M4/YZMB-00370-109, BIOS
    4.1.12 06/18/2017
    [20759.149734] RIP: 0010:copy_page_to_iter+0xad/0x300
    [20759.270877] __tcp_bpf_recvmsg+0x12c/0x350
    [20759.276099] tcp_bpf_recvmsg+0x113/0x370
    [20759.281137] inet_recvmsg+0x55/0xc0
    [20759.285734] __sys_recvfrom+0xc8/0x130
    [20759.290566] ? __audit_syscall_entry+0x103/0x130
    [20759.296227] ? syscall_trace_enter+0x1d2/0x2d0
    [20759.301700] ? __audit_syscall_exit+0x1e4/0x290
    [20759.307235] __x64_sys_recvfrom+0x24/0x30
    [20759.312226] do_syscall_64+0x55/0x1b0
    [20759.316852] entry_SYSCALL_64_after_hwframe+0x44/0xa9

    Signed-off-by: dihu <anny.hu@linux.alibaba.com>
    Signed-off-by: Alexei Starovoitov <ast@kernel.org>
    Acked-by: John Fastabend <john.fastabend@gmail.com>
    Acked-by: Jakub Sitnicki <jakub@cloudflare.com>
    Link: https://lore.kernel.org/bpf/20200605084625.9783-1-anny.hu@linux.alibaba.com
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    net/ipv4/tcp_bpf.c | 3 +++
    1 file changed, 3 insertions(+)

    diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
    index 9c5540887fbe..7aa68f4aae6c 100644
    --- a/net/ipv4/tcp_bpf.c
    +++ b/net/ipv4/tcp_bpf.c
    @@ -64,6 +64,9 @@ int __tcp_bpf_recvmsg(struct sock *sk, struct sk_psock *psock,
    } while (i != msg_rx->sg.end);

    if (unlikely(peek)) {
    + if (msg_rx == list_last_entry(&psock->ingress_msg,
    + struct sk_msg, list))
    + break;
    msg_rx = list_next_entry(msg_rx, list);
    continue;
    }
    --
    2.25.1
    \
     
     \ /
      Last update: 2020-06-18 04:56    [W:4.042 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site