From patchwork Wed May 1 02:06:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Fastabend X-Patchwork-Id: 1093535 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="AqX5xn+r"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44v1ws0d5Fz9s9N for ; Wed, 1 May 2019 12:06:53 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727259AbfEACGw (ORCPT ); Tue, 30 Apr 2019 22:06:52 -0400 Received: from mail-yw1-f67.google.com ([209.85.161.67]:36728 "EHLO mail-yw1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726115AbfEACGw (ORCPT ); Tue, 30 Apr 2019 22:06:52 -0400 Received: by mail-yw1-f67.google.com with SMTP id g29so7442147ywk.3; Tue, 30 Apr 2019 19:06:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:from:to:cc:date:message-id:in-reply-to:references :user-agent:mime-version:content-transfer-encoding; bh=zZT6VREpVNvjqSh4U4xaGhNNxa9B7EbNtNtljdue6CQ=; b=AqX5xn+r54TEs5XYPF5E9LvrO9JYPx6Q20UkFcoK9lA90ur7i9XlANAYRoqgaBlRMJ Mcd/5XyfDXCAOVPqxVhVK7WXyVFdkXKsLBEFWPv0UEEIFKzTm8idafTA6UrlKg5/+E8O ASyxsHMiRxf3/RqhFcJcycN+SWn+q/MSuoz8u71ibZslUNEYRhyylBDv71M2OGKk8rfI vijW7jNZFuwaSl7PbKbsKDzsi0VTbE0Xaln+Aaj2rGNQofrrqnUF1cS6hB8knTj+oWrP /lIV2ICh6tJKVtPR0f10bfOpzoFuv/XB83XRXqdYABtArOZzxCB9xprVlF9Lsl45ggJ5 RZ5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=zZT6VREpVNvjqSh4U4xaGhNNxa9B7EbNtNtljdue6CQ=; b=ZAjpYuq0cTg9w7KYba+N1EDRAHDvAZRgaJNWl3CE9n8nMF1R95nc648LySM0E+6q3c sbmHrUZTJgoHS/2wiFQgkZAGxZyCqkTkijjVEc9mSJ1SiHT63y8xRvV3CtNsFFxUA4mU T6RsThUh0rb7AbO0J7XSzj6ywoBTFXw+JI8KO8AOEZSJbmrdjvxLKCd6V7LNw2iZESLf M7pnLt+uO8QGTNDIiv3XE7c5y/kAkCdMlTRMqpYDGvZ+xIBYpwI4PaSZfGRpx0gUyUtw nfCqMiMzqfILP9h807zzGJSNNKGI++YPT+lJBeAlyQZPaNJIZjkY595MqRmFUEfttx2E S3HA== X-Gm-Message-State: APjAAAXTLJFc3jXtdyUd+WX/KVJ1yy5i5rAjm9k2YaqanO9GipoJ8aY4 ggQS33KSTMLhzm82OGyvlHo= X-Google-Smtp-Source: APXvYqwsHbGI/lhdKs+zU1b//6y6G9zApL7CHm547EPvJoPuBk75fBXLN4mxZN4l/r00oeAZtDjyGg== X-Received: by 2002:a81:3152:: with SMTP id x79mr52168440ywx.463.1556676410837; Tue, 30 Apr 2019 19:06:50 -0700 (PDT) Received: from [127.0.1.1] (adsl-173-228-226-134.prtc.net. [173.228.226.134]) by smtp.gmail.com with ESMTPSA id i13sm5368152ywl.22.2019.04.30.19.06.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 30 Apr 2019 19:06:50 -0700 (PDT) Subject: [bpf-next PATCH v3 1/4] bpf: tls, implement unhash to avoid transition out of ESTABLISHED From: John Fastabend To: jakub.kicinski@netronome.com, ast@kernel.org, daniel@iogearbox.net Cc: netdev@vger.kernel.org, bpf@vger.kernel.org, john.fastabend@gmail.com Date: Tue, 30 Apr 2019 19:06:49 -0700 Message-ID: <155667640930.4128.2206402218329524687.stgit@john-XPS-13-9360> In-Reply-To: <155667629056.4128.14102391877350907561.stgit@john-XPS-13-9360> References: <155667629056.4128.14102391877350907561.stgit@john-XPS-13-9360> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Sender: bpf-owner@vger.kernel.org Precedence: bulk List-Id: netdev.vger.kernel.org It is possible (via shutdown()) for TCP socks to go through TCP_CLOSE state via tcp_disconnect() without calling into close callback. This would allow a kTLS enabled socket to exist outside of ESTABLISHED state which is not supported. Solve this the same way we solved the sock{map|hash} case by adding an unhash hook to remove tear down the TLS state. In the process we also make the close hook more robust. We add a put call into the close path, also in the unhash path, to remove the reference to ulp data after free. Its no longer valid and may confuse things later if the socket (re)enters kTLS code paths. Second we add an 'if(ctx)' check to ensure the ctx is still valid and not released from a previous unhash/close path. Fixes: d91c3e17f75f2 ("net/tls: Only attach to sockets in ESTABLISHED state") Reported-by: Eric Dumazet Signed-off-by: John Fastabend --- include/net/tls.h | 24 ++++++++++++--- net/tls/tls_device.c | 6 ++-- net/tls/tls_main.c | 78 +++++++++++++++++++++++++++++++++----------------- net/tls/tls_sw.c | 51 ++++++++++++++++----------------- 4 files changed, 98 insertions(+), 61 deletions(-) diff --git a/include/net/tls.h b/include/net/tls.h index d9d0ac66f040..0782a92487f1 100644 --- a/include/net/tls.h +++ b/include/net/tls.h @@ -261,11 +261,14 @@ struct tls_context { bool in_tcp_sendpages; bool pending_open_record_frags; - int (*push_pending_record)(struct sock *sk, int flags); + int (*push_pending_record)(struct sock *sk, + struct tls_context *ctx, int flags); void (*sk_write_space)(struct sock *sk); void (*sk_destruct)(struct sock *sk); void (*sk_proto_close)(struct sock *sk, long timeout); + void (*sk_proto_unhash)(struct sock *sk); + struct proto *sk_proto; int (*setsockopt)(struct sock *sk, int level, int optname, char __user *optval, @@ -303,9 +306,10 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size); int tls_sw_sendpage(struct sock *sk, struct page *page, int offset, size_t size, int flags); void tls_sw_close(struct sock *sk, long timeout); -void tls_sw_free_resources_tx(struct sock *sk); -void tls_sw_free_resources_rx(struct sock *sk); -void tls_sw_release_resources_rx(struct sock *sk); +void tls_sw_free_resources_tx(struct sock *sk, + struct tls_context *ctx, bool locked); +void tls_sw_free_resources_rx(struct sock *sk, struct tls_context *ctx); +void tls_sw_release_resources_rx(struct sock *sk, struct tls_context *ctx); int tls_sw_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, int flags, int *addr_len); bool tls_sw_stream_read(const struct sock *sk); @@ -321,7 +325,7 @@ void tls_device_sk_destruct(struct sock *sk); void tls_device_free_resources_tx(struct sock *sk); void tls_device_init(void); void tls_device_cleanup(void); -int tls_tx_records(struct sock *sk, int flags); +int tls_tx_records(struct sock *sk, struct tls_context *ctx, int flags); struct tls_record_info *tls_get_record(struct tls_offload_context_tx *context, u32 seq, u64 *p_record_sn); @@ -504,6 +508,16 @@ static inline void xor_iv_with_seq(int version, char *iv, char *seq) } } +static inline void tls_put_ctx(struct sock *sk) +{ + struct inet_connection_sock *icsk = inet_csk(sk); + struct tls_context *ctx = icsk->icsk_ulp_data; + + if (!ctx) + return; + sk->sk_prot = ctx->sk_proto; + icsk->icsk_ulp_data = NULL; +} static inline struct tls_sw_context_rx *tls_sw_ctx_rx( const struct tls_context *tls_ctx) diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c index 9f3bdbc1e593..702a024c0c7b 100644 --- a/net/tls/tls_device.c +++ b/net/tls/tls_device.c @@ -548,7 +548,7 @@ struct tls_record_info *tls_get_record(struct tls_offload_context_tx *context, } EXPORT_SYMBOL(tls_get_record); -static int tls_device_push_pending_record(struct sock *sk, int flags) +static int tls_device_push_pending_record(struct sock *sk, struct tls_context *ctx, int flags) { struct iov_iter msg_iter; @@ -904,7 +904,7 @@ int tls_set_device_offload_rx(struct sock *sk, struct tls_context *ctx) goto release_netdev; free_sw_resources: - tls_sw_free_resources_rx(sk); + tls_sw_free_resources_rx(sk, ctx); release_ctx: ctx->priv_ctx_rx = NULL; release_netdev: @@ -941,7 +941,7 @@ void tls_device_offload_cleanup_rx(struct sock *sk) up_read(&device_offload_lock); kfree(tls_ctx->rx.rec_seq); kfree(tls_ctx->rx.iv); - tls_sw_release_resources_rx(sk); + tls_sw_release_resources_rx(sk, tls_ctx); } static int tls_device_down(struct net_device *netdev) diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index 7e546b8ec000..de2ec8349361 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c @@ -150,12 +150,10 @@ int tls_push_sg(struct sock *sk, return 0; } -static int tls_handle_open_record(struct sock *sk, int flags) +static int tls_handle_open_record(struct sock *sk, struct tls_context *ctx, int flags) { - struct tls_context *ctx = tls_get_ctx(sk); - if (tls_is_pending_open_record(ctx)) - return ctx->push_pending_record(sk, flags); + return ctx->push_pending_record(sk, ctx, flags); return 0; } @@ -163,6 +161,7 @@ static int tls_handle_open_record(struct sock *sk, int flags) int tls_proccess_cmsg(struct sock *sk, struct msghdr *msg, unsigned char *record_type) { + struct tls_context *ctx; struct cmsghdr *cmsg; int rc = -EINVAL; @@ -180,7 +179,8 @@ int tls_proccess_cmsg(struct sock *sk, struct msghdr *msg, if (msg->msg_flags & MSG_MORE) return -EINVAL; - rc = tls_handle_open_record(sk, msg->msg_flags); + ctx = tls_get_ctx(sk); + rc = tls_handle_open_record(sk, ctx, msg->msg_flags); if (rc) return rc; @@ -261,32 +261,28 @@ static void tls_ctx_free(struct tls_context *ctx) kfree(ctx); } -static void tls_sk_proto_close(struct sock *sk, long timeout) +static bool tls_sk_proto_destroy(struct sock *sk, + struct tls_context *ctx, bool locked) { - struct tls_context *ctx = tls_get_ctx(sk); long timeo = sock_sndtimeo(sk, 0); - void (*sk_proto_close)(struct sock *sk, long timeout); - bool free_ctx = false; - - lock_sock(sk); - sk_proto_close = ctx->sk_proto_close; if (ctx->tx_conf == TLS_HW_RECORD && ctx->rx_conf == TLS_HW_RECORD) - goto skip_tx_cleanup; + return false; - if (ctx->tx_conf == TLS_BASE && ctx->rx_conf == TLS_BASE) { - free_ctx = true; - goto skip_tx_cleanup; - } + if (ctx->tx_conf != TLS_HW && ctx->rx_conf != TLS_HW) + tls_put_ctx(sk); + + if (ctx->tx_conf == TLS_BASE && ctx->rx_conf == TLS_BASE) + return true; if (!tls_complete_pending_work(sk, ctx, 0, &timeo)) - tls_handle_open_record(sk, 0); + tls_handle_open_record(sk, ctx, 0); /* We need these for tls_sw_fallback handling of other packets */ if (ctx->tx_conf == TLS_SW) { kfree(ctx->tx.rec_seq); kfree(ctx->tx.iv); - tls_sw_free_resources_tx(sk); + tls_sw_free_resources_tx(sk, ctx, locked); #ifdef CONFIG_TLS_DEVICE } else if (ctx->tx_conf == TLS_HW) { tls_device_free_resources_tx(sk); @@ -296,22 +292,47 @@ static void tls_sk_proto_close(struct sock *sk, long timeout) if (ctx->rx_conf == TLS_SW) { kfree(ctx->rx.rec_seq); kfree(ctx->rx.iv); - tls_sw_free_resources_rx(sk); + tls_sw_free_resources_rx(sk, ctx); } #ifdef CONFIG_TLS_DEVICE if (ctx->rx_conf == TLS_HW) tls_device_offload_cleanup_rx(sk); - - if (ctx->tx_conf != TLS_HW && ctx->rx_conf != TLS_HW) { -#else - { #endif + + if (ctx->tx_conf != TLS_HW && ctx->rx_conf != TLS_HW) + return true; + return false; +} + +static void tls_sk_proto_unhash(struct sock *sk) +{ + struct tls_context *ctx = tls_get_ctx(sk); + void (*sk_proto_unhash)(struct sock *sk); + bool free_ctx; + + if (!ctx) + return sk->sk_prot->unhash(sk); + sk_proto_unhash = ctx->sk_proto_unhash; + free_ctx = tls_sk_proto_destroy(sk, ctx, false); + if (sk_proto_unhash) + sk_proto_unhash(sk); + if (free_ctx) tls_ctx_free(ctx); - ctx = NULL; - } +} + +static void tls_sk_proto_close(struct sock *sk, long timeout) +{ + void (*sk_proto_close)(struct sock *sk, long timeout); + struct tls_context *ctx = tls_get_ctx(sk); + bool free_ctx; -skip_tx_cleanup: + if (!ctx) + return sk->sk_prot->destroy(sk); + + lock_sock(sk); + sk_proto_close = ctx->sk_proto_close; + free_ctx = tls_sk_proto_destroy(sk, ctx, true); release_sock(sk); sk_proto_close(sk, timeout); /* free ctx for TLS_HW_RECORD, used by tcp_set_state @@ -609,6 +630,8 @@ static struct tls_context *create_ctx(struct sock *sk) ctx->setsockopt = sk->sk_prot->setsockopt; ctx->getsockopt = sk->sk_prot->getsockopt; ctx->sk_proto_close = sk->sk_prot->close; + ctx->sk_proto_unhash = sk->sk_prot->unhash; + ctx->sk_proto = sk->sk_prot; return ctx; } @@ -732,6 +755,7 @@ static void build_protos(struct proto prot[TLS_NUM_CONFIG][TLS_NUM_CONFIG], prot[TLS_BASE][TLS_BASE].setsockopt = tls_setsockopt; prot[TLS_BASE][TLS_BASE].getsockopt = tls_getsockopt; prot[TLS_BASE][TLS_BASE].close = tls_sk_proto_close; + prot[TLS_BASE][TLS_BASE].unhash = tls_sk_proto_unhash; prot[TLS_SW][TLS_BASE] = prot[TLS_BASE][TLS_BASE]; prot[TLS_SW][TLS_BASE].sendmsg = tls_sw_sendmsg; diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index f780b473827b..f145ab879552 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -337,9 +337,8 @@ static void tls_free_rec(struct sock *sk, struct tls_rec *rec) kfree(rec); } -static void tls_free_open_rec(struct sock *sk) +static void tls_free_open_rec(struct sock *sk, struct tls_context *tls_ctx) { - struct tls_context *tls_ctx = tls_get_ctx(sk); struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx); struct tls_rec *rec = ctx->open_rec; @@ -349,9 +348,8 @@ static void tls_free_open_rec(struct sock *sk) } } -int tls_tx_records(struct sock *sk, int flags) +int tls_tx_records(struct sock *sk, struct tls_context *tls_ctx, int flags) { - struct tls_context *tls_ctx = tls_get_ctx(sk); struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx); struct tls_rec *rec, *tmp; struct sk_msg *msg_en; @@ -737,7 +735,7 @@ static int tls_push_record(struct sock *sk, int flags, ctx->open_rec = tmp; } - return tls_tx_records(sk, flags); + return tls_tx_records(sk, tls_ctx, flags); } static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk, @@ -783,7 +781,7 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk, err = tls_push_record(sk, flags, record_type); if (err < 0) { *copied -= sk_msg_free(sk, msg); - tls_free_open_rec(sk); + tls_free_open_rec(sk, tls_ctx); goto out_err; } break; @@ -804,7 +802,7 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk, msg->sg.size = 0; } if (msg->sg.size == 0) - tls_free_open_rec(sk); + tls_free_open_rec(sk, tls_ctx); break; case __SK_DROP: default: @@ -814,7 +812,7 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk, else msg->apply_bytes -= send; if (msg->sg.size == 0) - tls_free_open_rec(sk); + tls_free_open_rec(sk, tls_ctx); *copied -= (send + delta); err = -EACCES; } @@ -843,9 +841,9 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk, return err; } -static int tls_sw_push_pending_record(struct sock *sk, int flags) +static int tls_sw_push_pending_record(struct sock *sk, + struct tls_context *tls_ctx, int flags) { - struct tls_context *tls_ctx = tls_get_ctx(sk); struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx); struct tls_rec *rec = ctx->open_rec; struct sk_msg *msg_pl; @@ -1074,7 +1072,7 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) /* Transmit if any encryptions have completed */ if (test_and_clear_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask)) { cancel_delayed_work(&ctx->tx_work.work); - tls_tx_records(sk, msg->msg_flags); + tls_tx_records(sk, tls_ctx, msg->msg_flags); } send_end: @@ -1199,7 +1197,7 @@ static int tls_sw_do_sendpage(struct sock *sk, struct page *page, /* Transmit if any encryptions have completed */ if (test_and_clear_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask)) { cancel_delayed_work(&ctx->tx_work.work); - tls_tx_records(sk, flags); + tls_tx_records(sk, tls_ctx, flags); } } sendpage_end: @@ -2044,9 +2042,8 @@ static void tls_data_ready(struct sock *sk) } } -void tls_sw_free_resources_tx(struct sock *sk) +void tls_sw_free_resources_tx(struct sock *sk, struct tls_context *tls_ctx, bool locked) { - struct tls_context *tls_ctx = tls_get_ctx(sk); struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx); struct tls_rec *rec, *tmp; @@ -2055,12 +2052,14 @@ void tls_sw_free_resources_tx(struct sock *sk) if (atomic_read(&ctx->encrypt_pending)) crypto_wait_req(-EINPROGRESS, &ctx->async_wait); - release_sock(sk); + if (locked) + release_sock(sk); cancel_delayed_work_sync(&ctx->tx_work.work); - lock_sock(sk); + if (locked) + lock_sock(sk); /* Tx whatever records we can transmit and abandon the rest */ - tls_tx_records(sk, -1); + tls_tx_records(sk, tls_ctx, -1); /* Free up un-sent records in tx_list. First, free * the partially sent record if any at head of tx_list. @@ -2080,15 +2079,17 @@ void tls_sw_free_resources_tx(struct sock *sk) kfree(rec); } - crypto_free_aead(ctx->aead_send); - tls_free_open_rec(sk); + if (ctx->aead_send) { + crypto_free_aead(ctx->aead_send); + ctx->aead_send = NULL; + } + tls_free_open_rec(sk, tls_ctx); kfree(ctx); } -void tls_sw_release_resources_rx(struct sock *sk) +void tls_sw_release_resources_rx(struct sock *sk, struct tls_context *tls_ctx) { - struct tls_context *tls_ctx = tls_get_ctx(sk); struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx); if (ctx->aead_recv) { @@ -2106,13 +2107,11 @@ void tls_sw_release_resources_rx(struct sock *sk) } } -void tls_sw_free_resources_rx(struct sock *sk) +void tls_sw_free_resources_rx(struct sock *sk, struct tls_context *tls_ctx) { - struct tls_context *tls_ctx = tls_get_ctx(sk); struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx); - tls_sw_release_resources_rx(sk); - + tls_sw_release_resources_rx(sk, tls_ctx); kfree(ctx); } @@ -2130,7 +2129,7 @@ static void tx_work_handler(struct work_struct *work) return; lock_sock(sk); - tls_tx_records(sk, -1); + tls_tx_records(sk, tls_ctx, -1); release_sock(sk); } From patchwork Wed May 1 02:06:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Fastabend X-Patchwork-Id: 1093537 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Tj6RiLbI"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44v1wy4sLWz9s9N for ; Wed, 1 May 2019 12:06:58 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727083AbfEACG6 (ORCPT ); Tue, 30 Apr 2019 22:06:58 -0400 Received: from mail-yw1-f68.google.com ([209.85.161.68]:46093 "EHLO mail-yw1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726328AbfEACG6 (ORCPT ); Tue, 30 Apr 2019 22:06:58 -0400 Received: by mail-yw1-f68.google.com with SMTP id v15so7414457ywe.13; Tue, 30 Apr 2019 19:06:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:from:to:cc:date:message-id:in-reply-to:references :user-agent:mime-version:content-transfer-encoding; bh=mP8S+aTEH0TfrmSoHVNIm1wecVOgLyl9+6N0y5RZVwA=; b=Tj6RiLbI8BFpKjLDqseZeMe2CLCAmWn4FY0XFyw7vEVAKjrgZLbe5CCXk0WWN/x0n7 5tbwgUp69Qq8ZeJwuxGbYv8gmiYqUUBA3Nu3VoufmbJvm/12MaxMwOnLom1IdjrerTkc hmtFbbEzhey2TfQIcd/XDIfyF9GqyIs2n/bXpYXxNs9yRGmeA8+2wdfnvQnOAxvwp4pT GyUv5mMKl39lXwbCHNuGQDVgq84OooHL9c6H0Vvw9xDCSysCDgbLY6OboYzQ46NTxw6D MRr+6fex0H/T7x4t43uxLcloDrqGxWu+Mtk/UojR2RyjeX9VwXPJhqOnzfWl5JBHc+nT vFHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=mP8S+aTEH0TfrmSoHVNIm1wecVOgLyl9+6N0y5RZVwA=; b=Z9o0ZwwIKXel/0O8v/pVNUDp0ZdLLctpZE7zRsIqIq8IfCSNFJBK9D1sJWNld5JErX no2zcNevW0gsz4PAIQdw1ofviiubY+r1SMq395zzLlJUf0MY1Z7j7Mkme7KLe6BcCyWq maLF8IsiokcjolS+z4Je9aD26o/qUu23lUMGa67em2IupAUlOi/p8vcitIrk9oIP137D vT0hBrnR73Sy7lIvrr2QUiGtr5LwS2dEz3t+9CWVkE+RvQ1RhM22863RxwCzCep5Vr2H JhL4YcL4LasTBYJFBDqHM3Q+IMCD8VoXii284wRQv/45td5u9n1+Lpf+P1NClNZ/UT2W V/mw== X-Gm-Message-State: APjAAAXJ93bhPzg+AMeDQMxtqzu9s4I/a1v72hcBAYD2Z1vVZUAXxkDd C9sjfB/KyhwDYBOFTriTEBE= X-Google-Smtp-Source: APXvYqx0OW9JWz5RcPk1ZiCm3VngQcRvJtWRAEuXC5YuHEy6ZOPRqGWp7jd/YKXxAI5CP0Nj0phufw== X-Received: by 2002:a81:5501:: with SMTP id j1mr50822573ywb.341.1556676417476; Tue, 30 Apr 2019 19:06:57 -0700 (PDT) Received: from [127.0.1.1] (adsl-173-228-226-134.prtc.net. [173.228.226.134]) by smtp.gmail.com with ESMTPSA id b69sm6002479ywh.18.2019.04.30.19.06.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 30 Apr 2019 19:06:56 -0700 (PDT) Subject: [bpf-next PATCH v3 2/4] bpf: sockmap remove duplicate queue free From: John Fastabend To: jakub.kicinski@netronome.com, ast@kernel.org, daniel@iogearbox.net Cc: netdev@vger.kernel.org, bpf@vger.kernel.org, john.fastabend@gmail.com Date: Tue, 30 Apr 2019 19:06:55 -0700 Message-ID: <155667641591.4128.16138679120246402872.stgit@john-XPS-13-9360> In-Reply-To: <155667629056.4128.14102391877350907561.stgit@john-XPS-13-9360> References: <155667629056.4128.14102391877350907561.stgit@john-XPS-13-9360> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Sender: bpf-owner@vger.kernel.org Precedence: bulk List-Id: netdev.vger.kernel.org In tcp bpf remove we free the cork list and purge the ingress msg list. However we do this before the ref count reaches zero so it could be possible some other access is in progress. In this case (tcp close and/or tcp_unhash) we happen to also hold the sock lock so no path exists but lets fix it otherwise it is extremely fragile and breaks the reference counting rules. Also we already check the cork list and ingress msg queue and free them once the ref count reaches zero so its wasteful to check twice. Fixes: 604326b41a6fb ("bpf, sockmap: convert to generic sk_msg interface") Signed-off-by: John Fastabend --- net/ipv4/tcp_bpf.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c index 1bb7321a256d..4a619c85daed 100644 --- a/net/ipv4/tcp_bpf.c +++ b/net/ipv4/tcp_bpf.c @@ -528,8 +528,6 @@ static void tcp_bpf_remove(struct sock *sk, struct sk_psock *psock) { struct sk_psock_link *link; - sk_psock_cork_free(psock); - __sk_psock_purge_ingress_msg(psock); while ((link = sk_psock_link_pop(psock))) { sk_psock_unlink(sk, link); sk_psock_free_link(link); From patchwork Wed May 1 02:07:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Fastabend X-Patchwork-Id: 1093539 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="uyUGqJvl"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44v1x53km4z9s9N for ; Wed, 1 May 2019 12:07:05 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727259AbfEACHF (ORCPT ); Tue, 30 Apr 2019 22:07:05 -0400 Received: from mail-yw1-f65.google.com ([209.85.161.65]:45137 "EHLO mail-yw1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726328AbfEACHE (ORCPT ); Tue, 30 Apr 2019 22:07:04 -0400 Received: by mail-yw1-f65.google.com with SMTP id r139so7422358ywe.12; Tue, 30 Apr 2019 19:07:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:from:to:cc:date:message-id:in-reply-to:references :user-agent:mime-version:content-transfer-encoding; bh=WzJyuh/ma1ajUJQPClMwlhf7p+o4ybJ/vyppnP30TzU=; b=uyUGqJvl88AlZC4coc/riLd1un44MdCbMnqcllQHNGNh65dB33xWb//pbyL+Q81Kp9 waApGve6mi6KMspg6Tj206aMNpPlrTYNcwVoijNpQ4F2BC/+4ETlTVp37biLn+ii/4c+ R0h6JrSlCOOOVoA7Jm7aD3qQaZbQ3lw4P/sSrvtyqUbdFRUye/m6sGCi8PrXKq01C/s9 MUuGnPRMrPpFcwwXWRPe3Esmy8yKRcRnbvBhG00vTR3EcDvDcmwWUqQDSjaBqHxcNaAr 5Wp2xJd8f3Z8ukmwfVizWITH0Ffcs0sxbpAdyHL11Q/HhSMjaAp1lbOIDaMNuPI2OY30 wJGA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=WzJyuh/ma1ajUJQPClMwlhf7p+o4ybJ/vyppnP30TzU=; b=PKplfMHuKaWjJ7f2/dt7DvBbWdvz50nTruDyPzhlEP9oecxmKWPMPTIT8YHioBtwp7 nfq5fWFkn+4g5OJzlipPzuHIINI36V/oWzdv/W4Ov9TO0iZBhj9CMh6QHykZlARgCJRr 2AXwSFbrNaiQBMl9q9m+NbI3pFWx+0iOfD7dW2aeXTGKVV/x/aOCiN2sJgrbBsqF1rin IlkzFdIuL+8NDuz//JU6wHRS5oHVCYW8x6MUEOXgfF+tPJimd6ezYLCbDzxXMsXvJzid kleY1TKiTdccPtzWzUWOKnLi4RMnlv8nia4FdqcHNXGPqT/em8R2OTDBctePWZdfYO/d 8XNA== X-Gm-Message-State: APjAAAW7koqTKuphHO+37qF12P6AxbkZrwU6N/I2nsQSQ/fBRXkIp5RJ VwWVQqxl+pDdyP1Fr42HhNA= X-Google-Smtp-Source: APXvYqweT3Q3lfynNjFjuu/PrU/uwtmf0nVPfMs7UjlQoSpAOx40GuNdihGpKGIvSStTZA8cUA/w7A== X-Received: by 2002:a25:3143:: with SMTP id x64mr9416168ybx.333.1556676424017; Tue, 30 Apr 2019 19:07:04 -0700 (PDT) Received: from [127.0.1.1] (adsl-173-228-226-134.prtc.net. [173.228.226.134]) by smtp.gmail.com with ESMTPSA id e64sm7217893ywf.63.2019.04.30.19.07.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 30 Apr 2019 19:07:03 -0700 (PDT) Subject: [bpf-next PATCH v3 3/4] bpf: sockmap fix msg->sg.size account on ingress skb From: John Fastabend To: jakub.kicinski@netronome.com, ast@kernel.org, daniel@iogearbox.net Cc: netdev@vger.kernel.org, bpf@vger.kernel.org, john.fastabend@gmail.com Date: Tue, 30 Apr 2019 19:07:02 -0700 Message-ID: <155667642255.4128.6629806323338519870.stgit@john-XPS-13-9360> In-Reply-To: <155667629056.4128.14102391877350907561.stgit@john-XPS-13-9360> References: <155667629056.4128.14102391877350907561.stgit@john-XPS-13-9360> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Sender: bpf-owner@vger.kernel.org Precedence: bulk List-Id: netdev.vger.kernel.org When converting a skb to msg->sg we forget to set the size after the latest ktls/tls code conversion. This patch can be reached by doing a redir into ingress path from BPF skb sock recv hook. Then trying to read the size fails. Fix this by setting the size. Fixes: 604326b41a6fb ("bpf, sockmap: convert to generic sk_msg interface") Signed-off-by: John Fastabend --- net/core/skmsg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/core/skmsg.c b/net/core/skmsg.c index cc94d921476c..782ae9eb4dce 100644 --- a/net/core/skmsg.c +++ b/net/core/skmsg.c @@ -411,6 +411,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb) sk_mem_charge(sk, skb->len); copied = skb->len; msg->sg.start = 0; + msg->sg.size = copied; msg->sg.end = num_sge == MAX_MSG_FRAGS ? 0 : num_sge; msg->skb = skb; From patchwork Wed May 1 02:07:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Fastabend X-Patchwork-Id: 1093541 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="JyWt5s8+"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44v1xD0H75z9s9N for ; Wed, 1 May 2019 12:07:12 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727083AbfEACHL (ORCPT ); Tue, 30 Apr 2019 22:07:11 -0400 Received: from mail-yw1-f67.google.com ([209.85.161.67]:46116 "EHLO mail-yw1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726328AbfEACHL (ORCPT ); Tue, 30 Apr 2019 22:07:11 -0400 Received: by mail-yw1-f67.google.com with SMTP id v15so7414746ywe.13; Tue, 30 Apr 2019 19:07:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:from:to:cc:date:message-id:in-reply-to:references :user-agent:mime-version:content-transfer-encoding; bh=wtoRhHiznELdjroOY8oXrivbtQDn8tLQ5eVLJAIsb9Q=; b=JyWt5s8+8x/5jv0/eY2R8fO6DHaXQnVbBYq90l1ySXf7ksVuwobZxv7k8okoSBgSww UOWnZMB5Q3OGTJRQLMviirexRFjxf6ft90NrSJ478WQzlQGeU5842v6LXQVX9ez8gx+Z RAv7EOPOjqG/fgoooSyvg28dVIHVfS/ISps/JUPfq1TpPTDuB9nXNufFaraqTpLlwiY+ TpEgCgBZxVOmjT2LGfq2n5CGxnoNUcJQQ2i6SmP1y0ZmPcjiJkxMETXsmruxqYJfgCGc iIG+YRvN4sr2CIMizvrMENNGBBhKRTC9uYQY6xvIHtcmOxMsXGMiGmEJu0mVgqac2We9 ptAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=wtoRhHiznELdjroOY8oXrivbtQDn8tLQ5eVLJAIsb9Q=; b=LOJBqouRKijsBwhm/EkubQA5EltYlP/GoK07Gdt7DurMz0rLPo+f3nh3ByR79Lm5GB L1tWEkQKpNtmiIO0Os+t+qg8x0hRosQ528f1FG98ednOKmo8iluwe7OEcbmlNpDKrRyC lp9IJHVxhU8ZXTUF17gK0hR0efBBd7+qAPLFXyhETso+U/keikOJ4bD8gSVzDnP2Oc/m qGOhov1k6LutbtSNwm2NSvKKXIcYujrrXZQ/qKA/myFITrgt/fGnztRWUTfEpM2WHajb 1jlSC1rd1OIizX4XDD/36y7tJxs00L6nDeOTabBw/RHbCbkaNkhzm+81paj6SFcs3I3k 9OXw== X-Gm-Message-State: APjAAAXvRSGLcMntf4IsoezD/YciXdHg+MmjkKKjcCeaDwt9h9fIWyk1 J4vXPz8z3l6FyLG2jQ8YIrY= X-Google-Smtp-Source: APXvYqxFY1ZoAtvd7wYGTf5KRjqi+p6v37oQZuAFfqNGIsry9tia0NQdd8fEx5ipp2SEMbx0AuKOIA== X-Received: by 2002:a81:730b:: with SMTP id o11mr58941667ywc.365.1556676430584; Tue, 30 Apr 2019 19:07:10 -0700 (PDT) Received: from [127.0.1.1] (adsl-173-228-226-134.prtc.net. [173.228.226.134]) by smtp.gmail.com with ESMTPSA id j84sm1027918ywa.104.2019.04.30.19.07.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 30 Apr 2019 19:07:09 -0700 (PDT) Subject: [bpf-next PATCH v3 4/4] bpf: sockmap, only stop/flush strp if it was enabled at some point From: John Fastabend To: jakub.kicinski@netronome.com, ast@kernel.org, daniel@iogearbox.net Cc: netdev@vger.kernel.org, bpf@vger.kernel.org, john.fastabend@gmail.com Date: Tue, 30 Apr 2019 19:07:09 -0700 Message-ID: <155667642909.4128.5577550149379609590.stgit@john-XPS-13-9360> In-Reply-To: <155667629056.4128.14102391877350907561.stgit@john-XPS-13-9360> References: <155667629056.4128.14102391877350907561.stgit@john-XPS-13-9360> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Sender: bpf-owner@vger.kernel.org Precedence: bulk List-Id: netdev.vger.kernel.org If we try to call strp_done on a parser that has never been initialized, because the sockmap user is only using TX side for example we get the following error. [ 883.422081] WARNING: CPU: 1 PID: 208 at kernel/workqueue.c:3030 __flush_work+0x1ca/0x1e0 ... [ 883.422095] Workqueue: events sk_psock_destroy_deferred [ 883.422097] RIP: 0010:__flush_work+0x1ca/0x1e0 This had been wrapped in a 'if (psock->parser.enabled)' logic which was broken because the strp_done() was never actually being called because we do a strp_stop() earlier in the tear down logic will set parser.enabled to false. This could result in a use after free if work was still in the queue and was resolved by the patch here, 1d79895aef18f ("sk_msg: Always cancel strp work before freeing the psock"). However, calling strp_stop(), done by the patch marked in the fixes tag, only is useful if we never initialized a strp parser program and never initialized the strp to start with. Because if we had initialized a stream parser strp_stop() would have been called by sk_psock_drop() earlier in the tear down process. By forcing the strp to stop we get past the WARNING in strp_done that checks the stopped flag but calling cancel_work_sync on work that has never been initialized is also wrong and generates the warning above. To fix check if the parser program exists. If the program exists then the strp work has been initialized and must be sync'd and cancelled before free'ing any structures. If no program exists we never initialized the stream parser in the first place so skip the sync/cancel logic implemented by strp_done. Finally, remove the strp_done its not needed and in the case where we are using the stream parser has already been called. Fixes: e8e3437762ad9 ("bpf: Stop the psock parser before canceling its work") Signed-off-by: John Fastabend --- net/core/skmsg.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/core/skmsg.c b/net/core/skmsg.c index 782ae9eb4dce..93bffaad2135 100644 --- a/net/core/skmsg.c +++ b/net/core/skmsg.c @@ -555,8 +555,10 @@ static void sk_psock_destroy_deferred(struct work_struct *gc) struct sk_psock *psock = container_of(gc, struct sk_psock, gc); /* No sk_callback_lock since already detached. */ - strp_stop(&psock->parser.strp); - strp_done(&psock->parser.strp); + + /* Parser has been stopped */ + if (psock->progs.skb_parser) + strp_done(&psock->parser.strp); cancel_work_sync(&psock->work);