lkml.org 
[lkml]   [2022]   [Jun]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.18 098/181] sock: redo the psock vs ULP protection check
    Date
    From: Jakub Kicinski <kuba@kernel.org>

    [ Upstream commit e34a07c0ae3906f97eb18df50902e2a01c1015b6 ]

    Commit 8a59f9d1e3d4 ("sock: Introduce sk->sk_prot->psock_update_sk_prot()")
    has moved the inet_csk_has_ulp(sk) check from sk_psock_init() to
    the new tcp_bpf_update_proto() function. I'm guessing that this
    was done to allow creating psocks for non-inet sockets.

    Unfortunately the destruction path for psock includes the ULP
    unwind, so we need to fail the sk_psock_init() itself.
    Otherwise if ULP is already present we'll notice that later,
    and call tcp_update_ulp() with the sk_proto of the ULP
    itself, which will most likely result in the ULP looping
    its callbacks.

    Fixes: 8a59f9d1e3d4 ("sock: Introduce sk->sk_prot->psock_update_sk_prot()")
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>
    Reviewed-by: John Fastabend <john.fastabend@gmail.com>
    Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com>
    Tested-by: Jakub Sitnicki <jakub@cloudflare.com>
    Link: https://lore.kernel.org/r/20220620191353.1184629-2-kuba@kernel.org
    Signed-off-by: Paolo Abeni <pabeni@redhat.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    include/net/inet_sock.h | 5 +++++
    net/core/skmsg.c | 5 +++++
    net/ipv4/tcp_bpf.c | 3 ---
    net/tls/tls_main.c | 2 ++
    4 files changed, 12 insertions(+), 3 deletions(-)

    diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
    index 234d70ae5f4c..48e4c59d85e2 100644
    --- a/include/net/inet_sock.h
    +++ b/include/net/inet_sock.h
    @@ -252,6 +252,11 @@ struct inet_sock {
    #define IP_CMSG_CHECKSUM BIT(7)
    #define IP_CMSG_RECVFRAGSIZE BIT(8)

    +static inline bool sk_is_inet(struct sock *sk)
    +{
    + return sk->sk_family == AF_INET || sk->sk_family == AF_INET6;
    +}
    +
    /**
    * sk_to_full_sk - Access to a full socket
    * @sk: pointer to a socket
    diff --git a/net/core/skmsg.c b/net/core/skmsg.c
    index cc381165ea08..ede0af308f40 100644
    --- a/net/core/skmsg.c
    +++ b/net/core/skmsg.c
    @@ -695,6 +695,11 @@ struct sk_psock *sk_psock_init(struct sock *sk, int node)

    write_lock_bh(&sk->sk_callback_lock);

    + if (sk_is_inet(sk) && inet_csk_has_ulp(sk)) {
    + psock = ERR_PTR(-EINVAL);
    + goto out;
    + }
    +
    if (sk->sk_user_data) {
    psock = ERR_PTR(-EBUSY);
    goto out;
    diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
    index 1cdcb4df0eb7..2c597a4e429a 100644
    --- a/net/ipv4/tcp_bpf.c
    +++ b/net/ipv4/tcp_bpf.c
    @@ -612,9 +612,6 @@ int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore)
    return 0;
    }

    - if (inet_csk_has_ulp(sk))
    - return -EINVAL;
    -
    if (sk->sk_family == AF_INET6) {
    if (tcp_bpf_assert_proto_ops(psock->sk_proto))
    return -EINVAL;
    diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
    index 7b2b0e7ffee4..5c9697840ef7 100644
    --- a/net/tls/tls_main.c
    +++ b/net/tls/tls_main.c
    @@ -873,6 +873,8 @@ static void tls_update(struct sock *sk, struct proto *p,
    {
    struct tls_context *ctx;

    + WARN_ON_ONCE(sk->sk_prot == p);
    +
    ctx = tls_get_ctx(sk);
    if (likely(ctx)) {
    ctx->sk_write_space = write_space;
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-06-27 13:55    [W:4.146 / U:0.212 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site