]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.1
authorSasha Levin <sashal@kernel.org>
Fri, 27 Dec 2024 15:06:15 +0000 (10:06 -0500)
committerSasha Levin <sashal@kernel.org>
Fri, 27 Dec 2024 15:06:15 +0000 (10:06 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-6.1/bpf-check-negative-offsets-in-__bpf_skb_min_len.patch [new file with mode: 0644]
queue-6.1/media-dvb-frontends-dib3000mb-fix-uninit-value-in-di.patch [new file with mode: 0644]
queue-6.1/mm-vmstat-fix-a-w-1-clang-compiler-warning.patch [new file with mode: 0644]
queue-6.1/nfsd-restore-callback-functionality-for-nfsv4.0.patch [new file with mode: 0644]
queue-6.1/series [new file with mode: 0644]
queue-6.1/tcp_bpf-add-sk_rmem_alloc-related-logic-for-tcp_bpf-.patch [new file with mode: 0644]
queue-6.1/tcp_bpf-charge-receive-socket-buffer-in-bpf_tcp_ingr.patch [new file with mode: 0644]

diff --git a/queue-6.1/bpf-check-negative-offsets-in-__bpf_skb_min_len.patch b/queue-6.1/bpf-check-negative-offsets-in-__bpf_skb_min_len.patch
new file mode 100644 (file)
index 0000000..190c93c
--- /dev/null
@@ -0,0 +1,66 @@
+From ce9d5d927f96ab11cb6a29974c3fe02fe782dac9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Dec 2024 19:40:54 -0800
+Subject: bpf: Check negative offsets in __bpf_skb_min_len()
+
+From: Cong Wang <cong.wang@bytedance.com>
+
+[ Upstream commit 9ecc4d858b92c1bb0673ad9c327298e600c55659 ]
+
+skb_network_offset() and skb_transport_offset() can be negative when
+they are called after we pull the transport header, for example, when
+we use eBPF sockmap at the point of ->sk_data_ready().
+
+__bpf_skb_min_len() uses an unsigned int to get these offsets, this
+leads to a very large number which then causes bpf_skb_change_tail()
+failed unexpectedly.
+
+Fix this by using a signed int to get these offsets and ensure the
+minimum is at least zero.
+
+Fixes: 5293efe62df8 ("bpf: add bpf_skb_change_tail helper")
+Signed-off-by: Cong Wang <cong.wang@bytedance.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/bpf/20241213034057.246437-2-xiyou.wangcong@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/filter.c | 21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 34cefd85aaf6..cf87e29a5e8f 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -3695,13 +3695,22 @@ static const struct bpf_func_proto bpf_skb_adjust_room_proto = {
+ static u32 __bpf_skb_min_len(const struct sk_buff *skb)
+ {
+-      u32 min_len = skb_network_offset(skb);
++      int offset = skb_network_offset(skb);
++      u32 min_len = 0;
+-      if (skb_transport_header_was_set(skb))
+-              min_len = skb_transport_offset(skb);
+-      if (skb->ip_summed == CHECKSUM_PARTIAL)
+-              min_len = skb_checksum_start_offset(skb) +
+-                        skb->csum_offset + sizeof(__sum16);
++      if (offset > 0)
++              min_len = offset;
++      if (skb_transport_header_was_set(skb)) {
++              offset = skb_transport_offset(skb);
++              if (offset > 0)
++                      min_len = offset;
++      }
++      if (skb->ip_summed == CHECKSUM_PARTIAL) {
++              offset = skb_checksum_start_offset(skb) +
++                       skb->csum_offset + sizeof(__sum16);
++              if (offset > 0)
++                      min_len = offset;
++      }
+       return min_len;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.1/media-dvb-frontends-dib3000mb-fix-uninit-value-in-di.patch b/queue-6.1/media-dvb-frontends-dib3000mb-fix-uninit-value-in-di.patch
new file mode 100644 (file)
index 0000000..9760cd9
--- /dev/null
@@ -0,0 +1,62 @@
+From 41e293bf01ac6a094e59d0b76711c617f6b1b43f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 May 2024 08:58:00 -0700
+Subject: media: dvb-frontends: dib3000mb: fix uninit-value in
+ dib3000_write_reg
+
+From: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+
+[ Upstream commit 2dd59fe0e19e1ab955259978082b62e5751924c7 ]
+
+Syzbot reports [1] an uninitialized value issue found by KMSAN in
+dib3000_read_reg().
+
+Local u8 rb[2] is used in i2c_transfer() as a read buffer; in case
+that call fails, the buffer may end up with some undefined values.
+
+Since no elaborate error handling is expected in dib3000_write_reg(),
+simply zero out rb buffer to mitigate the problem.
+
+[1] Syzkaller report
+dvb-usb: bulk message failed: -22 (6/0)
+=====================================================
+BUG: KMSAN: uninit-value in dib3000mb_attach+0x2d8/0x3c0 drivers/media/dvb-frontends/dib3000mb.c:758
+ dib3000mb_attach+0x2d8/0x3c0 drivers/media/dvb-frontends/dib3000mb.c:758
+ dibusb_dib3000mb_frontend_attach+0x155/0x2f0 drivers/media/usb/dvb-usb/dibusb-mb.c:31
+ dvb_usb_adapter_frontend_init+0xed/0x9a0 drivers/media/usb/dvb-usb/dvb-usb-dvb.c:290
+ dvb_usb_adapter_init drivers/media/usb/dvb-usb/dvb-usb-init.c:90 [inline]
+ dvb_usb_init drivers/media/usb/dvb-usb/dvb-usb-init.c:186 [inline]
+ dvb_usb_device_init+0x25a8/0x3760 drivers/media/usb/dvb-usb/dvb-usb-init.c:310
+ dibusb_probe+0x46/0x250 drivers/media/usb/dvb-usb/dibusb-mb.c:110
+...
+Local variable rb created at:
+ dib3000_read_reg+0x86/0x4e0 drivers/media/dvb-frontends/dib3000mb.c:54
+ dib3000mb_attach+0x123/0x3c0 drivers/media/dvb-frontends/dib3000mb.c:758
+...
+
+Fixes: 74340b0a8bc6 ("V4L/DVB (4457): Remove dib3000-common-module")
+Reported-by: syzbot+c88fc0ebe0d5935c70da@syzkaller.appspotmail.com
+Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+Link: https://lore.kernel.org/r/20240517155800.9881-1-n.zhandarovich@fintech.ru
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/dvb-frontends/dib3000mb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/dvb-frontends/dib3000mb.c b/drivers/media/dvb-frontends/dib3000mb.c
+index c598b2a63325..7c452ddd9e40 100644
+--- a/drivers/media/dvb-frontends/dib3000mb.c
++++ b/drivers/media/dvb-frontends/dib3000mb.c
+@@ -51,7 +51,7 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-a
+ static int dib3000_read_reg(struct dib3000_state *state, u16 reg)
+ {
+       u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff };
+-      u8 rb[2];
++      u8 rb[2] = {};
+       struct i2c_msg msg[] = {
+               { .addr = state->config.demod_address, .flags = 0,        .buf = wb, .len = 2 },
+               { .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 },
+-- 
+2.39.5
+
diff --git a/queue-6.1/mm-vmstat-fix-a-w-1-clang-compiler-warning.patch b/queue-6.1/mm-vmstat-fix-a-w-1-clang-compiler-warning.patch
new file mode 100644 (file)
index 0000000..b71ab97
--- /dev/null
@@ -0,0 +1,43 @@
+From aaca07b14d682b2a930c32fcbfcc4c6781987de4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Dec 2024 13:31:26 -0800
+Subject: mm/vmstat: fix a W=1 clang compiler warning
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 30c2de0a267c04046d89e678cc0067a9cfb455df ]
+
+Fix the following clang compiler warning that is reported if the kernel is
+built with W=1:
+
+./include/linux/vmstat.h:518:36: error: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Werror,-Wenum-enum-conversion]
+  518 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
+      |                               ~~~~~~~~~~~ ^ ~~~
+
+Link: https://lkml.kernel.org/r/20241212213126.1269116-1-bvanassche@acm.org
+Fixes: 9d7ea9a297e6 ("mm/vmstat: add helpers to get vmstat item names for each enum type")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Cc: Konstantin Khlebnikov <koct9i@gmail.com>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/vmstat.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
+index 19cf5b6892ce..4fb5fa0cc84e 100644
+--- a/include/linux/vmstat.h
++++ b/include/linux/vmstat.h
+@@ -513,7 +513,7 @@ static inline const char *node_stat_name(enum node_stat_item item)
+ static inline const char *lru_list_name(enum lru_list lru)
+ {
+-      return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
++      return node_stat_name(NR_LRU_BASE + (enum node_stat_item)lru) + 3; // skip "nr_"
+ }
+ static inline const char *writeback_stat_name(enum writeback_stat_item item)
+-- 
+2.39.5
+
diff --git a/queue-6.1/nfsd-restore-callback-functionality-for-nfsv4.0.patch b/queue-6.1/nfsd-restore-callback-functionality-for-nfsv4.0.patch
new file mode 100644 (file)
index 0000000..7c1ad6e
--- /dev/null
@@ -0,0 +1,51 @@
+From cfda96e477aae4b80d51ce7972cfcb1d3f3f2c2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Dec 2024 15:28:18 +1100
+Subject: nfsd: restore callback functionality for NFSv4.0
+
+From: NeilBrown <neilb@suse.de>
+
+[ Upstream commit 7917f01a286ce01e9c085e24468421f596ee1a0c ]
+
+A recent patch inadvertently broke callbacks for NFSv4.0.
+
+In the 4.0 case we do not expect a session to be found but still need to
+call setup_callback_client() which will not try to dereference it.
+
+This patch moves the check for failure to find a session into the 4.1+
+branch of setup_callback_client()
+
+Fixes: 1e02c641c3a4 ("NFSD: Prevent NULL dereference in nfsd4_process_cb_update()")
+Signed-off-by: NeilBrown <neilb@suse.de>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4callback.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
+index a6dc8c479a4b..d2885dd4822d 100644
+--- a/fs/nfsd/nfs4callback.c
++++ b/fs/nfsd/nfs4callback.c
+@@ -986,7 +986,7 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
+               args.authflavor = clp->cl_cred.cr_flavor;
+               clp->cl_cb_ident = conn->cb_ident;
+       } else {
+-              if (!conn->cb_xprt)
++              if (!conn->cb_xprt || !ses)
+                       return -EINVAL;
+               clp->cl_cb_session = ses;
+               args.bc_xprt = conn->cb_xprt;
+@@ -1379,8 +1379,6 @@ static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
+               ses = c->cn_session;
+       }
+       spin_unlock(&clp->cl_lock);
+-      if (!c)
+-              return;
+       err = setup_callback_client(clp, &conn, ses);
+       if (err) {
+-- 
+2.39.5
+
diff --git a/queue-6.1/series b/queue-6.1/series
new file mode 100644 (file)
index 0000000..165392b
--- /dev/null
@@ -0,0 +1,6 @@
+media-dvb-frontends-dib3000mb-fix-uninit-value-in-di.patch
+mm-vmstat-fix-a-w-1-clang-compiler-warning.patch
+tcp_bpf-charge-receive-socket-buffer-in-bpf_tcp_ingr.patch
+tcp_bpf-add-sk_rmem_alloc-related-logic-for-tcp_bpf-.patch
+bpf-check-negative-offsets-in-__bpf_skb_min_len.patch
+nfsd-restore-callback-functionality-for-nfsv4.0.patch
diff --git a/queue-6.1/tcp_bpf-add-sk_rmem_alloc-related-logic-for-tcp_bpf-.patch b/queue-6.1/tcp_bpf-add-sk_rmem_alloc-related-logic-for-tcp_bpf-.patch
new file mode 100644 (file)
index 0000000..11d011b
--- /dev/null
@@ -0,0 +1,116 @@
+From 063ad6c318960081fbf38421ca3a6ee41c04ee94 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Dec 2024 01:20:39 +0000
+Subject: tcp_bpf: Add sk_rmem_alloc related logic for tcp_bpf ingress
+ redirection
+
+From: Zijian Zhang <zijianzhang@bytedance.com>
+
+[ Upstream commit d888b7af7c149c115dd6ac772cc11c375da3e17c ]
+
+When we do sk_psock_verdict_apply->sk_psock_skb_ingress, an sk_msg will
+be created out of the skb, and the rmem accounting of the sk_msg will be
+handled by the skb.
+
+For skmsgs in __SK_REDIRECT case of tcp_bpf_send_verdict, when redirecting
+to the ingress of a socket, although we sk_rmem_schedule and add sk_msg to
+the ingress_msg of sk_redir, we do not update sk_rmem_alloc. As a result,
+except for the global memory limit, the rmem of sk_redir is nearly
+unlimited. Thus, add sk_rmem_alloc related logic to limit the recv buffer.
+
+Since the function sk_msg_recvmsg and __sk_psock_purge_ingress_msg are
+used in these two paths. We use "msg->skb" to test whether the sk_msg is
+skb backed up. If it's not, we shall do the memory accounting explicitly.
+
+Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface")
+Signed-off-by: Zijian Zhang <zijianzhang@bytedance.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/bpf/20241210012039.1669389-3-zijianzhang@bytedance.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/skmsg.h | 11 ++++++++---
+ net/core/skmsg.c      |  6 +++++-
+ net/ipv4/tcp_bpf.c    |  4 +++-
+ 3 files changed, 16 insertions(+), 5 deletions(-)
+
+diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h
+index 062fe440f5d0..6ccfd9236387 100644
+--- a/include/linux/skmsg.h
++++ b/include/linux/skmsg.h
+@@ -308,17 +308,22 @@ static inline void sock_drop(struct sock *sk, struct sk_buff *skb)
+       kfree_skb(skb);
+ }
+-static inline void sk_psock_queue_msg(struct sk_psock *psock,
++static inline bool sk_psock_queue_msg(struct sk_psock *psock,
+                                     struct sk_msg *msg)
+ {
++      bool ret;
++
+       spin_lock_bh(&psock->ingress_lock);
+-      if (sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED))
++      if (sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED)) {
+               list_add_tail(&msg->list, &psock->ingress_msg);
+-      else {
++              ret = true;
++      } else {
+               sk_msg_free(psock->sk, msg);
+               kfree(msg);
++              ret = false;
+       }
+       spin_unlock_bh(&psock->ingress_lock);
++      return ret;
+ }
+ static inline struct sk_msg *sk_psock_dequeue_msg(struct sk_psock *psock)
+diff --git a/net/core/skmsg.c b/net/core/skmsg.c
+index 584516387fda..65764952bc68 100644
+--- a/net/core/skmsg.c
++++ b/net/core/skmsg.c
+@@ -444,8 +444,10 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
+                       if (likely(!peek)) {
+                               sge->offset += copy;
+                               sge->length -= copy;
+-                              if (!msg_rx->skb)
++                              if (!msg_rx->skb) {
+                                       sk_mem_uncharge(sk, copy);
++                                      atomic_sub(copy, &sk->sk_rmem_alloc);
++                              }
+                               msg_rx->sg.size -= copy;
+                               if (!sge->length) {
+@@ -771,6 +773,8 @@ static void __sk_psock_purge_ingress_msg(struct sk_psock *psock)
+       list_for_each_entry_safe(msg, tmp, &psock->ingress_msg, list) {
+               list_del(&msg->list);
++              if (!msg->skb)
++                      atomic_sub(msg->sg.size, &psock->sk->sk_rmem_alloc);
+               sk_msg_free(psock->sk, msg);
+               kfree(msg);
+       }
+diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
+index cd999c55da99..a8db010e9e61 100644
+--- a/net/ipv4/tcp_bpf.c
++++ b/net/ipv4/tcp_bpf.c
+@@ -56,6 +56,7 @@ static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock,
+               }
+               sk_mem_charge(sk, size);
++              atomic_add(size, &sk->sk_rmem_alloc);
+               sk_msg_xfer(tmp, msg, i, size);
+               copied += size;
+               if (sge->length)
+@@ -74,7 +75,8 @@ static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock,
+       if (!ret) {
+               msg->sg.start = i;
+-              sk_psock_queue_msg(psock, tmp);
++              if (!sk_psock_queue_msg(psock, tmp))
++                      atomic_sub(copied, &sk->sk_rmem_alloc);
+               sk_psock_data_ready(sk, psock);
+       } else {
+               sk_msg_free(sk, tmp);
+-- 
+2.39.5
+
diff --git a/queue-6.1/tcp_bpf-charge-receive-socket-buffer-in-bpf_tcp_ingr.patch b/queue-6.1/tcp_bpf-charge-receive-socket-buffer-in-bpf_tcp_ingr.patch
new file mode 100644 (file)
index 0000000..6bbf589
--- /dev/null
@@ -0,0 +1,71 @@
+From 5a45d6db3d701047a6915296e66f93b075100cff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Dec 2024 01:20:38 +0000
+Subject: tcp_bpf: Charge receive socket buffer in bpf_tcp_ingress()
+
+From: Cong Wang <cong.wang@bytedance.com>
+
+[ Upstream commit 54f89b3178d5448dd4457afbb98fc1ab99090a65 ]
+
+When bpf_tcp_ingress() is called, the skmsg is being redirected to the
+ingress of the destination socket. Therefore, we should charge its
+receive socket buffer, instead of sending socket buffer.
+
+Because sk_rmem_schedule() tests pfmemalloc of skb, we need to
+introduce a wrapper and call it for skmsg.
+
+Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface")
+Signed-off-by: Cong Wang <cong.wang@bytedance.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/bpf/20241210012039.1669389-2-zijianzhang@bytedance.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sock.h | 10 ++++++++--
+ net/ipv4/tcp_bpf.c |  2 +-
+ 2 files changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 0a06c997b45b..e716b2ba00bb 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1660,7 +1660,7 @@ static inline bool sk_wmem_schedule(struct sock *sk, int size)
+ }
+ static inline bool
+-sk_rmem_schedule(struct sock *sk, struct sk_buff *skb, int size)
++__sk_rmem_schedule(struct sock *sk, int size, bool pfmemalloc)
+ {
+       int delta;
+@@ -1668,7 +1668,13 @@ sk_rmem_schedule(struct sock *sk, struct sk_buff *skb, int size)
+               return true;
+       delta = size - sk->sk_forward_alloc;
+       return delta <= 0 || __sk_mem_schedule(sk, delta, SK_MEM_RECV) ||
+-              skb_pfmemalloc(skb);
++             pfmemalloc;
++}
++
++static inline bool
++sk_rmem_schedule(struct sock *sk, struct sk_buff *skb, int size)
++{
++      return __sk_rmem_schedule(sk, size, skb_pfmemalloc(skb));
+ }
+ static inline int sk_unused_reserved_mem(const struct sock *sk)
+diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
+index deb6286b5881..cd999c55da99 100644
+--- a/net/ipv4/tcp_bpf.c
++++ b/net/ipv4/tcp_bpf.c
+@@ -49,7 +49,7 @@ static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock,
+               sge = sk_msg_elem(msg, i);
+               size = (apply && apply_bytes < sge->length) ?
+                       apply_bytes : sge->length;
+-              if (!sk_wmem_schedule(sk, size)) {
++              if (!__sk_rmem_schedule(sk, size, false)) {
+                       if (!copied)
+                               ret = -ENOMEM;
+                       break;
+-- 
+2.39.5
+