]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.4
authorSasha Levin <sashal@kernel.org>
Tue, 10 Dec 2024 02:42:10 +0000 (21:42 -0500)
committerSasha Levin <sashal@kernel.org>
Tue, 10 Dec 2024 02:42:10 +0000 (21:42 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.4/bpf-fix-exact-match-conditions-in-trie_get_next_key.patch [new file with mode: 0644]
queue-5.4/bpf-handle-bpf_exist-and-bpf_noexist-for-lpm-trie.patch [new file with mode: 0644]
queue-5.4/drm-sti-add-__iomem-for-mixer_dbg_mxn-s-parameter.patch [new file with mode: 0644]
queue-5.4/ocfs2-free-inode-when-ocfs2_get_init_inode-fails.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/spi-mpc52xx-add-cancel_work_sync-before-module-remov.patch [new file with mode: 0644]
queue-5.4/tcp_bpf-fix-the-sk_mem_uncharge-logic-in-tcp_bpf_sen.patch [new file with mode: 0644]

diff --git a/queue-5.4/bpf-fix-exact-match-conditions-in-trie_get_next_key.patch b/queue-5.4/bpf-fix-exact-match-conditions-in-trie_get_next_key.patch
new file mode 100644 (file)
index 0000000..d7a101a
--- /dev/null
@@ -0,0 +1,60 @@
+From 1b8f1fcc349e2b64cb57880ddc3aedcbdbbeba43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Dec 2024 19:06:18 +0800
+Subject: bpf: Fix exact match conditions in trie_get_next_key()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Hou Tao <houtao1@huawei.com>
+
+[ Upstream commit 27abc7b3fa2e09bbe41e2924d328121546865eda ]
+
+trie_get_next_key() uses node->prefixlen == key->prefixlen to identify
+an exact match, However, it is incorrect because when the target key
+doesn't fully match the found node (e.g., node->prefixlen != matchlen),
+these two nodes may also have the same prefixlen. It will return
+expected result when the passed key exist in the trie. However when a
+recently-deleted key or nonexistent key is passed to
+trie_get_next_key(), it may skip keys and return incorrect result.
+
+Fix it by using node->prefixlen == matchlen to identify exact matches.
+When the condition is true after the search, it also implies
+node->prefixlen equals key->prefixlen, otherwise, the search would
+return NULL instead.
+
+Fixes: b471f2f1de8b ("bpf: implement MAP_GET_NEXT_KEY command for LPM_TRIE map")
+Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Signed-off-by: Hou Tao <houtao1@huawei.com>
+Link: https://lore.kernel.org/r/20241206110622.1161752-6-houtao@huaweicloud.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/lpm_trie.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c
+index 1f92d531b4466..f726ceb8d7e96 100644
+--- a/kernel/bpf/lpm_trie.c
++++ b/kernel/bpf/lpm_trie.c
+@@ -655,7 +655,7 @@ static int trie_get_next_key(struct bpf_map *map, void *_key, void *_next_key)
+       struct lpm_trie_node **node_stack = NULL;
+       int err = 0, stack_ptr = -1;
+       unsigned int next_bit;
+-      size_t matchlen;
++      size_t matchlen = 0;
+       /* The get_next_key follows postorder. For the 4 node example in
+        * the top of this file, the trie_get_next_key() returns the following
+@@ -694,7 +694,7 @@ static int trie_get_next_key(struct bpf_map *map, void *_key, void *_next_key)
+               next_bit = extract_bit(key->data, node->prefixlen);
+               node = rcu_dereference(node->child[next_bit]);
+       }
+-      if (!node || node->prefixlen != key->prefixlen ||
++      if (!node || node->prefixlen != matchlen ||
+           (node->flags & LPM_TREE_NODE_FLAG_IM))
+               goto find_leftmost;
+-- 
+2.43.0
+
diff --git a/queue-5.4/bpf-handle-bpf_exist-and-bpf_noexist-for-lpm-trie.patch b/queue-5.4/bpf-handle-bpf_exist-and-bpf_noexist-for-lpm-trie.patch
new file mode 100644 (file)
index 0000000..a7b3488
--- /dev/null
@@ -0,0 +1,80 @@
+From 493899b5b617c6a6383b53a0a081587e212a9d0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Dec 2024 19:06:16 +0800
+Subject: bpf: Handle BPF_EXIST and BPF_NOEXIST for LPM trie
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Hou Tao <houtao1@huawei.com>
+
+[ Upstream commit eae6a075e9537dd69891cf77ca5a88fa8a28b4a1 ]
+
+Add the currently missing handling for the BPF_EXIST and BPF_NOEXIST
+flags. These flags can be specified by users and are relevant since LPM
+trie supports exact matches during update.
+
+Fixes: b95a5c4db09b ("bpf: add a longest prefix match trie map implementation")
+Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>
+Signed-off-by: Hou Tao <houtao1@huawei.com>
+Link: https://lore.kernel.org/r/20241206110622.1161752-4-houtao@huaweicloud.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/lpm_trie.c | 23 ++++++++++++++++++++---
+ 1 file changed, 20 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c
+index c372be6df264e..1f92d531b4466 100644
+--- a/kernel/bpf/lpm_trie.c
++++ b/kernel/bpf/lpm_trie.c
+@@ -364,6 +364,10 @@ static int trie_update_elem(struct bpf_map *map,
+        * simply assign the @new_node to that slot and be done.
+        */
+       if (!node) {
++              if (flags == BPF_EXIST) {
++                      ret = -ENOENT;
++                      goto out;
++              }
+               rcu_assign_pointer(*slot, new_node);
+               goto out;
+       }
+@@ -372,18 +376,31 @@ static int trie_update_elem(struct bpf_map *map,
+        * which already has the correct data array set.
+        */
+       if (node->prefixlen == matchlen) {
++              if (!(node->flags & LPM_TREE_NODE_FLAG_IM)) {
++                      if (flags == BPF_NOEXIST) {
++                              ret = -EEXIST;
++                              goto out;
++                      }
++                      trie->n_entries--;
++              } else if (flags == BPF_EXIST) {
++                      ret = -ENOENT;
++                      goto out;
++              }
++
+               new_node->child[0] = node->child[0];
+               new_node->child[1] = node->child[1];
+-              if (!(node->flags & LPM_TREE_NODE_FLAG_IM))
+-                      trie->n_entries--;
+-
+               rcu_assign_pointer(*slot, new_node);
+               kfree_rcu(node, rcu);
+               goto out;
+       }
++      if (flags == BPF_EXIST) {
++              ret = -ENOENT;
++              goto out;
++      }
++
+       /* If the new node matches the prefix completely, it must be inserted
+        * as an ancestor. Simply insert it between @node and *@slot.
+        */
+-- 
+2.43.0
+
diff --git a/queue-5.4/drm-sti-add-__iomem-for-mixer_dbg_mxn-s-parameter.patch b/queue-5.4/drm-sti-add-__iomem-for-mixer_dbg_mxn-s-parameter.patch
new file mode 100644 (file)
index 0000000..19c7e7a
--- /dev/null
@@ -0,0 +1,41 @@
+From 961fe05a233a619d2adfa44b090c313c2b039b1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Nov 2024 15:21:36 +0800
+Subject: drm/sti: Add __iomem for mixer_dbg_mxn's parameter
+
+From: Pei Xiao <xiaopei01@kylinos.cn>
+
+[ Upstream commit 86e8f94789dd6f3e705bfa821e1e416f97a2f863 ]
+
+Sparse complains about incorrect type in argument 1.
+expected void const volatile  __iomem *ptr but got void *.
+so modify mixer_dbg_mxn's addr parameter.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202411191809.6V3c826r-lkp@intel.com/
+Fixes: a5f81078a56c ("drm/sti: add debugfs entries for MIXER crtc")
+Signed-off-by: Pei Xiao <xiaopei01@kylinos.cn>
+Acked-by: Raphael Gallais-Pou <rgallaispou@gmail.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/c28f0dcb6a4526721d83ba1f659bba30564d3d54.1732087094.git.xiaopei01@kylinos.cn
+Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou@foss.st.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/sti/sti_mixer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/sti/sti_mixer.c b/drivers/gpu/drm/sti/sti_mixer.c
+index c3a3e1e5fc8ab..21cbb4d0ee4ac 100644
+--- a/drivers/gpu/drm/sti/sti_mixer.c
++++ b/drivers/gpu/drm/sti/sti_mixer.c
+@@ -137,7 +137,7 @@ static void mixer_dbg_crb(struct seq_file *s, int val)
+       }
+ }
+-static void mixer_dbg_mxn(struct seq_file *s, void *addr)
++static void mixer_dbg_mxn(struct seq_file *s, void __iomem *addr)
+ {
+       int i;
+-- 
+2.43.0
+
diff --git a/queue-5.4/ocfs2-free-inode-when-ocfs2_get_init_inode-fails.patch b/queue-5.4/ocfs2-free-inode-when-ocfs2_get_init_inode-fails.patch
new file mode 100644 (file)
index 0000000..a98ed2e
--- /dev/null
@@ -0,0 +1,50 @@
+From b9a2446ad808c46f4a83ee12fd0e9fb3e70385b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Nov 2024 22:28:34 +0900
+Subject: ocfs2: free inode when ocfs2_get_init_inode() fails
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+[ Upstream commit 965b5dd1894f4525f38c1b5f99b0106a07dbb5db ]
+
+syzbot is reporting busy inodes after unmount, for commit 9c89fe0af826
+("ocfs2: Handle error from dquot_initialize()") forgot to call iput() when
+new_inode() succeeded and dquot_initialize() failed.
+
+Link: https://lkml.kernel.org/r/e68c0224-b7c6-4784-b4fa-a9fc8c675525@I-love.SAKURA.ne.jp
+Fixes: 9c89fe0af826 ("ocfs2: Handle error from dquot_initialize()")
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Reported-by: syzbot+0af00f6a2cba2058b5db@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=0af00f6a2cba2058b5db
+Tested-by: syzbot+0af00f6a2cba2058b5db@syzkaller.appspotmail.com
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Jun Piao <piaojun@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ocfs2/namei.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
+index 34b84eb299e8e..5e87608cb987d 100644
+--- a/fs/ocfs2/namei.c
++++ b/fs/ocfs2/namei.c
+@@ -201,8 +201,10 @@ static struct inode *ocfs2_get_init_inode(struct inode *dir, umode_t mode)
+       mode = mode_strip_sgid(dir, mode);
+       inode_init_owner(inode, dir, mode);
+       status = dquot_initialize(inode);
+-      if (status)
++      if (status) {
++              iput(inode);
+               return ERR_PTR(status);
++      }
+       return inode;
+ }
+-- 
+2.43.0
+
index c1ef19a6f0797f4ad2eac10e6b29de59dbcca8c4..7c4c77f62fa745bbf3da03f4d845b72c701706d7 100644 (file)
@@ -246,3 +246,9 @@ x86-asm-crypto-annotate-local-functions.patch
 crypto-x86-aegis128-access-32-bit-arguments-as-32-bi.patch
 gpio-grgpio-use-a-helper-variable-to-store-the-addre.patch
 gpio-grgpio-add-null-check-in-grgpio_probe.patch
