atm: Fix uninit and mem accounting leak in vcc_sendmsg().
Subsystems (3)
v2 cover atm: Fix uninit and mem accounting leak in vcc_sendmsg().
From: Kuniyuki Iwashima <[email protected]>
Patch 1 fixes uninit issue reported by KMSAN, and patch 2 fixes another issue found by Simon Horman during review for v1 patch.
Changes:
v2:
* Add patch 2
* Patch 1: reuse "done:" label
v1: https://lore.kernel.org/netdev/[email protected]/
Kuniyuki Iwashima (2):
atm: atmtcp: Free invalid length skb in atmtcp_c_send().
atm: Revert atm_account_tx() if copy_from_iter_full() fails.
drivers/atm/atmtcp.c | 4 +++- include/linux/atmdev.h | 6 ++++++ net/atm/common.c | 1 + net/atm/raw.c | 2 +- 4 files changed, 11 insertions(+), 2 deletions(-)
Signature · 1 line
2.49.0
PATCH v2 1/2 atm: atmtcp: Free invalid length skb in atmtcp_c_send().
From: Kuniyuki Iwashima <[email protected]>
syzbot reported the splat below. [0]
vcc_sendmsg() copies data passed from userspace to skb and passes it to vcc->dev->ops->send().
atmtcp_c_send() accesses skb->data as struct atmtcp_hdr after checking if skb->len is 0, but it's not enough.
Also, when skb->len == 0, skb and sk (vcc) were leaked because dev_kfree_skb() is not called and sk_wmem_alloc adjustment is missing to revert atm_account_tx() in vcc_sendmsg(), which is expected to be done in atm_pop_raw().
Let's properly free skb with an invalid length in atmtcp_c_send().
[0]:
BUG: KMSAN: uninit-value in atmtcp_c_send+0x255/0xed0 drivers/atm/atmtcp.c:294 atmtcp_c_send+0x255/0xed0 drivers/atm/atmtcp.c:294 vcc_sendmsg+0xd7c/0xff0 net/atm/common.c:644 sock_sendmsg_nosec net/socket.c:712 [inline] __sock_sendmsg+0x330/0x3d0 net/socket.c:727 ____sys_sendmsg+0x7e0/0xd80 net/socket.c:2566 ___sys_sendmsg+0x271/0x3b0 net/socket.c:2620 __sys_sendmsg net/socket.c:2652 [inline] __do_sys_sendmsg net/socket.c:2657 [inline] __se_sys_sendmsg net/socket.c:2655 [inline] __x64_sys_sendmsg+0x211/0x3e0 net/socket.c:2655 x64_sys_call+0x32fb/0x3db0 arch/x86/include/generated/asm/syscalls_64.h:47 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xd9/0x210 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f
Uninit was created at:
slab_post_alloc_hook mm/slub.c:4154 [inline] slab_alloc_node mm/slub.c:4197 [inline] kmem_cache_alloc_node_noprof+0x818/0xf00 mm/slub.c:4249 kmalloc_reserve+0x13c/0x4b0 net/core/skbuff.c:579 __alloc_skb+0x347/0x7d0 net/core/skbuff.c:670 alloc_skb include/linux/skbuff.h:1336 [inline] vcc_sendmsg+0xb40/0xff0 net/atm/common.c:628 sock_sendmsg_nosec net/socket.c:712 [inline] __sock_sendmsg+0x330/0x3d0 net/socket.c:727 ____sys_sendmsg+0x7e0/0xd80 net/socket.c:2566 ___sys_sendmsg+0x271/0x3b0 net/socket.c:2620 __sys_sendmsg net/socket.c:2652 [inline] __do_sys_sendmsg net/socket.c:2657 [inline] __se_sys_sendmsg net/socket.c:2655 [inline] __x64_sys_sendmsg+0x211/0x3e0 net/socket.c:2655 x64_sys_call+0x32fb/0x3db0 arch/x86/include/generated/asm/syscalls_64.h:47 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xd9/0x210 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f CPU: 1 UID: 0 PID: 5798 Comm: syz-executor192 Not tainted 6.16.0-rc1-syzkaller-00010-g2c4a1f3fe03e #0 PREEMPT(undef) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/07/2025
---
v2: Reuse done: label
--- drivers/atm/atmtcp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/atm/atmtcp.c +3 -1
@@ -288,7 +288,9 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)struct sk_buff *new_skb;int result =0 ; -if (!skb->len)return 0 ; +if (skb->len <sizeof (struct atmtcp_hdr )) + goto done; + dev = vcc->dev_data; hdr = (struct atmtcp_hdr *) skb->data;if (hdr->length ==ATMTCP_HDR_MAGIC ) {
Signature · 1 line
2.49.0
PATCH v2 2/2 atm: Revert atm_account_tx() if copy_from_iter_full() fails.
In reply to Kuniyuki IwashimaFrom: Kuniyuki Iwashima <[email protected]>
In vcc_sendmsg(), we account skb->truesize to sk->sk_wmem_alloc by atm_account_tx().
It is expected to be reverted by atm_pop_raw() later called by vcc->dev->ops->send(vcc, skb).
However, vcc_sendmsg() misses the same revert when copy_from_iter_full() fails, and then we will leak a socket.
Let's factorise the revert part as atm_return_tx() and call it in the failure path.
Note that the corresponding sk_wmem_alloc operation can be found in alloc_tx() as of the blamed commit.
$ git blame -L:alloc_tx net/atm/common.c c55fa3cccbc2c~
--- include/linux/atmdev.h | 6 ++++++ net/atm/common.c | 1 + net/atm/raw.c | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-)
include/linux/atmdev.h +6 -0
@@ -249,6 +249,12 @@ static inline void atm_account_tx(struct atm_vcc *vcc, struct sk_buff *skb)ATM_SKB (skb)->atm_options = vcc->atm_options; } +static inline void atm_return_tx (struct atm_vcc *vcc,struct sk_buff *skb) +{ +WARN_ON_ONCE (refcount_sub_and_test (ATM_SKB (skb)->acct_truesize, + &sk_atm (vcc)->sk_wmem_alloc)); +} +static inline void atm_force_charge (struct atm_vcc *vcc,int truesize) {atomic_add (truesize, &sk_atm (vcc)->sk_rmem_alloc);
net/atm/common.c +1 -0
@@ -635,6 +635,7 @@ int vcc_sendmsg(struct socket *sock, struct msghdr *m, size_t size) skb->dev =NULL ;/* for paths shared with net_device interfaces */ if (!copy_from_iter_full (skb_put (skb, size), size, &m->msg_iter)) { +atm_return_tx (vcc, skb);kfree_skb (skb); error = -EFAULT ; goto out;
net/atm/raw.c +1 -1
@@ -36,7 +36,7 @@ static void atm_pop_raw(struct atm_vcc *vcc, struct sk_buff *skb)pr_debug ("(%d) %d -= %d\n" , vcc->vci,sk_wmem_alloc_get (sk),ATM_SKB (skb)->acct_truesize); -WARN_ON (refcount_sub_and_test (ATM_SKB (skb)->acct_truesize, &sk->sk_wmem_alloc)); +atm_return_tx (vcc, skb);dev_kfree_skb_any (skb); sk->sk_write_space (sk); }
Signature · 1 line
2.49.0
This series was applied to netdev/net.git (main) by Jakub Kicinski <[email protected]>:
Hello:
This series was applied to netdev/net.git (main)
by Jakub Kicinski <[email protected]>:
Quoted 6 lines · On Mon, 16 Jun 2025 11:21:13 -0700 you wrote:
From: Kuniyuki Iwashima <[email protected]>
Patch 1 fixes uninit issue reported by KMSAN, and patch 2 fixes another issue found by Simon Horman during review for v1 patch.
Quoted 6 lines
Changes:
v2:
* Add patch 2
* Patch 1: reuse "done:" label[...]
Here is the summary with links:
- [v2,net,1/2] atm: atmtcp: Free invalid length skb in atmtcp_c_send().
https://git.kernel.org/netdev/net/c/2f370ae1fb63 - [v2,net,2/2] atm: Revert atm_account_tx() if copy_from_iter_full() fails. https://git.kernel.org/netdev/net/c/7851263998d4
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html