From e9e2e8f37ff5b9f32bf738d40d3ab54212b36214 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 19 Feb 2024 20:16:16 +0100 Subject: [PATCH] 6.1-stable patches added patches: tls-fix-null-deref-on-tls_sw_splice_eof-with-empty-record.patch tracing-inform-kmemleak-of-saved_cmdlines-allocation.patch xfrm-silence-warnings-triggerable-by-bad-packets.patch xfrm-use-xfrm_state-selector-for-beet-input.patch --- queue-6.1/series | 4 + ...-tls_sw_splice_eof-with-empty-record.patch | 51 ++++++++++ ...memleak-of-saved_cmdlines-allocation.patch | 94 ++++++++++++++++++ ...-warnings-triggerable-by-bad-packets.patch | 97 +++++++++++++++++++ ...e-xfrm_state-selector-for-beet-input.patch | 39 ++++++++ 5 files changed, 285 insertions(+) create mode 100644 queue-6.1/tls-fix-null-deref-on-tls_sw_splice_eof-with-empty-record.patch create mode 100644 queue-6.1/tracing-inform-kmemleak-of-saved_cmdlines-allocation.patch create mode 100644 queue-6.1/xfrm-silence-warnings-triggerable-by-bad-packets.patch create mode 100644 queue-6.1/xfrm-use-xfrm_state-selector-for-beet-input.patch diff --git a/queue-6.1/series b/queue-6.1/series index 68f9ac914e8..af32a8142cb 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -159,3 +159,7 @@ can-j1939-prevent-deadlock-by-changing-j1939_socks_lock-to-rwlock.patch can-j1939-fix-uaf-in-j1939_sk_match_filter-during-setsockopt-so_j1939_filter.patch pmdomain-core-move-the-unused-cleanup-to-a-_sync-initcall.patch fs-proc-do_task_stat-move-thread_group_cputime_adjusted-outside-of-lock_task_sighand.patch +tracing-inform-kmemleak-of-saved_cmdlines-allocation.patch +xfrm-use-xfrm_state-selector-for-beet-input.patch +xfrm-silence-warnings-triggerable-by-bad-packets.patch +tls-fix-null-deref-on-tls_sw_splice_eof-with-empty-record.patch diff --git a/queue-6.1/tls-fix-null-deref-on-tls_sw_splice_eof-with-empty-record.patch b/queue-6.1/tls-fix-null-deref-on-tls_sw_splice_eof-with-empty-record.patch new file mode 100644 index 00000000000..31b685e63f1 --- /dev/null +++ b/queue-6.1/tls-fix-null-deref-on-tls_sw_splice_eof-with-empty-record.patch @@ -0,0 +1,51 @@ +From 53f2cb491b500897a619ff6abd72f565933760f0 Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Wed, 22 Nov 2023 22:44:47 +0100 +Subject: tls: fix NULL deref on tls_sw_splice_eof() with empty record + +From: Jann Horn + +commit 53f2cb491b500897a619ff6abd72f565933760f0 upstream. + +syzkaller discovered that if tls_sw_splice_eof() is executed as part of +sendfile() when the plaintext/ciphertext sk_msg are empty, the send path +gets confused because the empty ciphertext buffer does not have enough +space for the encryption overhead. This causes tls_push_record() to go on +the `split = true` path (which is only supposed to be used when interacting +with an attached BPF program), and then get further confused and hit the +tls_merge_open_record() path, which then assumes that there must be at +least one populated buffer element, leading to a NULL deref. + +It is possible to have empty plaintext/ciphertext buffers if we previously +bailed from tls_sw_sendmsg_locked() via the tls_trim_both_msgs() path. +tls_sw_push_pending_record() already handles this case correctly; let's do +the same check in tls_sw_splice_eof(). + +Fixes: df720d288dbb ("tls/sw: Use splice_eof() to flush") +Cc: stable@vger.kernel.org +Reported-by: syzbot+40d43509a099ea756317@syzkaller.appspotmail.com +Signed-off-by: Jann Horn +Link: https://lore.kernel.org/r/20231122214447.675768-1-jannh@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/tls/tls_sw.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -1179,11 +1179,14 @@ void tls_sw_splice_eof(struct socket *so + lock_sock(sk); + + retry: ++ /* same checks as in tls_sw_push_pending_record() */ + rec = ctx->open_rec; + if (!rec) + goto unlock; + + msg_pl = &rec->msg_plaintext; ++ if (msg_pl->sg.size == 0) ++ goto unlock; + + /* Check the BPF advisor and perform transmission. */ + ret = bpf_exec_tx_verdict(msg_pl, sk, false, TLS_RECORD_TYPE_DATA, diff --git a/queue-6.1/tracing-inform-kmemleak-of-saved_cmdlines-allocation.patch b/queue-6.1/tracing-inform-kmemleak-of-saved_cmdlines-allocation.patch new file mode 100644 index 00000000000..85c9b27b758 --- /dev/null +++ b/queue-6.1/tracing-inform-kmemleak-of-saved_cmdlines-allocation.patch @@ -0,0 +1,94 @@ +From 2394ac4145ea91b92271e675a09af2a9ea6840b7 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (Google)" +Date: Wed, 14 Feb 2024 11:20:46 -0500 +Subject: tracing: Inform kmemleak of saved_cmdlines allocation + +From: Steven Rostedt (Google) + +commit 2394ac4145ea91b92271e675a09af2a9ea6840b7 upstream. + +The allocation of the struct saved_cmdlines_buffer structure changed from: + + s = kmalloc(sizeof(*s), GFP_KERNEL); + s->saved_cmdlines = kmalloc_array(TASK_COMM_LEN, val, GFP_KERNEL); + +to: + + orig_size = sizeof(*s) + val * TASK_COMM_LEN; + order = get_order(orig_size); + size = 1 << (order + PAGE_SHIFT); + page = alloc_pages(GFP_KERNEL, order); + if (!page) + return NULL; + + s = page_address(page); + memset(s, 0, sizeof(*s)); + + s->saved_cmdlines = kmalloc_array(TASK_COMM_LEN, val, GFP_KERNEL); + +Where that s->saved_cmdlines allocation looks to be a dangling allocation +to kmemleak. That's because kmemleak only keeps track of kmalloc() +allocations. For allocations that use page_alloc() directly, the kmemleak +needs to be explicitly informed about it. + +Add kmemleak_alloc() and kmemleak_free() around the page allocation so +that it doesn't give the following false positive: + +unreferenced object 0xffff8881010c8000 (size 32760): + comm "swapper", pid 0, jiffies 4294667296 + hex dump (first 32 bytes): + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ + backtrace (crc ae6ec1b9): + [] kmemleak_alloc+0x45/0x80 + [] __kmalloc_large_node+0x10d/0x190 + [] __kmalloc+0x3b1/0x4c0 + [] allocate_cmdlines_buffer+0x113/0x230 + [] tracer_alloc_buffers.isra.0+0x124/0x460 + [] early_trace_init+0x14/0xa0 + [] start_kernel+0x12e/0x3c0 + [] x86_64_start_reservations+0x18/0x30 + [] x86_64_start_kernel+0x7b/0x80 + [] secondary_startup_64_no_verify+0x15e/0x16b + +Link: https://lore.kernel.org/linux-trace-kernel/87r0hfnr9r.fsf@kernel.org/ +Link: https://lore.kernel.org/linux-trace-kernel/20240214112046.09a322d6@gandalf.local.home + +Cc: Masami Hiramatsu +Cc: Mathieu Desnoyers +Cc: Catalin Marinas +Fixes: 44dc5c41b5b1 ("tracing: Fix wasted memory in saved_cmdlines logic") +Reported-by: Kalle Valo +Tested-by: Kalle Valo +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/trace.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -2268,6 +2269,7 @@ static void free_saved_cmdlines_buffer(s + int order = get_order(sizeof(*s) + s->cmdline_num * TASK_COMM_LEN); + + kfree(s->map_cmdline_to_pid); ++ kmemleak_free(s); + free_pages((unsigned long)s, order); + } + +@@ -2287,6 +2289,7 @@ static struct saved_cmdlines_buffer *all + return NULL; + + s = page_address(page); ++ kmemleak_alloc(s, size, 1, GFP_KERNEL); + memset(s, 0, sizeof(*s)); + + /* Round up to actual allocation */ diff --git a/queue-6.1/xfrm-silence-warnings-triggerable-by-bad-packets.patch b/queue-6.1/xfrm-silence-warnings-triggerable-by-bad-packets.patch new file mode 100644 index 00000000000..1deae67572d --- /dev/null +++ b/queue-6.1/xfrm-silence-warnings-triggerable-by-bad-packets.patch @@ -0,0 +1,97 @@ +From 57010b8ece2821a1fdfdba2197d14a022f3769db Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Tue, 4 Jul 2023 08:53:49 +0800 +Subject: xfrm: Silence warnings triggerable by bad packets +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Herbert Xu + +commit 57010b8ece2821a1fdfdba2197d14a022f3769db upstream. + +After the elimination of inner modes, a couple of warnings that +were previously unreachable can now be triggered by malformed +inbound packets. + +Fix this by: + +1. Moving the setting of skb->protocol into the decap functions. +2. Returning -EINVAL when unexpected protocol is seen. + +Reported-by: Maciej Żenczykowski +Fixes: 5f24f41e8ea6 ("xfrm: Remove inner/outer modes from input path") +Signed-off-by: Herbert Xu +Reviewed-by: Maciej Żenczykowski +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman +--- + net/xfrm/xfrm_input.c | 22 +++++++++------------- + 1 file changed, 9 insertions(+), 13 deletions(-) + +--- a/net/xfrm/xfrm_input.c ++++ b/net/xfrm/xfrm_input.c +@@ -180,6 +180,8 @@ static int xfrm4_remove_beet_encap(struc + int optlen = 0; + int err = -EINVAL; + ++ skb->protocol = htons(ETH_P_IP); ++ + if (unlikely(XFRM_MODE_SKB_CB(skb)->protocol == IPPROTO_BEETPH)) { + struct ip_beet_phdr *ph; + int phlen; +@@ -232,6 +234,8 @@ static int xfrm4_remove_tunnel_encap(str + { + int err = -EINVAL; + ++ skb->protocol = htons(ETH_P_IP); ++ + if (!pskb_may_pull(skb, sizeof(struct iphdr))) + goto out; + +@@ -267,6 +271,8 @@ static int xfrm6_remove_tunnel_encap(str + { + int err = -EINVAL; + ++ skb->protocol = htons(ETH_P_IPV6); ++ + if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) + goto out; + +@@ -296,6 +302,8 @@ static int xfrm6_remove_beet_encap(struc + int size = sizeof(struct ipv6hdr); + int err; + ++ skb->protocol = htons(ETH_P_IPV6); ++ + err = skb_cow_head(skb, size + skb->mac_len); + if (err) + goto out; +@@ -346,6 +354,7 @@ xfrm_inner_mode_encap_remove(struct xfrm + return xfrm6_remove_tunnel_encap(x, skb); + break; + } ++ return -EINVAL; + } + + WARN_ON_ONCE(1); +@@ -366,19 +375,6 @@ static int xfrm_prepare_input(struct xfr + return -EAFNOSUPPORT; + } + +- switch (XFRM_MODE_SKB_CB(skb)->protocol) { +- case IPPROTO_IPIP: +- case IPPROTO_BEETPH: +- skb->protocol = htons(ETH_P_IP); +- break; +- case IPPROTO_IPV6: +- skb->protocol = htons(ETH_P_IPV6); +- break; +- default: +- WARN_ON_ONCE(1); +- break; +- } +- + return xfrm_inner_mode_encap_remove(x, skb); + } + diff --git a/queue-6.1/xfrm-use-xfrm_state-selector-for-beet-input.patch b/queue-6.1/xfrm-use-xfrm_state-selector-for-beet-input.patch new file mode 100644 index 00000000000..918016d4e54 --- /dev/null +++ b/queue-6.1/xfrm-use-xfrm_state-selector-for-beet-input.patch @@ -0,0 +1,39 @@ +From 842665a9008a53ff13ac22a4e4b8ae2f10e92aca Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Wed, 7 Jun 2023 16:38:47 +0800 +Subject: xfrm: Use xfrm_state selector for BEET input + +From: Herbert Xu + +commit 842665a9008a53ff13ac22a4e4b8ae2f10e92aca upstream. + +For BEET the inner address and therefore family is stored in the +xfrm_state selector. Use that when decapsulating an input packet +instead of incorrectly relying on a non-existent tunnel protocol. + +Fixes: 5f24f41e8ea6 ("xfrm: Remove inner/outer modes from input path") +Reported-by: Steffen Klassert +Signed-off-by: Herbert Xu +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman +--- + net/xfrm/xfrm_input.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/net/xfrm/xfrm_input.c ++++ b/net/xfrm/xfrm_input.c +@@ -331,11 +331,10 @@ xfrm_inner_mode_encap_remove(struct xfrm + { + switch (x->props.mode) { + case XFRM_MODE_BEET: +- switch (XFRM_MODE_SKB_CB(skb)->protocol) { +- case IPPROTO_IPIP: +- case IPPROTO_BEETPH: ++ switch (x->sel.family) { ++ case AF_INET: + return xfrm4_remove_beet_encap(x, skb); +- case IPPROTO_IPV6: ++ case AF_INET6: + return xfrm6_remove_beet_encap(x, skb); + } + break; -- 2.47.3