+drm-sti-add-__iomem-for-mixer_dbg_mxn-s-parameter.patch
+tcp_bpf-fix-the-sk_mem_uncharge-logic-in-tcp_bpf_sen.patch
+spi-mpc52xx-add-cancel_work_sync-before-module-remov.patch
+ocfs2-free-inode-when-ocfs2_get_init_inode-fails.patch
+bpf-handle-bpf_exist-and-bpf_noexist-for-lpm-trie.patch
+bpf-fix-exact-match-conditions-in-trie_get_next_key.patch
diff --git a/queue-5.4/spi-mpc52xx-add-cancel_work_sync-before-module-remov.patch b/queue-5.4/spi-mpc52xx-add-cancel_work_sync-before-module-remov.patch
new file mode 100644 (file)
index 0000000..71a39fe
--- /dev/null
@@ -0,0 +1,41 @@
+From ca6eecc34869ecd62ab5a5ee21ce5423a42d58f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Nov 2024 16:38:17 +0800
+Subject: spi: mpc52xx: Add cancel_work_sync before module remove
+
+From: Pei Xiao <xiaopei01@kylinos.cn>
+
+[ Upstream commit 984836621aad98802d92c4a3047114cf518074c8 ]
+
+If we remove the module which will call mpc52xx_spi_remove
+it will free 'ms' through spi_unregister_controller.
+while the work ms->work will be used. The sequence of operations
+that may lead to a UAF bug.
+
+Fix it by ensuring that the work is canceled before proceeding with
+the cleanup in mpc52xx_spi_remove.
+
+Fixes: ca632f556697 ("spi: reorganize drivers")
+Signed-off-by: Pei Xiao <xiaopei01@kylinos.cn>
+Link: https://patch.msgid.link/1f16f8ae0e50ca9adb1dc849bf2ac65a40c9ceb9.1732783000.git.xiaopei01@kylinos.cn
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-mpc52xx.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c
+index ef2f24420460d..be99efafabbce 100644
+--- a/drivers/spi/spi-mpc52xx.c
++++ b/drivers/spi/spi-mpc52xx.c
+@@ -519,6 +519,7 @@ static int mpc52xx_spi_remove(struct platform_device *op)
+       struct mpc52xx_spi *ms = spi_master_get_devdata(master);
+       int i;
++      cancel_work_sync(&ms->work);
+       free_irq(ms->irq0, ms);
+       free_irq(ms->irq1, ms);
+-- 
+2.43.0
+
diff --git a/queue-5.4/tcp_bpf-fix-the-sk_mem_uncharge-logic-in-tcp_bpf_sen.patch b/queue-5.4/tcp_bpf-fix-the-sk_mem_uncharge-logic-in-tcp_bpf_sen.patch
new file mode 100644 (file)
index 0000000..31630d5
--- /dev/null
@@ -0,0 +1,165 @@
+From 98e9d87f19e2f9350c5eafd5464a89e186c064bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Oct 2024 23:48:38 +0000
+Subject: tcp_bpf: Fix the sk_mem_uncharge logic in tcp_bpf_sendmsg
+
+From: Zijian Zhang <zijianzhang@bytedance.com>
+
+[ Upstream commit ca70b8baf2bd125b2a4d96e76db79375c07d7ff2 ]
+
+The current sk memory accounting logic in __SK_REDIRECT is pre-uncharging
+tosend bytes, which is either msg->sg.size or a smaller value apply_bytes.
+
+Potential problems with this strategy are as follows:
+
+- If the actual sent bytes are smaller than tosend, we need to charge some
+  bytes back, as in line 487, which is okay but seems not clean.
+
+- When tosend is set to apply_bytes, as in line 417, and (ret < 0), we may
+  miss uncharging (msg->sg.size - apply_bytes) bytes.
+
+[...]
+415 tosend = msg->sg.size;
+416 if (psock->apply_bytes && psock->apply_bytes < tosend)
+417   tosend = psock->apply_bytes;
+[...]
+443 sk_msg_return(sk, msg, tosend);
+444 release_sock(sk);
+446 origsize = msg->sg.size;
+447 ret = tcp_bpf_sendmsg_redir(sk_redir, redir_ingress,
+448                             msg, tosend, flags);
+449 sent = origsize - msg->sg.size;
+[...]
+454 lock_sock(sk);
+455 if (unlikely(ret < 0)) {
+456   int free = sk_msg_free_nocharge(sk, msg);
+458   if (!cork)
+459     *copied -= free;
+460 }
+[...]
+487 if (eval == __SK_REDIRECT)
+488   sk_mem_charge(sk, tosend - sent);
+[...]
+
+When running the selftest test_txmsg_redir_wait_sndmem with txmsg_apply,
+the following warning will be reported:
+
+------------[ cut here ]------------
+WARNING: CPU: 6 PID: 57 at net/ipv4/af_inet.c:156 inet_sock_destruct+0x190/0x1a0
+Modules linked in:
+CPU: 6 UID: 0 PID: 57 Comm: kworker/6:0 Not tainted 6.12.0-rc1.bm.1-amd64+ #43
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
+Workqueue: events sk_psock_destroy
+RIP: 0010:inet_sock_destruct+0x190/0x1a0
+RSP: 0018:ffffad0a8021fe08 EFLAGS: 00010206
+RAX: 0000000000000011 RBX: ffff9aab4475b900 RCX: ffff9aab481a0800
+RDX: 0000000000000303 RSI: 0000000000000011 RDI: ffff9aab4475b900
+RBP: ffff9aab4475b990 R08: 0000000000000000 R09: ffff9aab40050ec0
+R10: 0000000000000000 R11: ffff9aae6fdb1d01 R12: ffff9aab49c60400
+R13: ffff9aab49c60598 R14: ffff9aab49c60598 R15: dead000000000100
+FS:  0000000000000000(0000) GS:ffff9aae6fd80000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007ffec7e47bd8 CR3: 00000001a1a1c004 CR4: 0000000000770ef0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+PKRU: 55555554
+Call Trace:
+<TASK>
+? __warn+0x89/0x130
+? inet_sock_destruct+0x190/0x1a0
+? report_bug+0xfc/0x1e0
+? handle_bug+0x5c/0xa0
+? exc_invalid_op+0x17/0x70
+? asm_exc_invalid_op+0x1a/0x20
+? inet_sock_destruct+0x190/0x1a0
+__sk_destruct+0x25/0x220
+sk_psock_destroy+0x2b2/0x310
+process_scheduled_works+0xa3/0x3e0
+worker_thread+0x117/0x240
+? __pfx_worker_thread+0x10/0x10
+kthread+0xcf/0x100
+? __pfx_kthread+0x10/0x10
+ret_from_fork+0x31/0x40
+? __pfx_kthread+0x10/0x10
+ret_from_fork_asm+0x1a/0x30
+</TASK>
+---[ end trace 0000000000000000 ]---
+
+In __SK_REDIRECT, a more concise way is delaying the uncharging after sent
+bytes are finalized, and uncharge this value. When (ret < 0), we shall
+invoke sk_msg_free.
+
+Same thing happens in case __SK_DROP, when tosend is set to apply_bytes,
+we may miss uncharging (msg->sg.size - apply_bytes) bytes. The same
+warning will be reported in selftest.
+
+[...]
+468 case __SK_DROP:
+469 default:
+470 sk_msg_free_partial(sk, msg, tosend);
+471 sk_msg_apply_bytes(psock, tosend);
+472 *copied -= (tosend + delta);
+473 return -EACCES;
+[...]
+
+So instead of sk_msg_free_partial we can do sk_msg_free here.
+
+Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface")
+Fixes: 8ec95b94716a ("bpf, sockmap: Fix the sk->sk_forward_alloc warning of sk_stream_kill_queues")
+Signed-off-by: Zijian Zhang <zijianzhang@bytedance.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/bpf/20241016234838.3167769-3-zijianzhang@bytedance.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_bpf.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
+index 0002a6730d2e9..8c1508a2e241a 100644
+--- a/net/ipv4/tcp_bpf.c
++++ b/net/ipv4/tcp_bpf.c
+@@ -370,7 +370,6 @@ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock,
+                       cork = true;
+                       psock->cork = NULL;
+               }
+-              sk_msg_return(sk, msg, tosend);
+               release_sock(sk);
+               origsize = msg->sg.size;
+@@ -381,8 +380,9 @@ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock,
+                       sock_put(sk_redir);
+               lock_sock(sk);
++              sk_mem_uncharge(sk, sent);
+               if (unlikely(ret < 0)) {
+-                      int free = sk_msg_free_nocharge(sk, msg);
++                      int free = sk_msg_free(sk, msg);
+                       if (!cork)
+                               *copied -= free;
+@@ -396,7 +396,7 @@ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock,
+               break;
+       case __SK_DROP:
+       default:
+-              sk_msg_free_partial(sk, msg, tosend);
++              sk_msg_free(sk, msg);
+               sk_msg_apply_bytes(psock, tosend);
+               *copied -= (tosend + delta);
+               return -EACCES;
+@@ -412,11 +412,8 @@ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock,
+               }
+               if (msg &&
+                   msg->sg.data[msg->sg.start].page_link &&
+-                  msg->sg.data[msg->sg.start].length) {
+-                      if (eval == __SK_REDIRECT)
+-                              sk_mem_charge(sk, tosend - sent);
++                  msg->sg.data[msg->sg.start].length)
+                       goto more_data;
+-              }
+       }
+       return ret;
+ }
+-- 
+2.43.0
+