lkml.org 
[lkml]   [2022]   [Apr]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.17 0660/1126] bpf, sockmap: Fix memleak in sk_psock_queue_msg
    Date
    From: Wang Yufen <wangyufen@huawei.com>

    [ Upstream commit 938d3480b92fa5e454b7734294f12a7b75126f09 ]

    If tcp_bpf_sendmsg is running during a tear down operation we may enqueue
    data on the ingress msg queue while tear down is trying to free it.

    sk1 (redirect sk2) sk2
    ------------------- ---------------
    tcp_bpf_sendmsg()
    tcp_bpf_send_verdict()
    tcp_bpf_sendmsg_redir()
    bpf_tcp_ingress()
    sock_map_close()
    lock_sock()
    lock_sock() ... blocking
    sk_psock_stop
    sk_psock_clear_state(psock, SK_PSOCK_TX_ENABLED);
    release_sock(sk);
    lock_sock()
    sk_mem_charge()
    get_page()
    sk_psock_queue_msg()
    sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED);
    drop_sk_msg()
    release_sock()

    While drop_sk_msg(), the msg has charged memory form sk by sk_mem_charge
    and has sg pages need to put. To fix we use sk_msg_free() and then kfee()
    msg.

    This issue can cause the following info:
    WARNING: CPU: 0 PID: 9202 at net/core/stream.c:205 sk_stream_kill_queues+0xc8/0xe0
    Call Trace:
    <IRQ>
    inet_csk_destroy_sock+0x55/0x110
    tcp_rcv_state_process+0xe5f/0xe90
    ? sk_filter_trim_cap+0x10d/0x230
    ? tcp_v4_do_rcv+0x161/0x250
    tcp_v4_do_rcv+0x161/0x250
    tcp_v4_rcv+0xc3a/0xce0
    ip_protocol_deliver_rcu+0x3d/0x230
    ip_local_deliver_finish+0x54/0x60
    ip_local_deliver+0xfd/0x110
    ? ip_protocol_deliver_rcu+0x230/0x230
    ip_rcv+0xd6/0x100
    ? ip_local_deliver+0x110/0x110
    __netif_receive_skb_one_core+0x85/0xa0
    process_backlog+0xa4/0x160
    __napi_poll+0x29/0x1b0
    net_rx_action+0x287/0x300
    __do_softirq+0xff/0x2fc
    do_softirq+0x79/0x90
    </IRQ>

    WARNING: CPU: 0 PID: 531 at net/ipv4/af_inet.c:154 inet_sock_destruct+0x175/0x1b0
    Call Trace:
    <TASK>
    __sk_destruct+0x24/0x1f0
    sk_psock_destroy+0x19b/0x1c0
    process_one_work+0x1b3/0x3c0
    ? process_one_work+0x3c0/0x3c0
    worker_thread+0x30/0x350
    ? process_one_work+0x3c0/0x3c0
    kthread+0xe6/0x110
    ? kthread_complete_and_exit+0x20/0x20
    ret_from_fork+0x22/0x30
    </TASK>

    Fixes: 9635720b7c88 ("bpf, sockmap: Fix memleak on ingress msg enqueue")
    Signed-off-by: Wang Yufen <wangyufen@huawei.com>
    Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
    Acked-by: John Fastabend <john.fastabend@gmail.com>
    Link: https://lore.kernel.org/bpf/20220304081145.2037182-2-wangyufen@huawei.com
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    include/linux/skmsg.h | 13 ++++---------
    1 file changed, 4 insertions(+), 9 deletions(-)

    diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h
    index 18a717fe62eb..7f32dd59e751 100644
    --- a/include/linux/skmsg.h
    +++ b/include/linux/skmsg.h
    @@ -310,21 +310,16 @@ static inline void sock_drop(struct sock *sk, struct sk_buff *skb)
    kfree_skb(skb);
    }

    -static inline void drop_sk_msg(struct sk_psock *psock, struct sk_msg *msg)
    -{
    - if (msg->skb)
    - sock_drop(psock->sk, msg->skb);
    - kfree(msg);
    -}
    -
    static inline void sk_psock_queue_msg(struct sk_psock *psock,
    struct sk_msg *msg)
    {
    spin_lock_bh(&psock->ingress_lock);
    if (sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED))
    list_add_tail(&msg->list, &psock->ingress_msg);
    - else
    - drop_sk_msg(psock, msg);
    + else {
    + sk_msg_free(psock->sk, msg);
    + kfree(msg);
    + }
    spin_unlock_bh(&psock->ingress_lock);
    }

    --
    2.34.1


    \
     
     \ /
      Last update: 2022-04-05 14:28    [W:6.176 / U:1.560 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site