From: Sasha Levin Date: Sun, 12 Nov 2023 02:50:13 +0000 (-0500) Subject: Fixes for 5.15 X-Git-Tag: v4.14.330~60 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=da85f3283de7a0416f969b583f44fd0ac187374b;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.15 Signed-off-by: Sasha Levin --- diff --git a/queue-5.15/blk-core-use-pr_warn_ratelimited-in-bio_check_ro.patch b/queue-5.15/blk-core-use-pr_warn_ratelimited-in-bio_check_ro.patch new file mode 100644 index 00000000000..3913ae2c8be --- /dev/null +++ b/queue-5.15/blk-core-use-pr_warn_ratelimited-in-bio_check_ro.patch @@ -0,0 +1,43 @@ +From 486c697c9a92ae6ebae2fe612504ff4ac65af016 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Nov 2023 19:12:47 +0800 +Subject: blk-core: use pr_warn_ratelimited() in bio_check_ro() + +From: Yu Kuai + +[ Upstream commit 1b0a151c10a6d823f033023b9fdd9af72a89591b ] + +If one of the underlying disks of raid or dm is set to read-only, then +each io will generate new log, which will cause message storm. This +environment is indeed problematic, however we can't make sure our +naive custormer won't do this, hence use pr_warn_ratelimited() to +prevent message storm in this case. + +Signed-off-by: Yu Kuai +Fixes: 57e95e4670d1 ("block: fix and cleanup bio_check_ro") +Signed-off-by: Ye Bin +Link: https://lore.kernel.org/r/20231107111247.2157820-1-yukuai1@huaweicloud.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/blk-core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/block/blk-core.c b/block/blk-core.c +index a3d5306d130d0..3c7d57afa5a3f 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -698,8 +698,8 @@ static inline void bio_check_ro(struct bio *bio) + if (op_is_write(bio_op(bio)) && bdev_read_only(bio->bi_bdev)) { + if (op_is_flush(bio->bi_opf) && !bio_sectors(bio)) + return; +- pr_warn("Trying to write to read-only block-device %pg\n", +- bio->bi_bdev); ++ pr_warn_ratelimited("Trying to write to read-only block-device %pg\n", ++ bio->bi_bdev); + /* Older lvm-tools actually trigger this */ + } + } +-- +2.42.0 + diff --git a/queue-5.15/block-remove-unneeded-return-value-of-bio_check_ro.patch b/queue-5.15/block-remove-unneeded-return-value-of-bio_check_ro.patch new file mode 100644 index 00000000000..128dbe1f490 --- /dev/null +++ b/queue-5.15/block-remove-unneeded-return-value-of-bio_check_ro.patch @@ -0,0 +1,59 @@ +From 3c2af6c3085fb4a9f0efd541790f791c8df02214 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Sep 2022 18:27:54 +0800 +Subject: block: remove unneeded return value of bio_check_ro() + +From: Miaohe Lin + +[ Upstream commit bdb7d420c6f6d2618d4c907cd7742c3195c425e2 ] + +bio_check_ro() always return false now. Remove this unneeded return value +and cleanup the sole caller. No functional change intended. + +Signed-off-by: Miaohe Lin +Link: https://lore.kernel.org/r/20220905102754.1942-1-linmiaohe@huawei.com +Signed-off-by: Jens Axboe +Stable-dep-of: 1b0a151c10a6 ("blk-core: use pr_warn_ratelimited() in bio_check_ro()") +Signed-off-by: Sasha Levin +--- + block/blk-core.c | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +diff --git a/block/blk-core.c b/block/blk-core.c +index fbbd59e6d7e15..a3d5306d130d0 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -693,18 +693,15 @@ static inline bool should_fail_request(struct block_device *part, + + #endif /* CONFIG_FAIL_MAKE_REQUEST */ + +-static inline bool bio_check_ro(struct bio *bio) ++static inline void bio_check_ro(struct bio *bio) + { + if (op_is_write(bio_op(bio)) && bdev_read_only(bio->bi_bdev)) { + if (op_is_flush(bio->bi_opf) && !bio_sectors(bio)) +- return false; ++ return; + pr_warn("Trying to write to read-only block-device %pg\n", + bio->bi_bdev); + /* Older lvm-tools actually trigger this */ +- return false; + } +- +- return false; + } + + static noinline int should_fail_bio(struct bio *bio) +@@ -810,8 +807,7 @@ static noinline_for_stack bool submit_bio_checks(struct bio *bio) + + if (should_fail_bio(bio)) + goto end_io; +- if (unlikely(bio_check_ro(bio))) +- goto end_io; ++ bio_check_ro(bio); + if (!bio_flagged(bio, BIO_REMAPPED)) { + if (unlikely(bio_check_eod(bio))) + goto end_io; +-- +2.42.0 + diff --git a/queue-5.15/bpf-check-map-usercnt-after-timer-timer-is-assigned.patch b/queue-5.15/bpf-check-map-usercnt-after-timer-timer-is-assigned.patch new file mode 100644 index 00000000000..bf98f76906d --- /dev/null +++ b/queue-5.15/bpf-check-map-usercnt-after-timer-timer-is-assigned.patch @@ -0,0 +1,113 @@ +From 59dee9f613a952cd37aba05dbcdfe8074d2cb468 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Oct 2023 14:36:16 +0800 +Subject: bpf: Check map->usercnt after timer->timer is assigned + +From: Hou Tao + +[ Upstream commit fd381ce60a2d79cc967506208085336d3d268ae0 ] + +When there are concurrent uref release and bpf timer init operations, +the following sequence diagram is possible. It will break the guarantee +provided by bpf_timer: bpf_timer will still be alive after userspace +application releases or unpins the map. It also will lead to kmemleak +for old kernel version which doesn't release bpf_timer when map is +released. + +bpf program X: + +bpf_timer_init() + lock timer->lock + read timer->timer as NULL + read map->usercnt != 0 + + process Y: + + close(map_fd) + // put last uref + bpf_map_put_uref() + atomic_dec_and_test(map->usercnt) + array_map_free_timers() + bpf_timer_cancel_and_free() + // just return + read timer->timer is NULL + + t = bpf_map_kmalloc_node() + timer->timer = t + unlock timer->lock + +Fix the problem by checking map->usercnt after timer->timer is assigned, +so when there are concurrent uref release and bpf timer init, either +bpf_timer_cancel_and_free() from uref release reads a no-NULL timer +or the newly-added atomic64_read() returns a zero usercnt. + +Because atomic_dec_and_test(map->usercnt) and READ_ONCE(timer->timer) +in bpf_timer_cancel_and_free() are not protected by a lock, so add +a memory barrier to guarantee the order between map->usercnt and +timer->timer. Also use WRITE_ONCE(timer->timer, x) to match the lockless +read of timer->timer in bpf_timer_cancel_and_free(). + +Reported-by: Hsin-Wei Hung +Closes: https://lore.kernel.org/bpf/CABcoxUaT2k9hWsS1tNgXyoU3E-=PuOgMn737qK984fbFmfYixQ@mail.gmail.com +Fixes: b00628b1c7d5 ("bpf: Introduce bpf timers.") +Signed-off-by: Hou Tao +Link: https://lore.kernel.org/r/20231030063616.1653024-1-houtao@huaweicloud.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/helpers.c | 25 ++++++++++++++++--------- + 1 file changed, 16 insertions(+), 9 deletions(-) + +diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c +index a711ffe238932..11e406ad16ae3 100644 +--- a/kernel/bpf/helpers.c ++++ b/kernel/bpf/helpers.c +@@ -1118,13 +1118,6 @@ BPF_CALL_3(bpf_timer_init, struct bpf_timer_kern *, timer, struct bpf_map *, map + ret = -EBUSY; + goto out; + } +- if (!atomic64_read(&map->usercnt)) { +- /* maps with timers must be either held by user space +- * or pinned in bpffs. +- */ +- ret = -EPERM; +- goto out; +- } + /* allocate hrtimer via map_kmalloc to use memcg accounting */ + t = bpf_map_kmalloc_node(map, sizeof(*t), GFP_ATOMIC, map->numa_node); + if (!t) { +@@ -1137,7 +1130,21 @@ BPF_CALL_3(bpf_timer_init, struct bpf_timer_kern *, timer, struct bpf_map *, map + rcu_assign_pointer(t->callback_fn, NULL); + hrtimer_init(&t->timer, clockid, HRTIMER_MODE_REL_SOFT); + t->timer.function = bpf_timer_cb; +- timer->timer = t; ++ WRITE_ONCE(timer->timer, t); ++ /* Guarantee the order between timer->timer and map->usercnt. So ++ * when there are concurrent uref release and bpf timer init, either ++ * bpf_timer_cancel_and_free() called by uref release reads a no-NULL ++ * timer or atomic64_read() below returns a zero usercnt. ++ */ ++ smp_mb(); ++ if (!atomic64_read(&map->usercnt)) { ++ /* maps with timers must be either held by user space ++ * or pinned in bpffs. ++ */ ++ WRITE_ONCE(timer->timer, NULL); ++ kfree(t); ++ ret = -EPERM; ++ } + out: + __bpf_spin_unlock_irqrestore(&timer->lock); + return ret; +@@ -1305,7 +1312,7 @@ void bpf_timer_cancel_and_free(void *val) + /* The subsequent bpf_timer_start/cancel() helpers won't be able to use + * this timer, since it won't be initialized. + */ +- timer->timer = NULL; ++ WRITE_ONCE(timer->timer, NULL); + out: + __bpf_spin_unlock_irqrestore(&timer->lock); + if (!t) +-- +2.42.0 + diff --git a/queue-5.15/dccp-call-security_inet_conn_request-after-setting-i.patch b/queue-5.15/dccp-call-security_inet_conn_request-after-setting-i.patch new file mode 100644 index 00000000000..0d4ebd5ae64 --- /dev/null +++ b/queue-5.15/dccp-call-security_inet_conn_request-after-setting-i.patch @@ -0,0 +1,59 @@ +From d181d3a51572a350dc7881f4327686851217d89f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Oct 2023 13:10:41 -0700 +Subject: dccp: Call security_inet_conn_request() after setting IPv4 addresses. + +From: Kuniyuki Iwashima + +[ Upstream commit fa2df45af13091f76b89adb84a28f13818d5d631 ] + +Initially, commit 4237c75c0a35 ("[MLSXFRM]: Auto-labeling of child +sockets") introduced security_inet_conn_request() in some functions +where reqsk is allocated. The hook is added just after the allocation, +so reqsk's IPv4 remote address was not initialised then. + +However, SELinux/Smack started to read it in netlbl_req_setattr() +after the cited commits. + +This bug was partially fixed by commit 284904aa7946 ("lsm: Relocate +the IPv4 security_inet_conn_request() hooks"). + +This patch fixes the last bug in DCCPv4. + +Fixes: 389fb800ac8b ("netlabel: Label incoming TCP connections correctly in SELinux") +Fixes: 07feee8f812f ("netlabel: Cleanup the Smack/NetLabel code to fix incoming TCP connections") +Signed-off-by: Kuniyuki Iwashima +Acked-by: Paul Moore +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/dccp/ipv4.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c +index b44e46dc8e040..cab82344de9be 100644 +--- a/net/dccp/ipv4.c ++++ b/net/dccp/ipv4.c +@@ -623,9 +623,6 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) + if (dccp_parse_options(sk, dreq, skb)) + goto drop_and_free; + +- if (security_inet_conn_request(sk, skb, req)) +- goto drop_and_free; +- + ireq = inet_rsk(req); + sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); + sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); +@@ -633,6 +630,9 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) + ireq->ireq_family = AF_INET; + ireq->ir_iif = sk->sk_bound_dev_if; + ++ if (security_inet_conn_request(sk, skb, req)) ++ goto drop_and_free; ++ + /* + * Step 3: Process LISTEN state + * +-- +2.42.0 + diff --git a/queue-5.15/dccp-tcp-call-security_inet_conn_request-after-setti.patch b/queue-5.15/dccp-tcp-call-security_inet_conn_request-after-setti.patch new file mode 100644 index 00000000000..0545d94e1fa --- /dev/null +++ b/queue-5.15/dccp-tcp-call-security_inet_conn_request-after-setti.patch @@ -0,0 +1,85 @@ +From 79548634d38c63044eb3b3439c6ed32dd18f75dd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Oct 2023 13:10:42 -0700 +Subject: dccp/tcp: Call security_inet_conn_request() after setting IPv6 + addresses. + +From: Kuniyuki Iwashima + +[ Upstream commit 23be1e0e2a83a8543214d2599a31d9a2185a796b ] + +Initially, commit 4237c75c0a35 ("[MLSXFRM]: Auto-labeling of child +sockets") introduced security_inet_conn_request() in some functions +where reqsk is allocated. The hook is added just after the allocation, +so reqsk's IPv6 remote address was not initialised then. + +However, SELinux/Smack started to read it in netlbl_req_setattr() +after commit e1adea927080 ("calipso: Allow request sockets to be +relabelled by the lsm."). + +Commit 284904aa7946 ("lsm: Relocate the IPv4 security_inet_conn_request() +hooks") fixed that kind of issue only in TCPv4 because IPv6 labeling was +not supported at that time. Finally, the same issue was introduced again +in IPv6. + +Let's apply the same fix on DCCPv6 and TCPv6. + +Fixes: e1adea927080 ("calipso: Allow request sockets to be relabelled by the lsm.") +Signed-off-by: Kuniyuki Iwashima +Acked-by: Paul Moore +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/dccp/ipv6.c | 6 +++--- + net/ipv6/syncookies.c | 7 ++++--- + 2 files changed, 7 insertions(+), 6 deletions(-) + +diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c +index 0ddf64845a06c..6f05e9d0d4287 100644 +--- a/net/dccp/ipv6.c ++++ b/net/dccp/ipv6.c +@@ -359,15 +359,15 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) + if (dccp_parse_options(sk, dreq, skb)) + goto drop_and_free; + +- if (security_inet_conn_request(sk, skb, req)) +- goto drop_and_free; +- + ireq = inet_rsk(req); + ireq->ir_v6_rmt_addr = ipv6_hdr(skb)->saddr; + ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr; + ireq->ireq_family = AF_INET6; + ireq->ir_mark = inet_request_mark(sk, skb); + ++ if (security_inet_conn_request(sk, skb, req)) ++ goto drop_and_free; ++ + if (ipv6_opt_accepted(sk, skb, IP6CB(skb)) || + np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || + np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) { +diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c +index 12ae817aaf2ec..c10a68bb85de3 100644 +--- a/net/ipv6/syncookies.c ++++ b/net/ipv6/syncookies.c +@@ -180,14 +180,15 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) + treq = tcp_rsk(req); + treq->tfo_listener = false; + +- if (security_inet_conn_request(sk, skb, req)) +- goto out_free; +- + req->mss = mss; + ireq->ir_rmt_port = th->source; + ireq->ir_num = ntohs(th->dest); + ireq->ir_v6_rmt_addr = ipv6_hdr(skb)->saddr; + ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr; ++ ++ if (security_inet_conn_request(sk, skb, req)) ++ goto out_free; ++ + if (ipv6_opt_accepted(sk, skb, &TCP_SKB_CB(skb)->header.h6) || + np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || + np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) { +-- +2.42.0 + diff --git a/queue-5.15/fix-termination-state-for-idr_for_each_entry_ul.patch b/queue-5.15/fix-termination-state-for-idr_for_each_entry_ul.patch new file mode 100644 index 00000000000..38d7c070342 --- /dev/null +++ b/queue-5.15/fix-termination-state-for-idr_for_each_entry_ul.patch @@ -0,0 +1,64 @@ +From b09ec0e2739d37657f4c98b2206f43079bc31ca2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Oct 2023 09:53:33 +1100 +Subject: Fix termination state for idr_for_each_entry_ul() + +From: NeilBrown + +[ Upstream commit e8ae8ad479e2d037daa33756e5e72850a7bd37a9 ] + +The comment for idr_for_each_entry_ul() states + + after normal termination @entry is left with the value NULL + +This is not correct in the case where UINT_MAX has an entry in the idr. +In that case @entry will be non-NULL after termination. +No current code depends on the documentation being correct, but to +save future code we should fix it. + +Also fix idr_for_each_entry_continue_ul(). While this is not documented +as leaving @entry as NULL, the mellanox driver appears to depend on +it doing so. So make that explicit in the documentation as well as in +the code. + +Fixes: e33d2b74d805 ("idr: fix overflow case for idr_for_each_entry_ul()") +Cc: Matthew Wilcox +Cc: Chris Mi +Cc: Cong Wang +Signed-off-by: NeilBrown +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/linux/idr.h | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/include/linux/idr.h b/include/linux/idr.h +index a0dce14090a9e..da5f5fa4a3a6a 100644 +--- a/include/linux/idr.h ++++ b/include/linux/idr.h +@@ -200,7 +200,7 @@ static inline void idr_preload_end(void) + */ + #define idr_for_each_entry_ul(idr, entry, tmp, id) \ + for (tmp = 0, id = 0; \ +- tmp <= id && ((entry) = idr_get_next_ul(idr, &(id))) != NULL; \ ++ ((entry) = tmp <= id ? idr_get_next_ul(idr, &(id)) : NULL) != NULL; \ + tmp = id, ++id) + + /** +@@ -224,10 +224,12 @@ static inline void idr_preload_end(void) + * @id: Entry ID. + * + * Continue to iterate over entries, continuing after the current position. ++ * After normal termination @entry is left with the value NULL. This ++ * is convenient for a "not found" value. + */ + #define idr_for_each_entry_continue_ul(idr, entry, tmp, id) \ + for (tmp = id; \ +- tmp <= id && ((entry) = idr_get_next_ul(idr, &(id))) != NULL; \ ++ ((entry) = tmp <= id ? idr_get_next_ul(idr, &(id)) : NULL) != NULL; \ + tmp = id, ++id) + + /* +-- +2.42.0 + diff --git a/queue-5.15/hsr-prevent-use-after-free-in-prp_create_tagged_fram.patch b/queue-5.15/hsr-prevent-use-after-free-in-prp_create_tagged_fram.patch new file mode 100644 index 00000000000..54cea4cfd2e --- /dev/null +++ b/queue-5.15/hsr-prevent-use-after-free-in-prp_create_tagged_fram.patch @@ -0,0 +1,42 @@ +From 5c2d4bb89b1edb7484217c2e8c34064f8b2008fc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Oct 2023 15:19:01 +0300 +Subject: hsr: Prevent use after free in prp_create_tagged_frame() + +From: Dan Carpenter + +[ Upstream commit 876f8ab52363f649bcc74072157dfd7adfbabc0d ] + +The prp_fill_rct() function can fail. In that situation, it frees the +skb and returns NULL. Meanwhile on the success path, it returns the +original skb. So it's straight forward to fix bug by using the returned +value. + +Fixes: 451d8123f897 ("net: prp: add packet handling support") +Signed-off-by: Dan Carpenter +Acked-by: Paolo Abeni +Link: https://lore.kernel.org/r/57af1f28-7f57-4a96-bcd3-b7a0f2340845@moroto.mountain +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/hsr/hsr_forward.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c +index 12ba43023d30e..e31747d328e70 100644 +--- a/net/hsr/hsr_forward.c ++++ b/net/hsr/hsr_forward.c +@@ -300,9 +300,7 @@ struct sk_buff *prp_create_tagged_frame(struct hsr_frame_info *frame, + skb = skb_copy_expand(frame->skb_std, 0, + skb_tailroom(frame->skb_std) + HSR_HLEN, + GFP_ATOMIC); +- prp_fill_rct(skb, frame, port); +- +- return skb; ++ return prp_fill_rct(skb, frame, port); + } + + static void hsr_deliver_master(struct sk_buff *skb, struct net_device *dev, +-- +2.42.0 + diff --git a/queue-5.15/i2c-iproc-handle-invalid-slave-state.patch b/queue-5.15/i2c-iproc-handle-invalid-slave-state.patch new file mode 100644 index 00000000000..7161402b9b1 --- /dev/null +++ b/queue-5.15/i2c-iproc-handle-invalid-slave-state.patch @@ -0,0 +1,200 @@ +From 518d9d45d669a2f951b769292e2b1f7f4ae846b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Aug 2023 14:23:51 -0700 +Subject: i2c: iproc: handle invalid slave state + +From: Roman Bacik + +[ Upstream commit ba15a14399c262f91ce30c19fcbdc952262dd1be ] + +Add the code to handle an invalid state when both bits S_RX_EVENT +(indicating a transaction) and S_START_BUSY (indicating the end +of transaction - transition of START_BUSY from 1 to 0) are set in +the interrupt status register during a slave read. + +Signed-off-by: Roman Bacik +Fixes: 1ca1b4516088 ("i2c: iproc: handle Master aborted error") +Acked-by: Ray Jui +Signed-off-by: Wolfram Sang +Signed-off-by: Sasha Levin +--- + drivers/i2c/busses/i2c-bcm-iproc.c | 133 ++++++++++++++++------------- + 1 file changed, 75 insertions(+), 58 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-bcm-iproc.c b/drivers/i2c/busses/i2c-bcm-iproc.c +index ec6571b82fff4..299dbcd4c8292 100644 +--- a/drivers/i2c/busses/i2c-bcm-iproc.c ++++ b/drivers/i2c/busses/i2c-bcm-iproc.c +@@ -326,26 +326,44 @@ static void bcm_iproc_i2c_slave_init( + iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, val); + } + +-static void bcm_iproc_i2c_check_slave_status( +- struct bcm_iproc_i2c_dev *iproc_i2c) ++static bool bcm_iproc_i2c_check_slave_status ++ (struct bcm_iproc_i2c_dev *iproc_i2c, u32 status) + { + u32 val; ++ bool recover = false; + +- val = iproc_i2c_rd_reg(iproc_i2c, S_CMD_OFFSET); +- /* status is valid only when START_BUSY is cleared after it was set */ +- if (val & BIT(S_CMD_START_BUSY_SHIFT)) +- return; ++ /* check slave transmit status only if slave is transmitting */ ++ if (!iproc_i2c->slave_rx_only) { ++ val = iproc_i2c_rd_reg(iproc_i2c, S_CMD_OFFSET); ++ /* status is valid only when START_BUSY is cleared */ ++ if (!(val & BIT(S_CMD_START_BUSY_SHIFT))) { ++ val = (val >> S_CMD_STATUS_SHIFT) & S_CMD_STATUS_MASK; ++ if (val == S_CMD_STATUS_TIMEOUT || ++ val == S_CMD_STATUS_MASTER_ABORT) { ++ dev_warn(iproc_i2c->device, ++ (val == S_CMD_STATUS_TIMEOUT) ? ++ "slave random stretch time timeout\n" : ++ "Master aborted read transaction\n"); ++ recover = true; ++ } ++ } ++ } ++ ++ /* RX_EVENT is not valid when START_BUSY is set */ ++ if ((status & BIT(IS_S_RX_EVENT_SHIFT)) && ++ (status & BIT(IS_S_START_BUSY_SHIFT))) { ++ dev_warn(iproc_i2c->device, "Slave aborted read transaction\n"); ++ recover = true; ++ } + +- val = (val >> S_CMD_STATUS_SHIFT) & S_CMD_STATUS_MASK; +- if (val == S_CMD_STATUS_TIMEOUT || val == S_CMD_STATUS_MASTER_ABORT) { +- dev_err(iproc_i2c->device, (val == S_CMD_STATUS_TIMEOUT) ? +- "slave random stretch time timeout\n" : +- "Master aborted read transaction\n"); ++ if (recover) { + /* re-initialize i2c for recovery */ + bcm_iproc_i2c_enable_disable(iproc_i2c, false); + bcm_iproc_i2c_slave_init(iproc_i2c, true); + bcm_iproc_i2c_enable_disable(iproc_i2c, true); + } ++ ++ return recover; + } + + static void bcm_iproc_i2c_slave_read(struct bcm_iproc_i2c_dev *iproc_i2c) +@@ -430,48 +448,6 @@ static bool bcm_iproc_i2c_slave_isr(struct bcm_iproc_i2c_dev *iproc_i2c, + u32 val; + u8 value; + +- /* +- * Slave events in case of master-write, master-write-read and, +- * master-read +- * +- * Master-write : only IS_S_RX_EVENT_SHIFT event +- * Master-write-read: both IS_S_RX_EVENT_SHIFT and IS_S_RD_EVENT_SHIFT +- * events +- * Master-read : both IS_S_RX_EVENT_SHIFT and IS_S_RD_EVENT_SHIFT +- * events or only IS_S_RD_EVENT_SHIFT +- * +- * iproc has a slave rx fifo size of 64 bytes. Rx fifo full interrupt +- * (IS_S_RX_FIFO_FULL_SHIFT) will be generated when RX fifo becomes +- * full. This can happen if Master issues write requests of more than +- * 64 bytes. +- */ +- if (status & BIT(IS_S_RX_EVENT_SHIFT) || +- status & BIT(IS_S_RD_EVENT_SHIFT) || +- status & BIT(IS_S_RX_FIFO_FULL_SHIFT)) { +- /* disable slave interrupts */ +- val = iproc_i2c_rd_reg(iproc_i2c, IE_OFFSET); +- val &= ~iproc_i2c->slave_int_mask; +- iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, val); +- +- if (status & BIT(IS_S_RD_EVENT_SHIFT)) +- /* Master-write-read request */ +- iproc_i2c->slave_rx_only = false; +- else +- /* Master-write request only */ +- iproc_i2c->slave_rx_only = true; +- +- /* schedule tasklet to read data later */ +- tasklet_schedule(&iproc_i2c->slave_rx_tasklet); +- +- /* +- * clear only IS_S_RX_EVENT_SHIFT and +- * IS_S_RX_FIFO_FULL_SHIFT interrupt. +- */ +- val = BIT(IS_S_RX_EVENT_SHIFT); +- if (status & BIT(IS_S_RX_FIFO_FULL_SHIFT)) +- val |= BIT(IS_S_RX_FIFO_FULL_SHIFT); +- iproc_i2c_wr_reg(iproc_i2c, IS_OFFSET, val); +- } + + if (status & BIT(IS_S_TX_UNDERRUN_SHIFT)) { + iproc_i2c->tx_underrun++; +@@ -503,8 +479,9 @@ static bool bcm_iproc_i2c_slave_isr(struct bcm_iproc_i2c_dev *iproc_i2c, + * less than PKT_LENGTH bytes were output on the SMBUS + */ + iproc_i2c->slave_int_mask &= ~BIT(IE_S_TX_UNDERRUN_SHIFT); +- iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, +- iproc_i2c->slave_int_mask); ++ val = iproc_i2c_rd_reg(iproc_i2c, IE_OFFSET); ++ val &= ~BIT(IE_S_TX_UNDERRUN_SHIFT); ++ iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, val); + + /* End of SMBUS for Master Read */ + val = BIT(S_TX_WR_STATUS_SHIFT); +@@ -525,9 +502,49 @@ static bool bcm_iproc_i2c_slave_isr(struct bcm_iproc_i2c_dev *iproc_i2c, + BIT(IS_S_START_BUSY_SHIFT)); + } + +- /* check slave transmit status only if slave is transmitting */ +- if (!iproc_i2c->slave_rx_only) +- bcm_iproc_i2c_check_slave_status(iproc_i2c); ++ /* if the controller has been reset, immediately return from the ISR */ ++ if (bcm_iproc_i2c_check_slave_status(iproc_i2c, status)) ++ return true; ++ ++ /* ++ * Slave events in case of master-write, master-write-read and, ++ * master-read ++ * ++ * Master-write : only IS_S_RX_EVENT_SHIFT event ++ * Master-write-read: both IS_S_RX_EVENT_SHIFT and IS_S_RD_EVENT_SHIFT ++ * events ++ * Master-read : both IS_S_RX_EVENT_SHIFT and IS_S_RD_EVENT_SHIFT ++ * events or only IS_S_RD_EVENT_SHIFT ++ * ++ * iproc has a slave rx fifo size of 64 bytes. Rx fifo full interrupt ++ * (IS_S_RX_FIFO_FULL_SHIFT) will be generated when RX fifo becomes ++ * full. This can happen if Master issues write requests of more than ++ * 64 bytes. ++ */ ++ if (status & BIT(IS_S_RX_EVENT_SHIFT) || ++ status & BIT(IS_S_RD_EVENT_SHIFT) || ++ status & BIT(IS_S_RX_FIFO_FULL_SHIFT)) { ++ /* disable slave interrupts */ ++ val = iproc_i2c_rd_reg(iproc_i2c, IE_OFFSET); ++ val &= ~iproc_i2c->slave_int_mask; ++ iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, val); ++ ++ if (status & BIT(IS_S_RD_EVENT_SHIFT)) ++ /* Master-write-read request */ ++ iproc_i2c->slave_rx_only = false; ++ else ++ /* Master-write request only */ ++ iproc_i2c->slave_rx_only = true; ++ ++ /* schedule tasklet to read data later */ ++ tasklet_schedule(&iproc_i2c->slave_rx_tasklet); ++ ++ /* clear IS_S_RX_FIFO_FULL_SHIFT interrupt */ ++ if (status & BIT(IS_S_RX_FIFO_FULL_SHIFT)) { ++ val = BIT(IS_S_RX_FIFO_FULL_SHIFT); ++ iproc_i2c_wr_reg(iproc_i2c, IS_OFFSET, val); ++ } ++ } + + return true; + } +-- +2.42.0 + diff --git a/queue-5.15/inet-shrink-struct-flowi_common.patch b/queue-5.15/inet-shrink-struct-flowi_common.patch new file mode 100644 index 00000000000..a2e7a05e712 --- /dev/null +++ b/queue-5.15/inet-shrink-struct-flowi_common.patch @@ -0,0 +1,44 @@ +From b01450a0bc4970cf915acc6106b398c4bee7654f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Oct 2023 14:10:37 +0000 +Subject: inet: shrink struct flowi_common + +From: Eric Dumazet + +[ Upstream commit 1726483b79a72e0150734d5367e4a0238bf8fcff ] + +I am looking at syzbot reports triggering kernel stack overflows +involving a cascade of ipvlan devices. + +We can save 8 bytes in struct flowi_common. + +This patch alone will not fix the issue, but is a start. + +Fixes: 24ba14406c5c ("route: Add multipath_hash in flowi_common to make user-define hash") +Signed-off-by: Eric Dumazet +Cc: wenxu +Reviewed-by: David Ahern +Link: https://lore.kernel.org/r/20231025141037.3448203-1-edumazet@google.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + include/net/flow.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/net/flow.h b/include/net/flow.h +index e3f9d92460e7a..776bacc96242a 100644 +--- a/include/net/flow.h ++++ b/include/net/flow.h +@@ -39,8 +39,8 @@ struct flowi_common { + #define FLOWI_FLAG_SKIP_NH_OIF 0x04 + __u32 flowic_secid; + kuid_t flowic_uid; +- struct flowi_tunnel flowic_tun_key; + __u32 flowic_multipath_hash; ++ struct flowi_tunnel flowic_tun_key; + }; + + union flowi_uli { +-- +2.42.0 + diff --git a/queue-5.15/input-synaptics-rmi4-fix-use-after-free-in-rmi_unreg.patch b/queue-5.15/input-synaptics-rmi4-fix-use-after-free-in-rmi_unreg.patch new file mode 100644 index 00000000000..f64ab41f5fc --- /dev/null +++ b/queue-5.15/input-synaptics-rmi4-fix-use-after-free-in-rmi_unreg.patch @@ -0,0 +1,43 @@ +From a70804718413b535e29f023dd6cf95b481cf2637 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 29 Oct 2023 02:53:36 +0000 +Subject: Input: synaptics-rmi4 - fix use after free in + rmi_unregister_function() + +From: Dan Carpenter + +[ Upstream commit eb988e46da2e4eae89f5337e047ce372fe33d5b1 ] + +The put_device() calls rmi_release_function() which frees "fn" so the +dereference on the next line "fn->num_of_irqs" is a use after free. +Move the put_device() to the end to fix this. + +Fixes: 24d28e4f1271 ("Input: synaptics-rmi4 - convert irq distribution to irq_domain") +Signed-off-by: Dan Carpenter +Link: https://lore.kernel.org/r/706efd36-7561-42f3-adfa-dd1d0bd4f5a1@moroto.mountain +Signed-off-by: Dmitry Torokhov +Signed-off-by: Sasha Levin +--- + drivers/input/rmi4/rmi_bus.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c +index 24f31a5c0e04a..014bb40e84236 100644 +--- a/drivers/input/rmi4/rmi_bus.c ++++ b/drivers/input/rmi4/rmi_bus.c +@@ -276,11 +276,11 @@ void rmi_unregister_function(struct rmi_function *fn) + + device_del(&fn->dev); + of_node_put(fn->dev.of_node); +- put_device(&fn->dev); + + for (i = 0; i < fn->num_of_irqs; i++) + irq_dispose_mapping(fn->irq[i]); + ++ put_device(&fn->dev); + } + + /** +-- +2.42.0 + diff --git a/queue-5.15/llc-verify-mac-len-before-reading-mac-header.patch b/queue-5.15/llc-verify-mac-len-before-reading-mac-header.patch new file mode 100644 index 00000000000..5697c1ba8a1 --- /dev/null +++ b/queue-5.15/llc-verify-mac-len-before-reading-mac-header.patch @@ -0,0 +1,113 @@ +From 82f87cfb1d4238d17e578fb41be2c8b3706ad67f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Oct 2023 19:42:38 -0400 +Subject: llc: verify mac len before reading mac header + +From: Willem de Bruijn + +[ Upstream commit 7b3ba18703a63f6fd487183b9262b08e5632da1b ] + +LLC reads the mac header with eth_hdr without verifying that the skb +has an Ethernet header. + +Syzbot was able to enter llc_rcv on a tun device. Tun can insert +packets without mac len and with user configurable skb->protocol +(passing a tun_pi header when not configuring IFF_NO_PI). + + BUG: KMSAN: uninit-value in llc_station_ac_send_test_r net/llc/llc_station.c:81 [inline] + BUG: KMSAN: uninit-value in llc_station_rcv+0x6fb/0x1290 net/llc/llc_station.c:111 + llc_station_ac_send_test_r net/llc/llc_station.c:81 [inline] + llc_station_rcv+0x6fb/0x1290 net/llc/llc_station.c:111 + llc_rcv+0xc5d/0x14a0 net/llc/llc_input.c:218 + __netif_receive_skb_one_core net/core/dev.c:5523 [inline] + __netif_receive_skb+0x1a6/0x5a0 net/core/dev.c:5637 + netif_receive_skb_internal net/core/dev.c:5723 [inline] + netif_receive_skb+0x58/0x660 net/core/dev.c:5782 + tun_rx_batched+0x3ee/0x980 drivers/net/tun.c:1555 + tun_get_user+0x54c5/0x69c0 drivers/net/tun.c:2002 + +Add a mac_len test before all three eth_hdr(skb) calls under net/llc. + +There are further uses in include/net/llc_pdu.h. All these are +protected by a test skb->protocol == ETH_P_802_2. Which does not +protect against this tun scenario. + +But the mac_len test added in this patch in llc_fixup_skb will +indirectly protect those too. That is called from llc_rcv before any +other LLC code. + +It is tempting to just add a blanket mac_len check in llc_rcv, but +not sure whether that could break valid LLC paths that do not assume +an Ethernet header. 802.2 LLC may be used on top of non-802.3 +protocols in principle. The below referenced commit shows that used +to, on top of Token Ring. + +At least one of the three eth_hdr uses goes back to before the start +of git history. But the one that syzbot exercises is introduced in +this commit. That commit is old enough (2008), that effectively all +stable kernels should receive this. + +Fixes: f83f1768f833 ("[LLC]: skb allocation size for responses") +Reported-by: syzbot+a8c7be6dee0de1b669cc@syzkaller.appspotmail.com +Signed-off-by: Willem de Bruijn +Link: https://lore.kernel.org/r/20231025234251.3796495-1-willemdebruijn.kernel@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/llc/llc_input.c | 10 ++++++++-- + net/llc/llc_s_ac.c | 3 +++ + net/llc/llc_station.c | 3 +++ + 3 files changed, 14 insertions(+), 2 deletions(-) + +diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c +index 7cac441862e21..51bccfb00a9cd 100644 +--- a/net/llc/llc_input.c ++++ b/net/llc/llc_input.c +@@ -127,8 +127,14 @@ static inline int llc_fixup_skb(struct sk_buff *skb) + skb->transport_header += llc_len; + skb_pull(skb, llc_len); + if (skb->protocol == htons(ETH_P_802_2)) { +- __be16 pdulen = eth_hdr(skb)->h_proto; +- s32 data_size = ntohs(pdulen) - llc_len; ++ __be16 pdulen; ++ s32 data_size; ++ ++ if (skb->mac_len < ETH_HLEN) ++ return 0; ++ ++ pdulen = eth_hdr(skb)->h_proto; ++ data_size = ntohs(pdulen) - llc_len; + + if (data_size < 0 || + !pskb_may_pull(skb, data_size)) +diff --git a/net/llc/llc_s_ac.c b/net/llc/llc_s_ac.c +index 79d1cef8f15a9..06fb8e6944b06 100644 +--- a/net/llc/llc_s_ac.c ++++ b/net/llc/llc_s_ac.c +@@ -153,6 +153,9 @@ int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb) + int rc = 1; + u32 data_size; + ++ if (skb->mac_len < ETH_HLEN) ++ return 1; ++ + llc_pdu_decode_sa(skb, mac_da); + llc_pdu_decode_da(skb, mac_sa); + llc_pdu_decode_ssap(skb, &dsap); +diff --git a/net/llc/llc_station.c b/net/llc/llc_station.c +index 05c6ae0920534..f506542925109 100644 +--- a/net/llc/llc_station.c ++++ b/net/llc/llc_station.c +@@ -76,6 +76,9 @@ static int llc_station_ac_send_test_r(struct sk_buff *skb) + u32 data_size; + struct sk_buff *nskb; + ++ if (skb->mac_len < ETH_HLEN) ++ goto out; ++ + /* The test request command is type U (llc_len = 3) */ + data_size = ntohs(eth_hdr(skb)->h_proto) - 3; + nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size); +-- +2.42.0 + diff --git a/queue-5.15/net-r8169-disable-multicast-filter-for-rtl8168h-and-.patch b/queue-5.15/net-r8169-disable-multicast-filter-for-rtl8168h-and-.patch new file mode 100644 index 00000000000..a8e7be4dc2c --- /dev/null +++ b/queue-5.15/net-r8169-disable-multicast-filter-for-rtl8168h-and-.patch @@ -0,0 +1,43 @@ +From a5ffaaca987dd8c5e03fb0066a8e2f87f7eac2ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Oct 2023 16:50:14 -0400 +Subject: net: r8169: Disable multicast filter for RTL8168H and RTL8107E + +From: Patrick Thompson + +[ Upstream commit efa5f1311c4998e9e6317c52bc5ee93b3a0f36df ] + +RTL8168H and RTL8107E ethernet adapters erroneously filter unicast +eapol packets unless allmulti is enabled. These devices correspond to +RTL_GIGA_MAC_VER_46 and VER_48. Add an exception for VER_46 and VER_48 +in the same way that VER_35 has an exception. + +Fixes: 6e1d0b898818 ("r8169:add support for RTL8168H and RTL8107E") +Signed-off-by: Patrick Thompson +Reviewed-by: Jacob Keller +Reviewed-by: Heiner Kallweit +Link: https://lore.kernel.org/r/20231030205031.177855-1-ptf@google.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/realtek/r8169_main.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c +index ab84c623a7c62..2e555eda19a85 100644 +--- a/drivers/net/ethernet/realtek/r8169_main.c ++++ b/drivers/net/ethernet/realtek/r8169_main.c +@@ -2551,7 +2551,9 @@ static void rtl_set_rx_mode(struct net_device *dev) + rx_mode |= AcceptAllPhys; + } else if (netdev_mc_count(dev) > MC_FILTER_LIMIT || + dev->flags & IFF_ALLMULTI || +- tp->mac_version == RTL_GIGA_MAC_VER_35) { ++ tp->mac_version == RTL_GIGA_MAC_VER_35 || ++ tp->mac_version == RTL_GIGA_MAC_VER_46 || ++ tp->mac_version == RTL_GIGA_MAC_VER_48) { + /* accept all multicasts */ + } else if (netdev_mc_empty(dev)) { + rx_mode &= ~AcceptMulticast; +-- +2.42.0 + diff --git a/queue-5.15/net-smc-allow-cdc-msg-send-rather-than-drop-it-with-.patch b/queue-5.15/net-smc-allow-cdc-msg-send-rather-than-drop-it-with-.patch new file mode 100644 index 00000000000..5be209d67dc --- /dev/null +++ b/queue-5.15/net-smc-allow-cdc-msg-send-rather-than-drop-it-with-.patch @@ -0,0 +1,64 @@ +From 9ca530bf318c3f03e27206c5ba4a43ae55e52ff6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Nov 2023 14:07:39 +0800 +Subject: net/smc: allow cdc msg send rather than drop it with NULL sndbuf_desc + +From: D. Wythe + +[ Upstream commit c5bf605ba4f9d6fbbb120595ab95002f4716edcb ] + +This patch re-fix the issues mentioned by commit 22a825c541d7 +("net/smc: fix NULL sndbuf_desc in smc_cdc_tx_handler()"). + +Blocking sending message do solve the issues though, but it also +prevents the peer to receive the final message. Besides, in logic, +whether the sndbuf_desc is NULL or not have no impact on the processing +of cdc message sending. + +Hence that, this patch allows the cdc message sending but to check the +sndbuf_desc with care in smc_cdc_tx_handler(). + +Fixes: 22a825c541d7 ("net/smc: fix NULL sndbuf_desc in smc_cdc_tx_handler()") +Signed-off-by: D. Wythe +Reviewed-by: Dust Li +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/smc/smc_cdc.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/net/smc/smc_cdc.c b/net/smc/smc_cdc.c +index 0823961ec2e63..1df7557362673 100644 +--- a/net/smc/smc_cdc.c ++++ b/net/smc/smc_cdc.c +@@ -28,13 +28,15 @@ static void smc_cdc_tx_handler(struct smc_wr_tx_pend_priv *pnd_snd, + { + struct smc_cdc_tx_pend *cdcpend = (struct smc_cdc_tx_pend *)pnd_snd; + struct smc_connection *conn = cdcpend->conn; ++ struct smc_buf_desc *sndbuf_desc; + struct smc_sock *smc; + int diff; + ++ sndbuf_desc = conn->sndbuf_desc; + smc = container_of(conn, struct smc_sock, conn); + bh_lock_sock(&smc->sk); +- if (!wc_status) { +- diff = smc_curs_diff(cdcpend->conn->sndbuf_desc->len, ++ if (!wc_status && sndbuf_desc) { ++ diff = smc_curs_diff(sndbuf_desc->len, + &cdcpend->conn->tx_curs_fin, + &cdcpend->cursor); + /* sndbuf_space is decreased in smc_sendmsg */ +@@ -104,9 +106,6 @@ int smc_cdc_msg_send(struct smc_connection *conn, + union smc_host_cursor cfed; + int rc; + +- if (unlikely(!READ_ONCE(conn->sndbuf_desc))) +- return -ENOBUFS; +- + smc_cdc_add_pending_send(conn, pend); + + conn->tx_cdc_seq++; +-- +2.42.0 + diff --git a/queue-5.15/net-smc-fix-dangling-sock-under-state-smc_appfinclos.patch b/queue-5.15/net-smc-fix-dangling-sock-under-state-smc_appfinclos.patch new file mode 100644 index 00000000000..1f1cd536f9a --- /dev/null +++ b/queue-5.15/net-smc-fix-dangling-sock-under-state-smc_appfinclos.patch @@ -0,0 +1,111 @@ +From 19484ea497a8a1229d06cd9acdc6d1f70c2bddcd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Nov 2023 14:07:38 +0800 +Subject: net/smc: fix dangling sock under state SMC_APPFINCLOSEWAIT + +From: D. Wythe + +[ Upstream commit 5211c9729484c923f8d2e06bd29f9322cc42bb8f ] + +Considering scenario: + + smc_cdc_rx_handler +__smc_release + sock_set_flag +smc_close_active() +sock_set_flag + +__set_bit(DEAD) __set_bit(DONE) + +Dues to __set_bit is not atomic, the DEAD or DONE might be lost. +if the DEAD flag lost, the state SMC_CLOSED will be never be reached +in smc_close_passive_work: + +if (sock_flag(sk, SOCK_DEAD) && + smc_close_sent_any_close(conn)) { + sk->sk_state = SMC_CLOSED; +} else { + /* just shutdown, but not yet closed locally */ + sk->sk_state = SMC_APPFINCLOSEWAIT; +} + +Replace sock_set_flags or __set_bit to set_bit will fix this problem. +Since set_bit is atomic. + +Fixes: b38d732477e4 ("smc: socket closing and linkgroup cleanup") +Signed-off-by: D. Wythe +Reviewed-by: Dust Li +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/smc/af_smc.c | 4 ++-- + net/smc/smc.h | 5 +++++ + net/smc/smc_cdc.c | 2 +- + net/smc/smc_close.c | 2 +- + 4 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c +index 9cdb7df0801f3..49cf523a783a2 100644 +--- a/net/smc/af_smc.c ++++ b/net/smc/af_smc.c +@@ -145,7 +145,7 @@ static int __smc_release(struct smc_sock *smc) + + if (!smc->use_fallback) { + rc = smc_close_active(smc); +- sock_set_flag(sk, SOCK_DEAD); ++ smc_sock_set_flag(sk, SOCK_DEAD); + sk->sk_shutdown |= SHUTDOWN_MASK; + } else { + if (sk->sk_state != SMC_CLOSED) { +@@ -1334,7 +1334,7 @@ static int smc_clcsock_accept(struct smc_sock *lsmc, struct smc_sock **new_smc) + if (new_clcsock) + sock_release(new_clcsock); + new_sk->sk_state = SMC_CLOSED; +- sock_set_flag(new_sk, SOCK_DEAD); ++ smc_sock_set_flag(new_sk, SOCK_DEAD); + sock_put(new_sk); /* final */ + *new_smc = NULL; + goto out; +diff --git a/net/smc/smc.h b/net/smc/smc.h +index 930544f7b2e2c..57e376756b913 100644 +--- a/net/smc/smc.h ++++ b/net/smc/smc.h +@@ -315,4 +315,9 @@ static inline bool using_ipsec(struct smc_sock *smc) + struct sock *smc_accept_dequeue(struct sock *parent, struct socket *new_sock); + void smc_close_non_accepted(struct sock *sk); + ++static inline void smc_sock_set_flag(struct sock *sk, enum sock_flags flag) ++{ ++ set_bit(flag, &sk->sk_flags); ++} ++ + #endif /* __SMC_H */ +diff --git a/net/smc/smc_cdc.c b/net/smc/smc_cdc.c +index 41b23f71c29a2..0823961ec2e63 100644 +--- a/net/smc/smc_cdc.c ++++ b/net/smc/smc_cdc.c +@@ -370,7 +370,7 @@ static void smc_cdc_msg_recv_action(struct smc_sock *smc, + smc->sk.sk_shutdown |= RCV_SHUTDOWN; + if (smc->clcsock && smc->clcsock->sk) + smc->clcsock->sk->sk_shutdown |= RCV_SHUTDOWN; +- sock_set_flag(&smc->sk, SOCK_DONE); ++ smc_sock_set_flag(&smc->sk, SOCK_DONE); + sock_hold(&smc->sk); /* sock_put in close_work */ + if (!queue_work(smc_close_wq, &conn->close_work)) + sock_put(&smc->sk); +diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c +index 149a59ecd299f..0790cac9ae3ee 100644 +--- a/net/smc/smc_close.c ++++ b/net/smc/smc_close.c +@@ -170,7 +170,7 @@ void smc_close_active_abort(struct smc_sock *smc) + break; + } + +- sock_set_flag(sk, SOCK_DEAD); ++ smc_sock_set_flag(sk, SOCK_DEAD); + sk->sk_state_change(sk); + + if (release_clcsock) { +-- +2.42.0 + diff --git a/queue-5.15/net-smc-put-sk-reference-if-close-work-was-canceled.patch b/queue-5.15/net-smc-put-sk-reference-if-close-work-was-canceled.patch new file mode 100644 index 00000000000..8164df43715 --- /dev/null +++ b/queue-5.15/net-smc-put-sk-reference-if-close-work-was-canceled.patch @@ -0,0 +1,40 @@ +From 383898c7942006ed087b2106d9e2dc8c37a11dd8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Nov 2023 14:07:40 +0800 +Subject: net/smc: put sk reference if close work was canceled + +From: D. Wythe + +[ Upstream commit aa96fbd6d78d9770323b21e2c92bd38821be8852 ] + +Note that we always hold a reference to sock when attempting +to submit close_work. Therefore, if we have successfully +canceled close_work from pending, we MUST release that reference +to avoid potential leaks. + +Fixes: 42bfba9eaa33 ("net/smc: immediate termination for SMCD link groups") +Signed-off-by: D. Wythe +Reviewed-by: Dust Li +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/smc/smc_close.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c +index 0790cac9ae3ee..bcd3ea894555d 100644 +--- a/net/smc/smc_close.c ++++ b/net/smc/smc_close.c +@@ -113,7 +113,8 @@ static void smc_close_cancel_work(struct smc_sock *smc) + struct sock *sk = &smc->sk; + + release_sock(sk); +- cancel_work_sync(&smc->conn.close_work); ++ if (cancel_work_sync(&smc->conn.close_work)) ++ sock_put(sk); + cancel_delayed_work_sync(&smc->conn.tx_work); + lock_sock(sk); + } +-- +2.42.0 + diff --git a/queue-5.15/net-stmmac-xgmac-enable-support-for-multiple-flexibl.patch b/queue-5.15/net-stmmac-xgmac-enable-support-for-multiple-flexibl.patch new file mode 100644 index 00000000000..777e87525f0 --- /dev/null +++ b/queue-5.15/net-stmmac-xgmac-enable-support-for-multiple-flexibl.patch @@ -0,0 +1,68 @@ +From 2bd20cad1de6cd383d222c7a208eea001d4536ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 31 Oct 2023 10:27:29 +0800 +Subject: net: stmmac: xgmac: Enable support for multiple Flexible PPS outputs + +From: Furong Xu <0x1207@gmail.com> + +[ Upstream commit db456d90a4c1b43b6251fa4348c8adc59b583274 ] + +From XGMAC Core 3.20 and later, each Flexible PPS has individual PPSEN bit +to select Fixed mode or Flexible mode. The PPSEN must be set, or it stays +in Fixed PPS mode by default. +XGMAC Core prior 3.20, only PPSEN0(bit 4) is writable. PPSEN{1,2,3} are +read-only reserved, and they are already in Flexible mode by default, our +new code always set PPSEN{1,2,3} do not make things worse ;-) + +Fixes: 95eaf3cd0a90 ("net: stmmac: dwxgmac: Add Flexible PPS support") +Reviewed-by: Serge Semin +Reviewed-by: Jacob Keller +Signed-off-by: Furong Xu <0x1207@gmail.com> +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h | 2 +- + .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 14 +++++++++++++- + 2 files changed, 14 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h +index 1913385df6856..880a75bf2eb1f 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h ++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h +@@ -222,7 +222,7 @@ + ((val) << XGMAC_PPS_MINIDX(x)) + #define XGMAC_PPSCMD_START 0x2 + #define XGMAC_PPSCMD_STOP 0x5 +-#define XGMAC_PPSEN0 BIT(4) ++#define XGMAC_PPSENx(x) BIT(4 + (x) * 8) + #define XGMAC_PPSx_TARGET_TIME_SEC(x) (0x00000d80 + (x) * 0x10) + #define XGMAC_PPSx_TARGET_TIME_NSEC(x) (0x00000d84 + (x) * 0x10) + #define XGMAC_TRGTBUSY0 BIT(31) +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c +index c4d78fa93663b..54aa0fbd1bf63 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c +@@ -1134,7 +1134,19 @@ static int dwxgmac2_flex_pps_config(void __iomem *ioaddr, int index, + + val |= XGMAC_PPSCMDx(index, XGMAC_PPSCMD_START); + val |= XGMAC_TRGTMODSELx(index, XGMAC_PPSCMD_START); +- val |= XGMAC_PPSEN0; ++ ++ /* XGMAC Core has 4 PPS outputs at most. ++ * ++ * Prior XGMAC Core 3.20, Fixed mode or Flexible mode are selectable for ++ * PPS0 only via PPSEN0. PPS{1,2,3} are in Flexible mode by default, ++ * and can not be switched to Fixed mode, since PPSEN{1,2,3} are ++ * read-only reserved to 0. ++ * But we always set PPSEN{1,2,3} do not make things worse ;-) ++ * ++ * From XGMAC Core 3.20 and later, PPSEN{0,1,2,3} are writable and must ++ * be set, or the PPS outputs stay in Fixed PPS mode by default. ++ */ ++ val |= XGMAC_PPSENx(index); + + writel(cfg->start.tv_sec, ioaddr + XGMAC_PPSx_TARGET_TIME_SEC(index)); + +-- +2.42.0 + diff --git a/queue-5.15/netfilter-nat-fix-ipv6-nat-redirect-with-mapped-and-.patch b/queue-5.15/netfilter-nat-fix-ipv6-nat-redirect-with-mapped-and-.patch new file mode 100644 index 00000000000..05e1869d489 --- /dev/null +++ b/queue-5.15/netfilter-nat-fix-ipv6-nat-redirect-with-mapped-and-.patch @@ -0,0 +1,97 @@ +From 98a806ff1cd1af5aa46b11d7ff4e7432dc20e02f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Nov 2023 13:18:53 +0100 +Subject: netfilter: nat: fix ipv6 nat redirect with mapped and scoped + addresses + +From: Florian Westphal + +[ Upstream commit 80abbe8a8263106fe45a4f293b92b5c74cc9cc8a ] + +The ipv6 redirect target was derived from the ipv4 one, i.e. its +identical to a 'dnat' with the first (primary) address assigned to the +network interface. The code has been moved around to make it usable +from nf_tables too, but its still the same as it was back when this +was added in 2012. + +IPv6, however, has different types of addresses, if the 'wrong' address +comes first the redirection does not work. + +In Daniels case, the addresses are: + inet6 ::ffff:192 ... + inet6 2a01: ... + +... so the function attempts to redirect to the mapped address. + +Add more checks before the address is deemed correct: +1. If the packets' daddr is scoped, search for a scoped address too +2. skip tentative addresses +3. skip mapped addresses + +Use the first address that appears to match our needs. + +Reported-by: Daniel Huhardeaux +Closes: https://lore.kernel.org/netfilter/71be06b8-6aa0-4cf9-9e0b-e2839b01b22f@tootai.net/ +Fixes: 115e23ac78f8 ("netfilter: ip6tables: add REDIRECT target") +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_nat_redirect.c | 27 ++++++++++++++++++++++++++- + 1 file changed, 26 insertions(+), 1 deletion(-) + +diff --git a/net/netfilter/nf_nat_redirect.c b/net/netfilter/nf_nat_redirect.c +index 6616ba5d0b049..5b37487d9d11f 100644 +--- a/net/netfilter/nf_nat_redirect.c ++++ b/net/netfilter/nf_nat_redirect.c +@@ -80,6 +80,26 @@ EXPORT_SYMBOL_GPL(nf_nat_redirect_ipv4); + + static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT; + ++static bool nf_nat_redirect_ipv6_usable(const struct inet6_ifaddr *ifa, unsigned int scope) ++{ ++ unsigned int ifa_addr_type = ipv6_addr_type(&ifa->addr); ++ ++ if (ifa_addr_type & IPV6_ADDR_MAPPED) ++ return false; ++ ++ if ((ifa->flags & IFA_F_TENTATIVE) && (!(ifa->flags & IFA_F_OPTIMISTIC))) ++ return false; ++ ++ if (scope) { ++ unsigned int ifa_scope = ifa_addr_type & IPV6_ADDR_SCOPE_MASK; ++ ++ if (!(scope & ifa_scope)) ++ return false; ++ } ++ ++ return true; ++} ++ + unsigned int + nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range, + unsigned int hooknum) +@@ -89,14 +109,19 @@ nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range, + if (hooknum == NF_INET_LOCAL_OUT) { + newdst.in6 = loopback_addr; + } else { ++ unsigned int scope = ipv6_addr_scope(&ipv6_hdr(skb)->daddr); + struct inet6_dev *idev; +- struct inet6_ifaddr *ifa; + bool addr = false; + + idev = __in6_dev_get(skb->dev); + if (idev != NULL) { ++ const struct inet6_ifaddr *ifa; ++ + read_lock_bh(&idev->lock); + list_for_each_entry(ifa, &idev->addr_list, if_list) { ++ if (!nf_nat_redirect_ipv6_usable(ifa, scope)) ++ continue; ++ + newdst.in6 = ifa->addr; + addr = true; + break; +-- +2.42.0 + diff --git a/queue-5.15/netfilter-nft_redir-use-struct-nf_nat_range2-through.patch b/queue-5.15/netfilter-nft_redir-use-struct-nf_nat_range2-through.patch new file mode 100644 index 00000000000..003be880a77 --- /dev/null +++ b/queue-5.15/netfilter-nft_redir-use-struct-nf_nat_range2-through.patch @@ -0,0 +1,372 @@ +From 327660d886619e7e5f84b615d79048c1261f57f5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Mar 2023 21:48:01 +0000 +Subject: netfilter: nft_redir: use `struct nf_nat_range2` throughout and + deduplicate eval call-backs + +From: Jeremy Sowden + +[ Upstream commit 6f56ad1b92328997e1b1792047099df6f8d7acb5 ] + +`nf_nat_redirect_ipv4` takes a `struct nf_nat_ipv4_multi_range_compat`, +but converts it internally to a `struct nf_nat_range2`. Change the +function to take the latter, factor out the code now shared with +`nf_nat_redirect_ipv6`, move the conversion to the xt_REDIRECT module, +and update the ipv4 range initialization in the nft_redir module. + +Replace a bare hex constant for 127.0.0.1 with a macro. + +Remove `WARN_ON`. `nf_nat_setup_info` calls `nf_ct_is_confirmed`: + + /* Can't setup nat info for confirmed ct. */ + if (nf_ct_is_confirmed(ct)) + return NF_ACCEPT; + +This means that `ct` cannot be null or the kernel will crash, and +implies that `ctinfo` is `IP_CT_NEW` or `IP_CT_RELATED`. + +nft_redir has separate ipv4 and ipv6 call-backs which share much of +their code, and an inet one switch containing a switch that calls one of +the others based on the family of the packet. Merge the ipv4 and ipv6 +ones into the inet one in order to get rid of the duplicate code. + +Const-qualify the `priv` pointer since we don't need to write through +it. + +Assign `priv->flags` to the range instead of OR-ing it in. + +Set the `NF_NAT_RANGE_PROTO_SPECIFIED` flag once during init, rather +than on every eval. + +Signed-off-by: Jeremy Sowden +Signed-off-by: Florian Westphal +Stable-dep-of: 80abbe8a8263 ("netfilter: nat: fix ipv6 nat redirect with mapped and scoped addresses") +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_nat_redirect.h | 3 +- + net/netfilter/nf_nat_redirect.c | 71 ++++++++++----------- + net/netfilter/nft_redir.c | 84 +++++++++---------------- + net/netfilter/xt_REDIRECT.c | 10 ++- + 4 files changed, 72 insertions(+), 96 deletions(-) + +diff --git a/include/net/netfilter/nf_nat_redirect.h b/include/net/netfilter/nf_nat_redirect.h +index 2418653a66db1..279380de904c8 100644 +--- a/include/net/netfilter/nf_nat_redirect.h ++++ b/include/net/netfilter/nf_nat_redirect.h +@@ -6,8 +6,7 @@ + #include + + unsigned int +-nf_nat_redirect_ipv4(struct sk_buff *skb, +- const struct nf_nat_ipv4_multi_range_compat *mr, ++nf_nat_redirect_ipv4(struct sk_buff *skb, const struct nf_nat_range2 *range, + unsigned int hooknum); + unsigned int + nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range, +diff --git a/net/netfilter/nf_nat_redirect.c b/net/netfilter/nf_nat_redirect.c +index f91579c821e9a..6616ba5d0b049 100644 +--- a/net/netfilter/nf_nat_redirect.c ++++ b/net/netfilter/nf_nat_redirect.c +@@ -10,6 +10,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -24,54 +25,56 @@ + #include + #include + ++static unsigned int ++nf_nat_redirect(struct sk_buff *skb, const struct nf_nat_range2 *range, ++ const union nf_inet_addr *newdst) ++{ ++ struct nf_nat_range2 newrange; ++ enum ip_conntrack_info ctinfo; ++ struct nf_conn *ct; ++ ++ ct = nf_ct_get(skb, &ctinfo); ++ ++ memset(&newrange, 0, sizeof(newrange)); ++ ++ newrange.flags = range->flags | NF_NAT_RANGE_MAP_IPS; ++ newrange.min_addr = *newdst; ++ newrange.max_addr = *newdst; ++ newrange.min_proto = range->min_proto; ++ newrange.max_proto = range->max_proto; ++ ++ return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST); ++} ++ + unsigned int +-nf_nat_redirect_ipv4(struct sk_buff *skb, +- const struct nf_nat_ipv4_multi_range_compat *mr, ++nf_nat_redirect_ipv4(struct sk_buff *skb, const struct nf_nat_range2 *range, + unsigned int hooknum) + { +- struct nf_conn *ct; +- enum ip_conntrack_info ctinfo; +- __be32 newdst; +- struct nf_nat_range2 newrange; ++ union nf_inet_addr newdst = {}; + + WARN_ON(hooknum != NF_INET_PRE_ROUTING && + hooknum != NF_INET_LOCAL_OUT); + +- ct = nf_ct_get(skb, &ctinfo); +- WARN_ON(!(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED))); +- + /* Local packets: make them go to loopback */ + if (hooknum == NF_INET_LOCAL_OUT) { +- newdst = htonl(0x7F000001); ++ newdst.ip = htonl(INADDR_LOOPBACK); + } else { + const struct in_device *indev; + +- newdst = 0; +- + indev = __in_dev_get_rcu(skb->dev); + if (indev) { + const struct in_ifaddr *ifa; + + ifa = rcu_dereference(indev->ifa_list); + if (ifa) +- newdst = ifa->ifa_local; ++ newdst.ip = ifa->ifa_local; + } + +- if (!newdst) ++ if (!newdst.ip) + return NF_DROP; + } + +- /* Transfer from original range. */ +- memset(&newrange.min_addr, 0, sizeof(newrange.min_addr)); +- memset(&newrange.max_addr, 0, sizeof(newrange.max_addr)); +- newrange.flags = mr->range[0].flags | NF_NAT_RANGE_MAP_IPS; +- newrange.min_addr.ip = newdst; +- newrange.max_addr.ip = newdst; +- newrange.min_proto = mr->range[0].min; +- newrange.max_proto = mr->range[0].max; +- +- /* Hand modified range to generic setup. */ +- return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST); ++ return nf_nat_redirect(skb, range, &newdst); + } + EXPORT_SYMBOL_GPL(nf_nat_redirect_ipv4); + +@@ -81,14 +84,10 @@ unsigned int + nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range, + unsigned int hooknum) + { +- struct nf_nat_range2 newrange; +- struct in6_addr newdst; +- enum ip_conntrack_info ctinfo; +- struct nf_conn *ct; ++ union nf_inet_addr newdst = {}; + +- ct = nf_ct_get(skb, &ctinfo); + if (hooknum == NF_INET_LOCAL_OUT) { +- newdst = loopback_addr; ++ newdst.in6 = loopback_addr; + } else { + struct inet6_dev *idev; + struct inet6_ifaddr *ifa; +@@ -98,7 +97,7 @@ nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range, + if (idev != NULL) { + read_lock_bh(&idev->lock); + list_for_each_entry(ifa, &idev->addr_list, if_list) { +- newdst = ifa->addr; ++ newdst.in6 = ifa->addr; + addr = true; + break; + } +@@ -109,12 +108,6 @@ nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range, + return NF_DROP; + } + +- newrange.flags = range->flags | NF_NAT_RANGE_MAP_IPS; +- newrange.min_addr.in6 = newdst; +- newrange.max_addr.in6 = newdst; +- newrange.min_proto = range->min_proto; +- newrange.max_proto = range->max_proto; +- +- return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST); ++ return nf_nat_redirect(skb, range, &newdst); + } + EXPORT_SYMBOL_GPL(nf_nat_redirect_ipv6); +diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c +index e64f531d66cfc..677ce42183691 100644 +--- a/net/netfilter/nft_redir.c ++++ b/net/netfilter/nft_redir.c +@@ -64,6 +64,8 @@ static int nft_redir_init(const struct nft_ctx *ctx, + } else { + priv->sreg_proto_max = priv->sreg_proto_min; + } ++ ++ priv->flags |= NF_NAT_RANGE_PROTO_SPECIFIED; + } + + if (tb[NFTA_REDIR_FLAGS]) { +@@ -98,25 +100,37 @@ static int nft_redir_dump(struct sk_buff *skb, const struct nft_expr *expr) + return -1; + } + +-static void nft_redir_ipv4_eval(const struct nft_expr *expr, +- struct nft_regs *regs, +- const struct nft_pktinfo *pkt) ++static void nft_redir_eval(const struct nft_expr *expr, ++ struct nft_regs *regs, ++ const struct nft_pktinfo *pkt) + { +- struct nft_redir *priv = nft_expr_priv(expr); +- struct nf_nat_ipv4_multi_range_compat mr; ++ const struct nft_redir *priv = nft_expr_priv(expr); ++ struct nf_nat_range2 range; + +- memset(&mr, 0, sizeof(mr)); ++ memset(&range, 0, sizeof(range)); ++ range.flags = priv->flags; + if (priv->sreg_proto_min) { +- mr.range[0].min.all = (__force __be16)nft_reg_load16( +- ®s->data[priv->sreg_proto_min]); +- mr.range[0].max.all = (__force __be16)nft_reg_load16( +- ®s->data[priv->sreg_proto_max]); +- mr.range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED; ++ range.min_proto.all = (__force __be16) ++ nft_reg_load16(®s->data[priv->sreg_proto_min]); ++ range.max_proto.all = (__force __be16) ++ nft_reg_load16(®s->data[priv->sreg_proto_max]); + } + +- mr.range[0].flags |= priv->flags; +- +- regs->verdict.code = nf_nat_redirect_ipv4(pkt->skb, &mr, nft_hook(pkt)); ++ switch (nft_pf(pkt)) { ++ case NFPROTO_IPV4: ++ regs->verdict.code = nf_nat_redirect_ipv4(pkt->skb, &range, ++ nft_hook(pkt)); ++ break; ++#ifdef CONFIG_NF_TABLES_IPV6 ++ case NFPROTO_IPV6: ++ regs->verdict.code = nf_nat_redirect_ipv6(pkt->skb, &range, ++ nft_hook(pkt)); ++ break; ++#endif ++ default: ++ WARN_ON_ONCE(1); ++ break; ++ } + } + + static void +@@ -129,7 +143,7 @@ static struct nft_expr_type nft_redir_ipv4_type; + static const struct nft_expr_ops nft_redir_ipv4_ops = { + .type = &nft_redir_ipv4_type, + .size = NFT_EXPR_SIZE(sizeof(struct nft_redir)), +- .eval = nft_redir_ipv4_eval, ++ .eval = nft_redir_eval, + .init = nft_redir_init, + .destroy = nft_redir_ipv4_destroy, + .dump = nft_redir_dump, +@@ -146,28 +160,6 @@ static struct nft_expr_type nft_redir_ipv4_type __read_mostly = { + }; + + #ifdef CONFIG_NF_TABLES_IPV6 +-static void nft_redir_ipv6_eval(const struct nft_expr *expr, +- struct nft_regs *regs, +- const struct nft_pktinfo *pkt) +-{ +- struct nft_redir *priv = nft_expr_priv(expr); +- struct nf_nat_range2 range; +- +- memset(&range, 0, sizeof(range)); +- if (priv->sreg_proto_min) { +- range.min_proto.all = (__force __be16)nft_reg_load16( +- ®s->data[priv->sreg_proto_min]); +- range.max_proto.all = (__force __be16)nft_reg_load16( +- ®s->data[priv->sreg_proto_max]); +- range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; +- } +- +- range.flags |= priv->flags; +- +- regs->verdict.code = +- nf_nat_redirect_ipv6(pkt->skb, &range, nft_hook(pkt)); +-} +- + static void + nft_redir_ipv6_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr) + { +@@ -178,7 +170,7 @@ static struct nft_expr_type nft_redir_ipv6_type; + static const struct nft_expr_ops nft_redir_ipv6_ops = { + .type = &nft_redir_ipv6_type, + .size = NFT_EXPR_SIZE(sizeof(struct nft_redir)), +- .eval = nft_redir_ipv6_eval, ++ .eval = nft_redir_eval, + .init = nft_redir_init, + .destroy = nft_redir_ipv6_destroy, + .dump = nft_redir_dump, +@@ -196,20 +188,6 @@ static struct nft_expr_type nft_redir_ipv6_type __read_mostly = { + #endif + + #ifdef CONFIG_NF_TABLES_INET +-static void nft_redir_inet_eval(const struct nft_expr *expr, +- struct nft_regs *regs, +- const struct nft_pktinfo *pkt) +-{ +- switch (nft_pf(pkt)) { +- case NFPROTO_IPV4: +- return nft_redir_ipv4_eval(expr, regs, pkt); +- case NFPROTO_IPV6: +- return nft_redir_ipv6_eval(expr, regs, pkt); +- } +- +- WARN_ON_ONCE(1); +-} +- + static void + nft_redir_inet_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr) + { +@@ -220,7 +198,7 @@ static struct nft_expr_type nft_redir_inet_type; + static const struct nft_expr_ops nft_redir_inet_ops = { + .type = &nft_redir_inet_type, + .size = NFT_EXPR_SIZE(sizeof(struct nft_redir)), +- .eval = nft_redir_inet_eval, ++ .eval = nft_redir_eval, + .init = nft_redir_init, + .destroy = nft_redir_inet_destroy, + .dump = nft_redir_dump, +diff --git a/net/netfilter/xt_REDIRECT.c b/net/netfilter/xt_REDIRECT.c +index 353ca7801251a..ff66b56a3f97d 100644 +--- a/net/netfilter/xt_REDIRECT.c ++++ b/net/netfilter/xt_REDIRECT.c +@@ -46,7 +46,6 @@ static void redirect_tg_destroy(const struct xt_tgdtor_param *par) + nf_ct_netns_put(par->net, par->family); + } + +-/* FIXME: Take multiple ranges --RR */ + static int redirect_tg4_check(const struct xt_tgchk_param *par) + { + const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo; +@@ -65,7 +64,14 @@ static int redirect_tg4_check(const struct xt_tgchk_param *par) + static unsigned int + redirect_tg4(struct sk_buff *skb, const struct xt_action_param *par) + { +- return nf_nat_redirect_ipv4(skb, par->targinfo, xt_hooknum(par)); ++ const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo; ++ struct nf_nat_range2 range = { ++ .flags = mr->range[0].flags, ++ .min_proto = mr->range[0].min, ++ .max_proto = mr->range[0].max, ++ }; ++ ++ return nf_nat_redirect_ipv4(skb, &range, xt_hooknum(par)); + } + + static struct xt_target redirect_tg_reg[] __read_mostly = { +-- +2.42.0 + diff --git a/queue-5.15/netfilter-xt_recent-fix-increase-ipv6-literal-buffer.patch b/queue-5.15/netfilter-xt_recent-fix-increase-ipv6-literal-buffer.patch new file mode 100644 index 00000000000..bc0d0df3cda --- /dev/null +++ b/queue-5.15/netfilter-xt_recent-fix-increase-ipv6-literal-buffer.patch @@ -0,0 +1,49 @@ +From 7bb911d83f9bf03a49c5a94fb177dbb81f28f182 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 5 Nov 2023 11:56:00 -0800 +Subject: netfilter: xt_recent: fix (increase) ipv6 literal buffer length +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Maciej Å»enczykowski + +[ Upstream commit 7b308feb4fd2d1c06919445c65c8fbf8e9fd1781 ] + +in6_pton() supports 'low-32-bit dot-decimal representation' +(this is useful with DNS64/NAT64 networks for example): + + # echo +aaaa:bbbb:cccc:dddd:eeee:ffff:1.2.3.4 > /proc/self/net/xt_recent/DEFAULT + # cat /proc/self/net/xt_recent/DEFAULT + src=aaaa:bbbb:cccc:dddd:eeee:ffff:0102:0304 ttl: 0 last_seen: 9733848829 oldest_pkt: 1 9733848829 + +but the provided buffer is too short: + + # echo +aaaa:bbbb:cccc:dddd:eeee:ffff:255.255.255.255 > /proc/self/net/xt_recent/DEFAULT + -bash: echo: write error: Invalid argument + +Fixes: 079aa88fe717 ("netfilter: xt_recent: IPv6 support") +Signed-off-by: Maciej Å»enczykowski +Reviewed-by: Simon Horman +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/xt_recent.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c +index 0446307516cdf..39937ff245275 100644 +--- a/net/netfilter/xt_recent.c ++++ b/net/netfilter/xt_recent.c +@@ -561,7 +561,7 @@ recent_mt_proc_write(struct file *file, const char __user *input, + { + struct recent_table *t = PDE_DATA(file_inode(file)); + struct recent_entry *e; +- char buf[sizeof("+b335:1d35:1e55:dead:c0de:1715:5afe:c0de")]; ++ char buf[sizeof("+b335:1d35:1e55:dead:c0de:1715:255.255.255.255")]; + const char *c = buf; + union nf_inet_addr addr = {}; + u_int16_t family; +-- +2.42.0 + diff --git a/queue-5.15/octeontx2-pf-fix-error-codes.patch b/queue-5.15/octeontx2-pf-fix-error-codes.patch new file mode 100644 index 00000000000..82aac0e518d --- /dev/null +++ b/queue-5.15/octeontx2-pf-fix-error-codes.patch @@ -0,0 +1,69 @@ +From 3a5854c24049e7c293f03cb018e79c99a5bb578f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Oct 2023 07:49:52 +0530 +Subject: octeontx2-pf: Fix error codes + +From: Ratheesh Kannoth + +[ Upstream commit 96b9a68d1a6e4f889d453874c9e359aa720b520f ] + +Some of error codes were wrong. Fix the same. + +Fixes: 51afe9026d0c ("octeontx2-pf: NIX TX overwrites SQ_CTX_HW_S[SQ_INT]") +Signed-off-by: Ratheesh Kannoth +Reviewed-by: Wojciech Drewek +Link: https://lore.kernel.org/r/20231027021953.1819959-1-rkannoth@marvell.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../marvell/octeontx2/nic/otx2_struct.h | 34 +++++++++---------- + 1 file changed, 17 insertions(+), 17 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h +index e5f30fd778fc1..e7fd9d955d650 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h +@@ -311,23 +311,23 @@ enum nix_snd_status_e { + NIX_SND_STATUS_EXT_ERR = 0x6, + NIX_SND_STATUS_JUMP_FAULT = 0x7, + NIX_SND_STATUS_JUMP_POISON = 0x8, +- NIX_SND_STATUS_CRC_ERR = 0x9, +- NIX_SND_STATUS_IMM_ERR = 0x10, +- NIX_SND_STATUS_SG_ERR = 0x11, +- NIX_SND_STATUS_MEM_ERR = 0x12, +- NIX_SND_STATUS_INVALID_SUBDC = 0x13, +- NIX_SND_STATUS_SUBDC_ORDER_ERR = 0x14, +- NIX_SND_STATUS_DATA_FAULT = 0x15, +- NIX_SND_STATUS_DATA_POISON = 0x16, +- NIX_SND_STATUS_NPC_DROP_ACTION = 0x17, +- NIX_SND_STATUS_LOCK_VIOL = 0x18, +- NIX_SND_STATUS_NPC_UCAST_CHAN_ERR = 0x19, +- NIX_SND_STATUS_NPC_MCAST_CHAN_ERR = 0x20, +- NIX_SND_STATUS_NPC_MCAST_ABORT = 0x21, +- NIX_SND_STATUS_NPC_VTAG_PTR_ERR = 0x22, +- NIX_SND_STATUS_NPC_VTAG_SIZE_ERR = 0x23, +- NIX_SND_STATUS_SEND_MEM_FAULT = 0x24, +- NIX_SND_STATUS_SEND_STATS_ERR = 0x25, ++ NIX_SND_STATUS_CRC_ERR = 0x10, ++ NIX_SND_STATUS_IMM_ERR = 0x11, ++ NIX_SND_STATUS_SG_ERR = 0x12, ++ NIX_SND_STATUS_MEM_ERR = 0x13, ++ NIX_SND_STATUS_INVALID_SUBDC = 0x14, ++ NIX_SND_STATUS_SUBDC_ORDER_ERR = 0x15, ++ NIX_SND_STATUS_DATA_FAULT = 0x16, ++ NIX_SND_STATUS_DATA_POISON = 0x17, ++ NIX_SND_STATUS_NPC_DROP_ACTION = 0x20, ++ NIX_SND_STATUS_LOCK_VIOL = 0x21, ++ NIX_SND_STATUS_NPC_UCAST_CHAN_ERR = 0x22, ++ NIX_SND_STATUS_NPC_MCAST_CHAN_ERR = 0x23, ++ NIX_SND_STATUS_NPC_MCAST_ABORT = 0x24, ++ NIX_SND_STATUS_NPC_VTAG_PTR_ERR = 0x25, ++ NIX_SND_STATUS_NPC_VTAG_SIZE_ERR = 0x26, ++ NIX_SND_STATUS_SEND_MEM_FAULT = 0x27, ++ NIX_SND_STATUS_SEND_STATS_ERR = 0x28, + NIX_SND_STATUS_MAX, + }; + +-- +2.42.0 + diff --git a/queue-5.15/octeontx2-pf-fix-holes-in-error-code.patch b/queue-5.15/octeontx2-pf-fix-holes-in-error-code.patch new file mode 100644 index 00000000000..19a3f861a27 --- /dev/null +++ b/queue-5.15/octeontx2-pf-fix-holes-in-error-code.patch @@ -0,0 +1,156 @@ +From 204d5a962bf783fa75a34291a66bd2bc3b078e4a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Oct 2023 07:49:53 +0530 +Subject: octeontx2-pf: Fix holes in error code + +From: Ratheesh Kannoth + +[ Upstream commit 7aeeb2cb7a2570bb69a87ad14018b03e06ce5be5 ] + +Error code strings are not getting printed properly +due to holes. Print error code as well. + +Fixes: 51afe9026d0c ("octeontx2-pf: NIX TX overwrites SQ_CTX_HW_S[SQ_INT]") +Signed-off-by: Ratheesh Kannoth +Reviewed-by: Wojciech Drewek +Link: https://lore.kernel.org/r/20231027021953.1819959-2-rkannoth@marvell.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../ethernet/marvell/octeontx2/nic/otx2_pf.c | 80 +++++++++++-------- + 1 file changed, 46 insertions(+), 34 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +index 8fc4ecc4f7140..a718d42daeb5e 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +@@ -1180,31 +1180,32 @@ static char *nix_mnqerr_e_str[NIX_MNQERR_MAX] = { + }; + + static char *nix_snd_status_e_str[NIX_SND_STATUS_MAX] = { +- "NIX_SND_STATUS_GOOD", +- "NIX_SND_STATUS_SQ_CTX_FAULT", +- "NIX_SND_STATUS_SQ_CTX_POISON", +- "NIX_SND_STATUS_SQB_FAULT", +- "NIX_SND_STATUS_SQB_POISON", +- "NIX_SND_STATUS_HDR_ERR", +- "NIX_SND_STATUS_EXT_ERR", +- "NIX_SND_STATUS_JUMP_FAULT", +- "NIX_SND_STATUS_JUMP_POISON", +- "NIX_SND_STATUS_CRC_ERR", +- "NIX_SND_STATUS_IMM_ERR", +- "NIX_SND_STATUS_SG_ERR", +- "NIX_SND_STATUS_MEM_ERR", +- "NIX_SND_STATUS_INVALID_SUBDC", +- "NIX_SND_STATUS_SUBDC_ORDER_ERR", +- "NIX_SND_STATUS_DATA_FAULT", +- "NIX_SND_STATUS_DATA_POISON", +- "NIX_SND_STATUS_NPC_DROP_ACTION", +- "NIX_SND_STATUS_LOCK_VIOL", +- "NIX_SND_STATUS_NPC_UCAST_CHAN_ERR", +- "NIX_SND_STATUS_NPC_MCAST_CHAN_ERR", +- "NIX_SND_STATUS_NPC_MCAST_ABORT", +- "NIX_SND_STATUS_NPC_VTAG_PTR_ERR", +- "NIX_SND_STATUS_NPC_VTAG_SIZE_ERR", +- "NIX_SND_STATUS_SEND_STATS_ERR", ++ [NIX_SND_STATUS_GOOD] = "NIX_SND_STATUS_GOOD", ++ [NIX_SND_STATUS_SQ_CTX_FAULT] = "NIX_SND_STATUS_SQ_CTX_FAULT", ++ [NIX_SND_STATUS_SQ_CTX_POISON] = "NIX_SND_STATUS_SQ_CTX_POISON", ++ [NIX_SND_STATUS_SQB_FAULT] = "NIX_SND_STATUS_SQB_FAULT", ++ [NIX_SND_STATUS_SQB_POISON] = "NIX_SND_STATUS_SQB_POISON", ++ [NIX_SND_STATUS_HDR_ERR] = "NIX_SND_STATUS_HDR_ERR", ++ [NIX_SND_STATUS_EXT_ERR] = "NIX_SND_STATUS_EXT_ERR", ++ [NIX_SND_STATUS_JUMP_FAULT] = "NIX_SND_STATUS_JUMP_FAULT", ++ [NIX_SND_STATUS_JUMP_POISON] = "NIX_SND_STATUS_JUMP_POISON", ++ [NIX_SND_STATUS_CRC_ERR] = "NIX_SND_STATUS_CRC_ERR", ++ [NIX_SND_STATUS_IMM_ERR] = "NIX_SND_STATUS_IMM_ERR", ++ [NIX_SND_STATUS_SG_ERR] = "NIX_SND_STATUS_SG_ERR", ++ [NIX_SND_STATUS_MEM_ERR] = "NIX_SND_STATUS_MEM_ERR", ++ [NIX_SND_STATUS_INVALID_SUBDC] = "NIX_SND_STATUS_INVALID_SUBDC", ++ [NIX_SND_STATUS_SUBDC_ORDER_ERR] = "NIX_SND_STATUS_SUBDC_ORDER_ERR", ++ [NIX_SND_STATUS_DATA_FAULT] = "NIX_SND_STATUS_DATA_FAULT", ++ [NIX_SND_STATUS_DATA_POISON] = "NIX_SND_STATUS_DATA_POISON", ++ [NIX_SND_STATUS_NPC_DROP_ACTION] = "NIX_SND_STATUS_NPC_DROP_ACTION", ++ [NIX_SND_STATUS_LOCK_VIOL] = "NIX_SND_STATUS_LOCK_VIOL", ++ [NIX_SND_STATUS_NPC_UCAST_CHAN_ERR] = "NIX_SND_STAT_NPC_UCAST_CHAN_ERR", ++ [NIX_SND_STATUS_NPC_MCAST_CHAN_ERR] = "NIX_SND_STAT_NPC_MCAST_CHAN_ERR", ++ [NIX_SND_STATUS_NPC_MCAST_ABORT] = "NIX_SND_STATUS_NPC_MCAST_ABORT", ++ [NIX_SND_STATUS_NPC_VTAG_PTR_ERR] = "NIX_SND_STATUS_NPC_VTAG_PTR_ERR", ++ [NIX_SND_STATUS_NPC_VTAG_SIZE_ERR] = "NIX_SND_STATUS_NPC_VTAG_SIZE_ERR", ++ [NIX_SND_STATUS_SEND_MEM_FAULT] = "NIX_SND_STATUS_SEND_MEM_FAULT", ++ [NIX_SND_STATUS_SEND_STATS_ERR] = "NIX_SND_STATUS_SEND_STATS_ERR", + }; + + static irqreturn_t otx2_q_intr_handler(int irq, void *data) +@@ -1224,14 +1225,16 @@ static irqreturn_t otx2_q_intr_handler(int irq, void *data) + continue; + + if (val & BIT_ULL(42)) { +- netdev_err(pf->netdev, "CQ%lld: error reading NIX_LF_CQ_OP_INT, NIX_LF_ERR_INT 0x%llx\n", ++ netdev_err(pf->netdev, ++ "CQ%lld: error reading NIX_LF_CQ_OP_INT, NIX_LF_ERR_INT 0x%llx\n", + qidx, otx2_read64(pf, NIX_LF_ERR_INT)); + } else { + if (val & BIT_ULL(NIX_CQERRINT_DOOR_ERR)) + netdev_err(pf->netdev, "CQ%lld: Doorbell error", + qidx); + if (val & BIT_ULL(NIX_CQERRINT_CQE_FAULT)) +- netdev_err(pf->netdev, "CQ%lld: Memory fault on CQE write to LLC/DRAM", ++ netdev_err(pf->netdev, ++ "CQ%lld: Memory fault on CQE write to LLC/DRAM", + qidx); + } + +@@ -1254,7 +1257,8 @@ static irqreturn_t otx2_q_intr_handler(int irq, void *data) + (val & NIX_SQINT_BITS)); + + if (val & BIT_ULL(42)) { +- netdev_err(pf->netdev, "SQ%lld: error reading NIX_LF_SQ_OP_INT, NIX_LF_ERR_INT 0x%llx\n", ++ netdev_err(pf->netdev, ++ "SQ%lld: error reading NIX_LF_SQ_OP_INT, NIX_LF_ERR_INT 0x%llx\n", + qidx, otx2_read64(pf, NIX_LF_ERR_INT)); + goto done; + } +@@ -1264,8 +1268,11 @@ static irqreturn_t otx2_q_intr_handler(int irq, void *data) + goto chk_mnq_err_dbg; + + sq_op_err_code = FIELD_GET(GENMASK(7, 0), sq_op_err_dbg); +- netdev_err(pf->netdev, "SQ%lld: NIX_LF_SQ_OP_ERR_DBG(%llx) err=%s\n", +- qidx, sq_op_err_dbg, nix_sqoperr_e_str[sq_op_err_code]); ++ netdev_err(pf->netdev, ++ "SQ%lld: NIX_LF_SQ_OP_ERR_DBG(0x%llx) err=%s(%#x)\n", ++ qidx, sq_op_err_dbg, ++ nix_sqoperr_e_str[sq_op_err_code], ++ sq_op_err_code); + + otx2_write64(pf, NIX_LF_SQ_OP_ERR_DBG, BIT_ULL(44)); + +@@ -1282,16 +1289,21 @@ static irqreturn_t otx2_q_intr_handler(int irq, void *data) + goto chk_snd_err_dbg; + + mnq_err_code = FIELD_GET(GENMASK(7, 0), mnq_err_dbg); +- netdev_err(pf->netdev, "SQ%lld: NIX_LF_MNQ_ERR_DBG(%llx) err=%s\n", +- qidx, mnq_err_dbg, nix_mnqerr_e_str[mnq_err_code]); ++ netdev_err(pf->netdev, ++ "SQ%lld: NIX_LF_MNQ_ERR_DBG(0x%llx) err=%s(%#x)\n", ++ qidx, mnq_err_dbg, nix_mnqerr_e_str[mnq_err_code], ++ mnq_err_code); + otx2_write64(pf, NIX_LF_MNQ_ERR_DBG, BIT_ULL(44)); + + chk_snd_err_dbg: + snd_err_dbg = otx2_read64(pf, NIX_LF_SEND_ERR_DBG); + if (snd_err_dbg & BIT(44)) { + snd_err_code = FIELD_GET(GENMASK(7, 0), snd_err_dbg); +- netdev_err(pf->netdev, "SQ%lld: NIX_LF_SND_ERR_DBG:0x%llx err=%s\n", +- qidx, snd_err_dbg, nix_snd_status_e_str[snd_err_code]); ++ netdev_err(pf->netdev, ++ "SQ%lld: NIX_LF_SND_ERR_DBG:0x%llx err=%s(%#x)\n", ++ qidx, snd_err_dbg, ++ nix_snd_status_e_str[snd_err_code], ++ snd_err_code); + otx2_write64(pf, NIX_LF_SEND_ERR_DBG, BIT_ULL(44)); + } + +-- +2.42.0 + diff --git a/queue-5.15/pwm-brcmstb-utilize-appropriate-clock-apis-in-suspen.patch b/queue-5.15/pwm-brcmstb-utilize-appropriate-clock-apis-in-suspen.patch new file mode 100644 index 00000000000..8e2eaace563 --- /dev/null +++ b/queue-5.15/pwm-brcmstb-utilize-appropriate-clock-apis-in-suspen.patch @@ -0,0 +1,51 @@ +From 09de7c1bd9eb48274f536020fba45ec37e902585 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 10:54:14 -0700 +Subject: pwm: brcmstb: Utilize appropriate clock APIs in suspend/resume +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Florian Fainelli + +[ Upstream commit e9bc4411548aaa738905d37851a0146c16b3bb21 ] + +The suspend/resume functions currently utilize +clk_disable()/clk_enable() respectively which may be no-ops with certain +clock providers such as SCMI. Fix this to use clk_disable_unprepare() +and clk_prepare_enable() respectively as we should. + +Fixes: 3a9f5957020f ("pwm: Add Broadcom BCM7038 PWM controller support") +Signed-off-by: Florian Fainelli +Acked-by: Uwe Kleine-König +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + drivers/pwm/pwm-brcmstb.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/pwm/pwm-brcmstb.c b/drivers/pwm/pwm-brcmstb.c +index 3b529f82b97c9..202e2d013685f 100644 +--- a/drivers/pwm/pwm-brcmstb.c ++++ b/drivers/pwm/pwm-brcmstb.c +@@ -294,7 +294,7 @@ static int brcmstb_pwm_suspend(struct device *dev) + { + struct brcmstb_pwm *p = dev_get_drvdata(dev); + +- clk_disable(p->clk); ++ clk_disable_unprepare(p->clk); + + return 0; + } +@@ -303,7 +303,7 @@ static int brcmstb_pwm_resume(struct device *dev) + { + struct brcmstb_pwm *p = dev_get_drvdata(dev); + +- clk_enable(p->clk); ++ clk_prepare_enable(p->clk); + + return 0; + } +-- +2.42.0 + diff --git a/queue-5.15/pwm-sti-reduce-number-of-allocations-and-drop-usage-.patch b/queue-5.15/pwm-sti-reduce-number-of-allocations-and-drop-usage-.patch new file mode 100644 index 00000000000..5e361553ad1 --- /dev/null +++ b/queue-5.15/pwm-sti-reduce-number-of-allocations-and-drop-usage-.patch @@ -0,0 +1,115 @@ +From 2c3ecb4b7dce779a79a6a050bc52f829fd37ffde Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Jul 2023 10:06:48 +0200 +Subject: pwm: sti: Reduce number of allocations and drop usage of chip_data +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit 2d6812b41e0d832919d72c72ebddf361df53ba1b ] + +Instead of using one allocation per capture channel, use a single one. Also +store it in driver data instead of chip data. + +This has several advantages: + + - driver data isn't cleared when pwm_put() is called + - Reduces memory fragmentation + +Also register the pwm chip only after the per capture channel data is +initialized as the capture callback relies on this initialization and it +might be called even before pwmchip_add() returns. + +It would be still better to have struct sti_pwm_compat_data and the +per-channel data struct sti_cpt_ddata in a single memory chunk, but that's +not easily possible because the number of capture channels isn't known yet +when the driver data struct is allocated. + +Fixes: e926b12c611c ("pwm: Clear chip_data in pwm_put()") +Reported-by: George Stark +Fixes: c97267ae831d ("pwm: sti: Add PWM capture callback") +Link: https://lore.kernel.org/r/20230705080650.2353391-7-u.kleine-koenig@pengutronix.de +Signed-off-by: Uwe Kleine-König +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + drivers/pwm/pwm-sti.c | 29 ++++++++++++++--------------- + 1 file changed, 14 insertions(+), 15 deletions(-) + +diff --git a/drivers/pwm/pwm-sti.c b/drivers/pwm/pwm-sti.c +index f491d56254d7c..f8a3f30e54dd5 100644 +--- a/drivers/pwm/pwm-sti.c ++++ b/drivers/pwm/pwm-sti.c +@@ -79,6 +79,7 @@ struct sti_pwm_compat_data { + unsigned int cpt_num_devs; + unsigned int max_pwm_cnt; + unsigned int max_prescale; ++ struct sti_cpt_ddata *ddata; + }; + + struct sti_pwm_chip { +@@ -314,7 +315,7 @@ static int sti_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, + { + struct sti_pwm_chip *pc = to_sti_pwmchip(chip); + struct sti_pwm_compat_data *cdata = pc->cdata; +- struct sti_cpt_ddata *ddata = pwm_get_chip_data(pwm); ++ struct sti_cpt_ddata *ddata = &cdata->ddata[pwm->hwpwm]; + struct device *dev = pc->dev; + unsigned int effective_ticks; + unsigned long long high, low; +@@ -417,7 +418,7 @@ static irqreturn_t sti_pwm_interrupt(int irq, void *data) + while (cpt_int_stat) { + devicenum = ffs(cpt_int_stat) - 1; + +- ddata = pwm_get_chip_data(&pc->chip.pwms[devicenum]); ++ ddata = &pc->cdata->ddata[devicenum]; + + /* + * Capture input: +@@ -615,30 +616,28 @@ static int sti_pwm_probe(struct platform_device *pdev) + dev_err(dev, "failed to prepare clock\n"); + return ret; + } ++ ++ cdata->ddata = devm_kzalloc(dev, cdata->cpt_num_devs * sizeof(*cdata->ddata), GFP_KERNEL); ++ if (!cdata->ddata) ++ return -ENOMEM; + } + + pc->chip.dev = dev; + pc->chip.ops = &sti_pwm_ops; + pc->chip.npwm = pc->cdata->pwm_num_devs; + +- ret = pwmchip_add(&pc->chip); +- if (ret < 0) { +- clk_unprepare(pc->pwm_clk); +- clk_unprepare(pc->cpt_clk); +- return ret; +- } +- + for (i = 0; i < cdata->cpt_num_devs; i++) { +- struct sti_cpt_ddata *ddata; +- +- ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); +- if (!ddata) +- return -ENOMEM; ++ struct sti_cpt_ddata *ddata = &cdata->ddata[i]; + + init_waitqueue_head(&ddata->wait); + mutex_init(&ddata->lock); ++ } + +- pwm_set_chip_data(&pc->chip.pwms[i], ddata); ++ ret = pwmchip_add(&pc->chip); ++ if (ret < 0) { ++ clk_unprepare(pc->pwm_clk); ++ clk_unprepare(pc->cpt_clk); ++ return ret; + } + + platform_set_drvdata(pdev, pc); +-- +2.42.0 + diff --git a/queue-5.15/r8169-respect-userspace-disabling-iff_multicast.patch b/queue-5.15/r8169-respect-userspace-disabling-iff_multicast.patch new file mode 100644 index 00000000000..cac1d1c1c9b --- /dev/null +++ b/queue-5.15/r8169-respect-userspace-disabling-iff_multicast.patch @@ -0,0 +1,42 @@ +From e3b0a1420a773019dc79a346c9625353e3179658 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 5 Nov 2023 23:43:36 +0100 +Subject: r8169: respect userspace disabling IFF_MULTICAST + +From: Heiner Kallweit + +[ Upstream commit 8999ce4cfc87e61b4143ec2e7b93d8e92e11fa7f ] + +So far we ignore the setting of IFF_MULTICAST. Fix this and clear bit +AcceptMulticast if IFF_MULTICAST isn't set. + +Note: Based on the implementations I've seen it doesn't seem to be 100% clear +what a driver is supposed to do if IFF_ALLMULTI is set but IFF_MULTICAST +is not. This patch is based on the understanding that IFF_MULTICAST has +precedence. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Heiner Kallweit +Link: https://lore.kernel.org/r/4a57ba02-d52d-4369-9f14-3565e6c1f7dc@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/realtek/r8169_main.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c +index 2e555eda19a85..4cb2510f6fac6 100644 +--- a/drivers/net/ethernet/realtek/r8169_main.c ++++ b/drivers/net/ethernet/realtek/r8169_main.c +@@ -2549,6 +2549,8 @@ static void rtl_set_rx_mode(struct net_device *dev) + + if (dev->flags & IFF_PROMISC) { + rx_mode |= AcceptAllPhys; ++ } else if (!(dev->flags & IFF_MULTICAST)) { ++ rx_mode &= ~AcceptMulticast; + } else if (netdev_mc_count(dev) > MC_FILTER_LIMIT || + dev->flags & IFF_ALLMULTI || + tp->mac_version == RTL_GIGA_MAC_VER_35 || +-- +2.42.0 + diff --git a/queue-5.15/selftests-pmtu.sh-fix-result-checking.patch b/queue-5.15/selftests-pmtu.sh-fix-result-checking.patch new file mode 100644 index 00000000000..c6addb8776d --- /dev/null +++ b/queue-5.15/selftests-pmtu.sh-fix-result-checking.patch @@ -0,0 +1,41 @@ +From 087b0164c56ca61b65c406a12dbeed028a822b18 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 31 Oct 2023 11:47:32 +0800 +Subject: selftests: pmtu.sh: fix result checking + +From: Hangbin Liu + +[ Upstream commit 63e201916b27260218e528a2f8758be47f99bbf4 ] + +In the PMTU test, when all previous tests are skipped and the new test +passes, the exit code is set to 0. However, the current check mistakenly +treats this as an assignment, causing the check to pass every time. + +Consequently, regardless of how many tests have failed, if the latest test +passes, the PMTU test will report a pass. + +Fixes: 2a9d3716b810 ("selftests: pmtu.sh: improve the test result processing") +Signed-off-by: Hangbin Liu +Acked-by: Po-Hsu Lin +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/pmtu.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh +index da6ab300207c0..0a9d482c50589 100755 +--- a/tools/testing/selftests/net/pmtu.sh ++++ b/tools/testing/selftests/net/pmtu.sh +@@ -1880,7 +1880,7 @@ run_test() { + case $ret in + 0) + all_skipped=false +- [ $exitcode=$ksft_skip ] && exitcode=0 ++ [ $exitcode -eq $ksft_skip ] && exitcode=0 + ;; + $ksft_skip) + [ $all_skipped = true ] && exitcode=$ksft_skip +-- +2.42.0 + diff --git a/queue-5.15/series b/queue-5.15/series index bd3d5101837..ab90ac51c75 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -229,3 +229,30 @@ media-v4l-async-rename-async-nf-functions-clean-up-l.patch media-cadence-csi2rx-unregister-v4l2-async-notifier.patch media-dvb-usb-v2-af9035-fix-missing-unlock.patch regmap-prevent-noinc-writes-from-clobbering-cache.patch +pwm-sti-reduce-number-of-allocations-and-drop-usage-.patch +pwm-brcmstb-utilize-appropriate-clock-apis-in-suspen.patch +input-synaptics-rmi4-fix-use-after-free-in-rmi_unreg.patch +llc-verify-mac-len-before-reading-mac-header.patch +hsr-prevent-use-after-free-in-prp_create_tagged_fram.patch +tipc-change-nla_policy-for-bearer-related-names-to-n.patch +bpf-check-map-usercnt-after-timer-timer-is-assigned.patch +inet-shrink-struct-flowi_common.patch +octeontx2-pf-fix-error-codes.patch +octeontx2-pf-fix-holes-in-error-code.patch +dccp-call-security_inet_conn_request-after-setting-i.patch +dccp-tcp-call-security_inet_conn_request-after-setti.patch +net-r8169-disable-multicast-filter-for-rtl8168h-and-.patch +fix-termination-state-for-idr_for_each_entry_ul.patch +net-stmmac-xgmac-enable-support-for-multiple-flexibl.patch +selftests-pmtu.sh-fix-result-checking.patch +net-smc-fix-dangling-sock-under-state-smc_appfinclos.patch +net-smc-allow-cdc-msg-send-rather-than-drop-it-with-.patch +net-smc-put-sk-reference-if-close-work-was-canceled.patch +tg3-power-down-device-only-on-system_power_off.patch +block-remove-unneeded-return-value-of-bio_check_ro.patch +blk-core-use-pr_warn_ratelimited-in-bio_check_ro.patch +r8169-respect-userspace-disabling-iff_multicast.patch +i2c-iproc-handle-invalid-slave-state.patch +netfilter-xt_recent-fix-increase-ipv6-literal-buffer.patch +netfilter-nft_redir-use-struct-nf_nat_range2-through.patch +netfilter-nat-fix-ipv6-nat-redirect-with-mapped-and-.patch diff --git a/queue-5.15/tg3-power-down-device-only-on-system_power_off.patch b/queue-5.15/tg3-power-down-device-only-on-system_power_off.patch new file mode 100644 index 00000000000..d718aa1e7fb --- /dev/null +++ b/queue-5.15/tg3-power-down-device-only-on-system_power_off.patch @@ -0,0 +1,46 @@ +From afd21bac9d9d4fad44ffdad8b46f324fe4a172d5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Nov 2023 13:50:29 +0200 +Subject: tg3: power down device only on SYSTEM_POWER_OFF + +From: George Shuklin + +[ Upstream commit 9fc3bc7643341dc5be7d269f3d3dbe441d8d7ac3 ] + +Dell R650xs servers hangs on reboot if tg3 driver calls +tg3_power_down. + +This happens only if network adapters (BCM5720 for R650xs) were +initialized using SNP (e.g. by booting ipxe.efi). + +The actual problem is on Dell side, but this fix allows servers +to come back alive after reboot. + +Signed-off-by: George Shuklin +Fixes: 2ca1c94ce0b6 ("tg3: Disable tg3 device on system reboot to avoid triggering AER") +Reviewed-by: Pavan Chebbi +Reviewed-by: Michael Chan +Link: https://lore.kernel.org/r/20231103115029.83273-1-george.shuklin@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/tg3.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c +index 70b1a855273e4..2c41852a082bb 100644 +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -18088,7 +18088,8 @@ static void tg3_shutdown(struct pci_dev *pdev) + if (netif_running(dev)) + dev_close(dev); + +- tg3_power_down(tp); ++ if (system_state == SYSTEM_POWER_OFF) ++ tg3_power_down(tp); + + rtnl_unlock(); + +-- +2.42.0 + diff --git a/queue-5.15/tipc-change-nla_policy-for-bearer-related-names-to-n.patch b/queue-5.15/tipc-change-nla_policy-for-bearer-related-names-to-n.patch new file mode 100644 index 00000000000..a394adbee06 --- /dev/null +++ b/queue-5.15/tipc-change-nla_policy-for-bearer-related-names-to-n.patch @@ -0,0 +1,111 @@ +From fe962fdc0563462b64ff2919bc2b290c310cc108 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Oct 2023 16:55:40 +0900 +Subject: tipc: Change nla_policy for bearer-related names to NLA_NUL_STRING + +From: Shigeru Yoshida + +[ Upstream commit 19b3f72a41a8751e26bffc093bb7e1cef29ad579 ] + +syzbot reported the following uninit-value access issue [1]: + +===================================================== +BUG: KMSAN: uninit-value in strlen lib/string.c:418 [inline] +BUG: KMSAN: uninit-value in strstr+0xb8/0x2f0 lib/string.c:756 + strlen lib/string.c:418 [inline] + strstr+0xb8/0x2f0 lib/string.c:756 + tipc_nl_node_reset_link_stats+0x3ea/0xb50 net/tipc/node.c:2595 + genl_family_rcv_msg_doit net/netlink/genetlink.c:971 [inline] + genl_family_rcv_msg net/netlink/genetlink.c:1051 [inline] + genl_rcv_msg+0x11ec/0x1290 net/netlink/genetlink.c:1066 + netlink_rcv_skb+0x371/0x650 net/netlink/af_netlink.c:2545 + genl_rcv+0x40/0x60 net/netlink/genetlink.c:1075 + netlink_unicast_kernel net/netlink/af_netlink.c:1342 [inline] + netlink_unicast+0xf47/0x1250 net/netlink/af_netlink.c:1368 + netlink_sendmsg+0x1238/0x13d0 net/netlink/af_netlink.c:1910 + sock_sendmsg_nosec net/socket.c:730 [inline] + sock_sendmsg net/socket.c:753 [inline] + ____sys_sendmsg+0x9c2/0xd60 net/socket.c:2541 + ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2595 + __sys_sendmsg net/socket.c:2624 [inline] + __do_sys_sendmsg net/socket.c:2633 [inline] + __se_sys_sendmsg net/socket.c:2631 [inline] + __x64_sys_sendmsg+0x307/0x490 net/socket.c:2631 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x63/0xcd + +Uninit was created at: + slab_post_alloc_hook+0x12f/0xb70 mm/slab.h:767 + slab_alloc_node mm/slub.c:3478 [inline] + kmem_cache_alloc_node+0x577/0xa80 mm/slub.c:3523 + kmalloc_reserve+0x13d/0x4a0 net/core/skbuff.c:559 + __alloc_skb+0x318/0x740 net/core/skbuff.c:650 + alloc_skb include/linux/skbuff.h:1286 [inline] + netlink_alloc_large_skb net/netlink/af_netlink.c:1214 [inline] + netlink_sendmsg+0xb34/0x13d0 net/netlink/af_netlink.c:1885 + sock_sendmsg_nosec net/socket.c:730 [inline] + sock_sendmsg net/socket.c:753 [inline] + ____sys_sendmsg+0x9c2/0xd60 net/socket.c:2541 + ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2595 + __sys_sendmsg net/socket.c:2624 [inline] + __do_sys_sendmsg net/socket.c:2633 [inline] + __se_sys_sendmsg net/socket.c:2631 [inline] + __x64_sys_sendmsg+0x307/0x490 net/socket.c:2631 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x63/0xcd + +TIPC bearer-related names including link names must be null-terminated +strings. If a link name which is not null-terminated is passed through +netlink, strstr() and similar functions can cause buffer overrun. This +causes the above issue. + +This patch changes the nla_policy for bearer-related names from NLA_STRING +to NLA_NUL_STRING. This resolves the issue by ensuring that only +null-terminated strings are accepted as bearer-related names. + +syzbot reported similar uninit-value issue related to bearer names [2]. The +root cause of this issue is that a non-null-terminated bearer name was +passed. This patch also resolved this issue. + +Fixes: 7be57fc69184 ("tipc: add link get/dump to new netlink api") +Fixes: 0655f6a8635b ("tipc: add bearer disable/enable to new netlink api") +Reported-and-tested-by: syzbot+5138ca807af9d2b42574@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=5138ca807af9d2b42574 [1] +Reported-and-tested-by: syzbot+9425c47dccbcb4c17d51@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=9425c47dccbcb4c17d51 [2] +Signed-off-by: Shigeru Yoshida +Reviewed-by: Jiri Pirko +Link: https://lore.kernel.org/r/20231030075540.3784537-1-syoshida@redhat.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/tipc/netlink.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c +index c447cb5f879e7..f10ed873858f8 100644 +--- a/net/tipc/netlink.c ++++ b/net/tipc/netlink.c +@@ -88,7 +88,7 @@ const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = { + + const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = { + [TIPC_NLA_LINK_UNSPEC] = { .type = NLA_UNSPEC }, +- [TIPC_NLA_LINK_NAME] = { .type = NLA_STRING, ++ [TIPC_NLA_LINK_NAME] = { .type = NLA_NUL_STRING, + .len = TIPC_MAX_LINK_NAME }, + [TIPC_NLA_LINK_MTU] = { .type = NLA_U32 }, + [TIPC_NLA_LINK_BROADCAST] = { .type = NLA_FLAG }, +@@ -125,7 +125,7 @@ const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = { + + const struct nla_policy tipc_nl_bearer_policy[TIPC_NLA_BEARER_MAX + 1] = { + [TIPC_NLA_BEARER_UNSPEC] = { .type = NLA_UNSPEC }, +- [TIPC_NLA_BEARER_NAME] = { .type = NLA_STRING, ++ [TIPC_NLA_BEARER_NAME] = { .type = NLA_NUL_STRING, + .len = TIPC_MAX_BEARER_NAME }, + [TIPC_NLA_BEARER_PROP] = { .type = NLA_NESTED }, + [TIPC_NLA_BEARER_DOMAIN] = { .type = NLA_U32 } +-- +2.42.0 +