memory leak in radix_tree_insert (2)
Subsystems (5)
syzbot
syzbotHello,
syzbot found the following issue on:
HEAD commit: 33cc938e65a9 Linux 6.7-rc4 git tree: upstream console output: https://syzkaller.appspot.com/x/log.txt?x=16ddf83ce80000 kernel config: https://syzkaller.appspot.com/x/.config?x=37d1b8bb20150e6 dashboard link: https://syzkaller.appspot.com/bug?extid=006987d1be3586e13555 compiler: gcc (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40 syz repro: https://syzkaller.appspot.com/x/repro.syz?x=10276ebae80000 C reproducer: https://syzkaller.appspot.com/x/repro.c?x=128c50d2e80000
Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/bd6d7a5ff2af/disk-33cc938e.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/ce91b40ecddb/vmlinux-33cc938e.xz
kernel image: https://storage.googleapis.com/syzbot-assets/5507257fe99e/bzImage-33cc938e.xz
IMPORTANT: if you fix the issue, please add the following tag to the commit:
write to /proc/sys/kernel/hung_task_check_interval_secs failed: No such file or directory write to /proc/sys/kernel/softlockup_all_cpu_backtrace failed: No such file or directory
BUG: memory leak
unreferenced object 0xffff88810bbf56d8 (size 576):
comm "syz-executor250", pid 5051, jiffies 4294951219 (age 12.920s)
hex dump (first 32 bytes):
3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 <...............
f0 a9 2d 0c 81 88 ff ff f0 56 bf 0b 81 88 ff ff ..-......V......
backtrace:
[<ffffffff81631398>] kmemleak_alloc_recursive include/linux/kmemleak.h:42 [inline]
[<ffffffff81631398>] slab_post_alloc_hook mm/slab.h:766 [inline]
[<ffffffff81631398>] slab_alloc_node mm/slub.c:3478 [inline]
[<ffffffff81631398>] slab_alloc mm/slub.c:3486 [inline]
[<ffffffff81631398>] __kmem_cache_alloc_lru mm/slub.c:3493 [inline]
[<ffffffff81631398>] kmem_cache_alloc+0x298/0x430 mm/slub.c:3502
[<ffffffff84b5094c>] radix_tree_node_alloc.constprop.0+0x7c/0x1a0 lib/radix-tree.c:276
[<ffffffff84b524cf>] __radix_tree_create lib/radix-tree.c:624 [inline]
[<ffffffff84b524cf>] radix_tree_insert+0x14f/0x360 lib/radix-tree.c:712
[<ffffffff84ae105d>] qrtr_tx_wait net/qrtr/af_qrtr.c:277 [inline]
[<ffffffff84ae105d>] qrtr_node_enqueue+0x57d/0x630 net/qrtr/af_qrtr.c:348
[<ffffffff84ae26f6>] qrtr_bcast_enqueue+0x66/0xd0 net/qrtr/af_qrtr.c:891
[<ffffffff84ae32d2>] qrtr_sendmsg+0x232/0x450 net/qrtr/af_qrtr.c:992
[<ffffffff83ec3c32>] sock_sendmsg_nosec net/socket.c:730 [inline]
[<ffffffff83ec3c32>] __sock_sendmsg+0x52/0xa0 net/socket.c:745
[<ffffffff83ec3d7b>] sock_write_iter+0xfb/0x180 net/socket.c:1158
[<ffffffff816961a7>] call_write_iter include/linux/fs.h:2020 [inline]
[<ffffffff816961a7>] new_sync_write fs/read_write.c:491 [inline]
[<ffffffff816961a7>] vfs_write+0x327/0x590 fs/read_write.c:584
[<ffffffff816966fb>] ksys_write+0x13b/0x170 fs/read_write.c:637
[<ffffffff84b6ddcf>] do_syscall_x64 arch/x86/entry/common.c:51 [inline]
[<ffffffff84b6ddcf>] do_syscall_64+0x3f/0x110 arch/x86/entry/common.c:82
[<ffffffff84c0008b>] entry_SYSCALL_64_after_hwframe+0x63/0x6b
BUG: memory leak
unreferenced object 0xffff88810bbf5920 (size 576):
comm "syz-executor250", pid 5051, jiffies 4294951219 (age 12.920s)
hex dump (first 32 bytes):
36 0f 01 00 00 00 00 00 d8 56 bf 0b 81 88 ff ff 6........V......
f0 a9 2d 0c 81 88 ff ff 38 59 bf 0b 81 88 ff ff ..-.....8Y......
backtrace:
[<ffffffff81631398>] kmemleak_alloc_recursive include/linux/kmemleak.h:42 [inline]
[<ffffffff81631398>] slab_post_alloc_hook mm/slab.h:766 [inline]
[<ffffffff81631398>] slab_alloc_node mm/slub.c:3478 [inline]
[<ffffffff81631398>] slab_alloc mm/slub.c:3486 [inline]
[<ffffffff81631398>] __kmem_cache_alloc_lru mm/slub.c:3493 [inline]
[<ffffffff81631398>] kmem_cache_alloc+0x298/0x430 mm/slub.c:3502
[<ffffffff84b5094c>] radix_tree_node_alloc.constprop.0+0x7c/0x1a0 lib/radix-tree.c:276
[<ffffffff84b524cf>] __radix_tree_create lib/radix-tree.c:624 [inline]
[<ffffffff84b524cf>] radix_tree_insert+0x14f/0x360 lib/radix-tree.c:712
[<ffffffff84ae105d>] qrtr_tx_wait net/qrtr/af_qrtr.c:277 [inline]
[<ffffffff84ae105d>] qrtr_node_enqueue+0x57d/0x630 net/qrtr/af_qrtr.c:348
[<ffffffff84ae26f6>] qrtr_bcast_enqueue+0x66/0xd0 net/qrtr/af_qrtr.c:891
[<ffffffff84ae32d2>] qrtr_sendmsg+0x232/0x450 net/qrtr/af_qrtr.c:992
[<ffffffff83ec3c32>] sock_sendmsg_nosec net/socket.c:730 [inline]
[<ffffffff83ec3c32>] __sock_sendmsg+0x52/0xa0 net/socket.c:745
[<ffffffff83ec3d7b>] sock_write_iter+0xfb/0x180 net/socket.c:1158
[<ffffffff816961a7>] call_write_iter include/linux/fs.h:2020 [inline]
[<ffffffff816961a7>] new_sync_write fs/read_write.c:491 [inline]
[<ffffffff816961a7>] vfs_write+0x327/0x590 fs/read_write.c:584
[<ffffffff816966fb>] ksys_write+0x13b/0x170 fs/read_write.c:637
[<ffffffff84b6ddcf>] do_syscall_x64 arch/x86/entry/common.c:51 [inline]
[<ffffffff84b6ddcf>] do_syscall_64+0x3f/0x110 arch/x86/entry/common.c:82
[<ffffffff84c0008b>] entry_SYSCALL_64_after_hwframe+0x63/0x6b
BUG: memory leak
unreferenced object 0xffff88810c832000 (size 576):
comm "syz-executor250", pid 5051, jiffies 4294951219 (age 12.920s)
hex dump (first 32 bytes):
30 3f 01 00 00 00 00 00 20 59 bf 0b 81 88 ff ff 0?...... Y......
f0 a9 2d 0c 81 88 ff ff 18 20 83 0c 81 88 ff ff ..-...... ......
backtrace:
[<ffffffff81631398>] kmemleak_alloc_recursive include/linux/kmemleak.h:42 [inline]
[<ffffffff81631398>] slab_post_alloc_hook mm/slab.h:766 [inline]
[<ffffffff81631398>] slab_alloc_node mm/slub.c:3478 [inline]
[<ffffffff81631398>] slab_alloc mm/slub.c:3486 [inline]
[<ffffffff81631398>] __kmem_cache_alloc_lru mm/slub.c:3493 [inline]
[<ffffffff81631398>] kmem_cache_alloc+0x298/0x430 mm/slub.c:3502
[<ffffffff84b5094c>] radix_tree_node_alloc.constprop.0+0x7c/0x1a0 lib/radix-tree.c:276
[<ffffffff84b524cf>] __radix_tree_create lib/radix-tree.c:624 [inline]
[<ffffffff84b524cf>] radix_tree_insert+0x14f/0x360 lib/radix-tree.c:712
[<ffffffff84ae105d>] qrtr_tx_wait net/qrtr/af_qrtr.c:277 [inline]
[<ffffffff84ae105d>] qrtr_node_enqueue+0x57d/0x630 net/qrtr/af_qrtr.c:348
[<ffffffff84ae26f6>] qrtr_bcast_enqueue+0x66/0xd0 net/qrtr/af_qrtr.c:891
[<ffffffff84ae32d2>] qrtr_sendmsg+0x232/0x450 net/qrtr/af_qrtr.c:992
[<ffffffff83ec3c32>] sock_sendmsg_nosec net/socket.c:730 [inline]
[<ffffffff83ec3c32>] __sock_sendmsg+0x52/0xa0 net/socket.c:745
[<ffffffff83ec3d7b>] sock_write_iter+0xfb/0x180 net/socket.c:1158
[<ffffffff816961a7>] call_write_iter include/linux/fs.h:2020 [inline]
[<ffffffff816961a7>] new_sync_write fs/read_write.c:491 [inline]
[<ffffffff816961a7>] vfs_write+0x327/0x590 fs/read_write.c:584
[<ffffffff816966fb>] ksys_write+0x13b/0x170 fs/read_write.c:637
[<ffffffff84b6ddcf>] do_syscall_x64 arch/x86/entry/common.c:51 [inline]
[<ffffffff84b6ddcf>] do_syscall_64+0x3f/0x110 arch/x86/entry/common.c:82
[<ffffffff84c0008b>] entry_SYSCALL_64_after_hwframe+0x63/0x6b
BUG: memory leak
unreferenced object 0xffff88810c832248 (size 576):
comm "syz-executor250", pid 5051, jiffies 4294951219 (age 12.920s)
hex dump (first 32 bytes):
2a 3f 00 00 00 00 00 00 00 20 83 0c 81 88 ff ff *?....... ......
f0 a9 2d 0c 81 88 ff ff 60 22 83 0c 81 88 ff ff ..-.....`"......
backtrace:
[<ffffffff81631398>] kmemleak_alloc_recursive include/linux/kmemleak.h:42 [inline]
[<ffffffff81631398>] slab_post_alloc_hook mm/slab.h:766 [inline]
[<ffffffff81631398>] slab_alloc_node mm/slub.c:3478 [inline]
[<ffffffff81631398>] slab_alloc mm/slub.c:3486 [inline]
[<ffffffff81631398>] __kmem_cache_alloc_lru mm/slub.c:3493 [inline]
[<ffffffff81631398>] kmem_cache_alloc+0x298/0x430 mm/slub.c:3502
[<ffffffff84b5094c>] radix_tree_node_alloc.constprop.0+0x7c/0x1a0 lib/radix-tree.c:276
[<ffffffff84b524cf>] __radix_tree_create lib/radix-tree.c:624 [inline]
[<ffffffff84b524cf>] radix_tree_insert+0x14f/0x360 lib/radix-tree.c:712
[<ffffffff84ae105d>] qrtr_tx_wait net/qrtr/af_qrtr.c:277 [inline]
[<ffffffff84ae105d>] qrtr_node_enqueue+0x57d/0x630 net/qrtr/af_qrtr.c:348
[<ffffffff84ae26f6>] qrtr_bcast_enqueue+0x66/0xd0 net/qrtr/af_qrtr.c:891
[<ffffffff84ae32d2>] qrtr_sendmsg+0x232/0x450 net/qrtr/af_qrtr.c:992
[<ffffffff83ec3c32>] sock_sendmsg_nosec net/socket.c:730 [inline]
[<ffffffff83ec3c32>] __sock_sendmsg+0x52/0xa0 net/socket.c:745
[<ffffffff83ec3d7b>] sock_write_iter+0xfb/0x180 net/socket.c:1158
[<ffffffff816961a7>] call_write_iter include/linux/fs.h:2020 [inline]
[<ffffffff816961a7>] new_sync_write fs/read_write.c:491 [inline]
[<ffffffff816961a7>] vfs_write+0x327/0x590 fs/read_write.c:584
[<ffffffff816966fb>] ksys_write+0x13b/0x170 fs/read_write.c:637
[<ffffffff84b6ddcf>] do_syscall_x64 arch/x86/entry/common.c:51 [inline]
[<ffffffff84b6ddcf>] do_syscall_64+0x3f/0x110 arch/x86/entry/common.c:82
[<ffffffff84c0008b>] entry_SYSCALL_64_after_hwframe+0x63/0x6bwrite to /proc/sys/kernel/hung_task_check_interval_secs failed: No such file or directory write to /proc/sys/kernel/softlockup_all_cpu_backtrace failed: No such file or directory
---
This report is generated by a bot. It may contain errors. See https://goo.gl/tpsmEJ for more information about syzbot. syzbot engineers can be reached at [email protected].
syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title
If you want syzbot to run the reproducer, reply with:
#syz test: git://repo/address.git branch-or-commit-hash
If you attach or paste a git patch, syzbot will apply it before testing.
If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)
If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report
If you want to undo deduplication, reply with:
#syz undup
syzbot
syzbotRe: [syzbot] [arm-msm?] [net?] memory leak in radix_tree_insert
For archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [arm-msm?] [net?] memory leak in radix_tree_insert
Author: [email protected]
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 33cc938e65a9
lib/radix-tree.c +3 -1
@@ -714,8 +714,10 @@ int radix_tree_insert(struct radix_tree_root *root, unsigned long index,return error; error =insert_entries (node, slot, item); -if (error <0 ) +if (error <0 ) { +__radix_tree_delete (root, node, slot);return error; + }if (node) {unsigned offset =get_slot_offset (node, slot);
syzbot
syzbotRe: [syzbot] [arm-msm?] [net?] memory leak in radix_tree_insert
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [arm-msm?] [net?] memory leak in radix_tree_insert
Author: [email protected]
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 33cc938e65a9
lib/radix-tree.c +5 -1
@@ -714,8 +714,10 @@ int radix_tree_insert(struct radix_tree_root *root, unsigned long index,return error; error =insert_entries (node, slot, item); -if (error <0 ) +if (error <0 ) { +__radix_tree_delete (root, node, slot);return error; + }if (node) {unsigned offset =get_slot_offset (node, slot);
@@ -55,6 +55,8 @@ struct kmem_cache *radix_tree_node_cachep;#define IDR_MAX_PATH (DIV_ROUND_UP(IDR_INDEX_BITS, \ RADIX_TREE_MAP_SHIFT))#define IDR_PRELOAD_SIZE (IDR_MAX_PATH * 2 - 1) +static bool __radix_tree_delete (struct radix_tree_root *root, +struct radix_tree_node *node,void __rcu **slot);/* * Per-cpu pool of preloaded nodes
syzbot
syzbotRe: [syzbot] [arm-msm?] [net?] memory leak in radix_tree_insert
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [arm-msm?] [net?] memory leak in radix_tree_insert
Author: [email protected]
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 33cc938e65a9
lib/radix-tree.c +21 -19
@@ -714,8 +714,10 @@ int radix_tree_insert(struct radix_tree_root *root, unsigned long index,return error; error =insert_entries (node, slot, item); -if (error <0 ) +if (error <0 ) { +__radix_tree_delete (root, node, slot);return error; + }if (node) {unsigned offset =get_slot_offset (node, slot);
@@ -581,6 +579,24 @@ static bool delete_node(struct radix_tree_root *root,return deleted; } +static bool __radix_tree_delete (struct radix_tree_root *root, +struct radix_tree_node *node,void __rcu **slot) +{ +void *old =rcu_dereference_raw (*slot); +int values =xa_is_value (old) ?-1 :0 ; +unsigned offset =get_slot_offset (node, slot); +int tag; + +if (is_idr (root)) +node_tag_set (root, node,IDR_FREE , offset); +else +for (tag =0 ; tag <RADIX_TREE_MAX_TAGS ; tag++) +node_tag_clear (root, node, tag, offset); + +replace_slot (slot,NULL , node,-1 , values); +return node &&delete_node (root, node); +} +/** * __radix_tree_create - create a slot in a radix tree * @root: radix tree root
@@ -1365,24 +1381,6 @@ radix_tree_gang_lookup_tag_slot(const struct radix_tree_root *root, }EXPORT_SYMBOL (radix_tree_gang_lookup_tag_slot); -static bool __radix_tree_delete (struct radix_tree_root *root, -struct radix_tree_node *node,void __rcu **slot) -{ -void *old =rcu_dereference_raw (*slot); -int values =xa_is_value (old) ?-1 :0 ; -unsigned offset =get_slot_offset (node, slot); -int tag; - -if (is_idr (root)) -node_tag_set (root, node,IDR_FREE , offset); -else -for (tag =0 ; tag <RADIX_TREE_MAX_TAGS ; tag++) -node_tag_clear (root, node, tag, offset); - -replace_slot (slot,NULL , node,-1 , values); -return node &&delete_node (root, node); -} -/** * radix_tree_iter_delete - delete the entry at this iterator position * @root: radix tree root
syzbot
syzbotRe: [syzbot] [arm-msm?] [net?] memory leak in radix_tree_insert
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [arm-msm?] [net?] memory leak in radix_tree_insert
Author: [email protected]
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 33cc938e65a9
lib/radix-tree.c +21 -19
@@ -581,6 +579,24 @@ static bool delete_node(struct radix_tree_root *root,return deleted; } +static bool __radix_tree_delete (struct radix_tree_root *root, +struct radix_tree_node *node,void __rcu **slot) +{ +void *old =rcu_dereference_raw (*slot); +int values =xa_is_value (old) ?-1 :0 ; +unsigned offset =get_slot_offset (node, slot); +int tag; + +if (is_idr (root)) +node_tag_set (root, node,IDR_FREE , offset); +else +for (tag =0 ; tag <RADIX_TREE_MAX_TAGS ; tag++) +node_tag_clear (root, node, tag, offset); + +replace_slot (slot,NULL , node,-1 , values); +return node &&delete_node (root, node); +} +/** * __radix_tree_create - create a slot in a radix tree * @root: radix tree root
@@ -714,8 +714,10 @@ int radix_tree_insert(struct radix_tree_root *root, unsigned long index,return error; error =insert_entries (node, slot, item); -if (error <0 ) +if (error <0 ) { +__radix_tree_delete (root, node, slot);return error; + }if (node) {unsigned offset =get_slot_offset (node, slot);
@@ -1365,24 +1381,6 @@ radix_tree_gang_lookup_tag_slot(const struct radix_tree_root *root, }EXPORT_SYMBOL (radix_tree_gang_lookup_tag_slot); -static bool __radix_tree_delete (struct radix_tree_root *root, -struct radix_tree_node *node,void __rcu **slot) -{ -void *old =rcu_dereference_raw (*slot); -int values =xa_is_value (old) ?-1 :0 ; -unsigned offset =get_slot_offset (node, slot); -int tag; - -if (is_idr (root)) -node_tag_set (root, node,IDR_FREE , offset); -else -for (tag =0 ; tag <RADIX_TREE_MAX_TAGS ; tag++) -node_tag_clear (root, node, tag, offset); - -replace_slot (slot,NULL , node,-1 , values); -return node &&delete_node (root, node); -} -/** * radix_tree_iter_delete - delete the entry at this iterator position * @root: radix tree root
syzbot
syzbotRe: [syzbot] [arm-msm?] [net?] memory leak in radix_tree_insert
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [arm-msm?] [net?] memory leak in radix_tree_insert
Author: [email protected]
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 33cc938e65a9
lib/radix-tree.c +5 -1
@@ -55,6 +55,8 @@ struct kmem_cache *radix_tree_node_cachep;#define IDR_MAX_PATH (DIV_ROUND_UP(IDR_INDEX_BITS, \ RADIX_TREE_MAP_SHIFT))#define IDR_PRELOAD_SIZE (IDR_MAX_PATH * 2 - 1) +static bool __radix_tree_delete (struct radix_tree_root *root, +struct radix_tree_node *node,void __rcu **slot);/* * Per-cpu pool of preloaded nodes
@@ -714,8 +716,10 @@ int radix_tree_insert(struct radix_tree_root *root, unsigned long index,return error; error =insert_entries (node, slot, item); -if (error <0 ) +if (error <0 ) { +__radix_tree_delete (root, node, slot);return error; + }if (node) {unsigned offset =get_slot_offset (node, slot);
Signature · 1 line
2.43.0
syzbot
syzbotRe: [syzbot] [arm-msm?] [net?] memory leak in radix_tree_insert
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [arm-msm?] [net?] memory leak in radix_tree_insert
Author: [email protected]
please test memory leak in radix_tree_insert
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 33cc938e65a9
net/qrtr/af_qrtr.c +3 -0
@@ -911,6 +911,9 @@ static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)u32 type;int rc; +if (!msg->msg_iter.count) +return -EINVAL ; +if (msg->msg_flags & ~(MSG_DONTWAIT ))return -EINVAL ;
syzbot
syzbotRe: [syzbot] [arm-msm?] [net?] memory leak in radix_tree_insert
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [arm-msm?] [net?] memory leak in radix_tree_insert
Author: [email protected]
please test memory leak in radix_tree_insert
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 33cc938e65a9
net/qrtr/af_qrtr.c +9 -0
@@ -275,6 +275,8 @@ static int qrtr_tx_wait(struct qrtr_node *node, int dest_node, int dest_port,if (flow) {init_waitqueue_head (&flow->resume_tx);if (radix_tree_insert (&node->qrtr_tx_flow, key, flow)) { +printk ("f: %p\n" , flow); +radix_tree_delete (&node->qrtr_tx_flow, key);kfree (flow); flow =NULL ; }
@@ -287,10 +289,14 @@ static int qrtr_tx_wait(struct qrtr_node *node, int dest_node, int dest_port,return 1 ;spin_lock_irq (&flow->resume_tx.lock); +printk ("to wait, f: %p, pd: %d, ff: %d, ep: %p\n" , + flow, flow->pending, flow->failed, node->ep); ret =wait_event_interruptible_locked_irq (flow->resume_tx, flow->pending <QRTR_TX_FLOW_HIGH || flow->tx_failed || !node->ep); +printk ("r: %d, f: %p, pd: %d, ff: %d, ep: %p\n" , + ret, flow, flow->pending, flow->failed, node->ep);if (ret <0 ) { confirm_rx = ret; }else if (!node->ep) {
@@ -911,6 +917,9 @@ static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)u32 type;int rc; +if (!msg->msg_iter.count) +return -EINVAL ; +if (msg->msg_flags & ~(MSG_DONTWAIT ))return -EINVAL ;
syzbot
syzbotRe: [syzbot] [arm-msm?] [net?] memory leak in radix_tree_insert
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [arm-msm?] [net?] memory leak in radix_tree_insert
Author: [email protected]
please test memory leak in radix_tree_insert
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 33cc938e65a9
net/qrtr/af_qrtr.c +6 -0
@@ -275,6 +275,8 @@ static int qrtr_tx_wait(struct qrtr_node *node, int dest_node, int dest_port,if (flow) {init_waitqueue_head (&flow->resume_tx);if (radix_tree_insert (&node->qrtr_tx_flow, key, flow)) { +printk ("f: %p\n" , flow); +radix_tree_delete (&node->qrtr_tx_flow, key);kfree (flow); flow =NULL ; }
@@ -287,10 +289,14 @@ static int qrtr_tx_wait(struct qrtr_node *node, int dest_node, int dest_port,return 1 ;spin_lock_irq (&flow->resume_tx.lock); +printk ("to wait, f: %p, pd: %d, ff: %d, ep: %p\n" , + flow, flow->pending, flow->failed, node->ep); ret =wait_event_interruptible_locked_irq (flow->resume_tx, flow->pending <QRTR_TX_FLOW_HIGH || flow->tx_failed || !node->ep); +printk ("r: %d, f: %p, pd: %d, ff: %d, ep: %p\n" , + ret, flow, flow->pending, flow->failed, node->ep);if (ret <0 ) { confirm_rx = ret; }else if (!node->ep) {
syzbot
syzbotRe: [syzbot] [arm-msm?] [net?] memory leak in radix_tree_insert
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [arm-msm?] [net?] memory leak in radix_tree_insert
Author: [email protected]
please test memory leak in radix_tree_insert
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 33cc938e65a9
net/qrtr/af_qrtr.c +6 -0
@@ -275,6 +275,8 @@ static int qrtr_tx_wait(struct qrtr_node *node, int dest_node, int dest_port,if (flow) {init_waitqueue_head (&flow->resume_tx);if (radix_tree_insert (&node->qrtr_tx_flow, key, flow)) { +printk ("f: %p\n" , flow); +radix_tree_delete (&node->qrtr_tx_flow, key);kfree (flow); flow =NULL ; }
@@ -287,10 +289,14 @@ static int qrtr_tx_wait(struct qrtr_node *node, int dest_node, int dest_port,return 1 ;spin_lock_irq (&flow->resume_tx.lock); +printk ("to wait, f: %p, pd: %d, ff: %d, ep: %p\n" , + flow, flow->pending, flow->tx_failed, node->ep); ret =wait_event_interruptible_locked_irq (flow->resume_tx, flow->pending <QRTR_TX_FLOW_HIGH || flow->tx_failed || !node->ep); +printk ("r: %d, f: %p, pd: %d, ff: %d, ep: %p\n" , + ret, flow, flow->pending, flow->tx_failed, node->ep);if (ret <0 ) { confirm_rx = ret; }else if (!node->ep) {
syzbot
syzbotRe: [syzbot] [arm-msm?] [net?] memory leak in radix_tree_insert
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [arm-msm?] [net?] memory leak in radix_tree_insert
Author: [email protected]
please test memory leak in radix_tree_insert
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 33cc938e65a9
net/qrtr/af_qrtr.c +7 -1
@@ -273,11 +273,17 @@ static int qrtr_tx_wait(struct qrtr_node *node, int dest_node, int dest_port,if (!flow) { flow =kzalloc (sizeof (*flow),GFP_KERNEL );if (flow) { +if (radix_tree_preload (GFP_KERNEL )) { +mutex_unlock (&node->qrtr_tx_lock); +return -ENOMEM ; + }init_waitqueue_head (&flow->resume_tx); -if (radix_tree_insert (&node->qrtr_tx_flow, key, flow)) { +if (ret =radix_tree_insert (&node->qrtr_tx_flow, key, flow)) { +printk ("r: %d\n" , ret);kfree (flow); flow =NULL ; } +radix_tree_preload_end (); } }mutex_unlock (&node->qrtr_tx_lock);
syzbot
syzbotRe: [syzbot] [arm-msm?] [net?] memory leak in radix_tree_insert
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [arm-msm?] [net?] memory leak in radix_tree_insert
Author: [email protected]
please test memory leak in radix_tree_insert
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 33cc938e65a9
net/qrtr/af_qrtr.c +2 -1
@@ -274,7 +274,8 @@ static int qrtr_tx_wait(struct qrtr_node *node, int dest_node, int dest_port, flow =kzalloc (sizeof (*flow),GFP_KERNEL );if (flow) {init_waitqueue_head (&flow->resume_tx); -if (radix_tree_insert (&node->qrtr_tx_flow, key, flow)) { +if (ret =radix_tree_insert (&node->qrtr_tx_flow, key, flow)) { +printk ("r: %d\n" , ret);kfree (flow); flow =NULL ; }
lib/radix-tree.c +5 -0
@@ -413,6 +413,7 @@ static int radix_tree_extend(struct radix_tree_root *root, gfp_t gfp,void *entry;unsigned int maxshift;int tag; +int i =0 ;/* Figure out what the shift should be. */ maxshift = shift;
@@ -428,6 +429,8 @@ static int radix_tree_extend(struct radix_tree_root *root, gfp_t gfp, root, shift, 0, 1, 0);if (!node)return -ENOMEM ; + i++; +printk ("i: %d, n: %p, idx: %d, s: %d, %s\n" , i, node, index, shift, __func__);if (is_idr (root)) {all_tag_set (node,IDR_FREE );
@@ -611,6 +614,7 @@ static int __radix_tree_create(struct radix_tree_root *root, shift =radix_tree_load_root (root, &child, &maxindex);/* Make sure the tree is high enough. */ +printk ("im: %d, s: %d, m: %d, %s\n" , index, shift, maxindex, __func__);if (max > maxindex) {int error =radix_tree_extend (root, gfp, max, shift);if (error <0 )
@@ -625,6 +629,7 @@ static int __radix_tree_create(struct radix_tree_root *root,/* Have to add a child node. */ child =radix_tree_node_alloc (gfp, node, root, shift, offset,0 ,0 ); +printk ("c: %p, %s\n" , child, __func__);if (!child)return -ENOMEM ;rcu_assign_pointer (*slot,node_to_entry (child));
syzbot
syzbotRe: [syzbot] [arm-msm?] [net?] memory leak in radix_tree_insert
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [arm-msm?] [net?] memory leak in radix_tree_insert
Author: [email protected]
please test memory leak in radix_tree_insert
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 33cc938e65a9
net/qrtr/af_qrtr.c +3 -0
@@ -267,6 +267,9 @@ static int qrtr_tx_wait(struct qrtr_node *node, int dest_node, int dest_port,/* Never set confirm_rx on non-data packets */ if (type !=QRTR_TYPE_DATA )return 0 ; +printk ("dn: %d, dp: %d, %s\n" , dest_node, dest_port, type, __func__); +if (dest_node <0 ) +return -EINVAL ;mutex_lock (&node->qrtr_tx_lock); flow =radix_tree_lookup (&node->qrtr_tx_flow, key);
syzbot
syzbotRe: [syzbot] [arm-msm?] [net?] memory leak in radix_tree_insert
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [arm-msm?] [net?] memory leak in radix_tree_insert
Author: [email protected]
please test memory leak in radix_tree_insert
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 33cc938e65a9
include/linux/radix-tree.h +1 -0
@@ -254,6 +254,7 @@ unsigned int radix_tree_gang_lookup_tag_slot(const struct radix_tree_root *, void __rcu ***results, unsigned long first_index, unsigned int max_items, unsigned int tag);int radix_tree_tagged (const struct radix_tree_root *,unsigned int tag); +unsigned long radix_tree_maxindex (const struct radix_tree_root *root);static inline void radix_tree_preload_end (void ) {
lib/radix-tree.c +12 -0
@@ -404,6 +404,18 @@ static unsigned radix_tree_load_root(const struct radix_tree_root *root,return 0 ; } +unsigned long radix_tree_maxindex (const struct radix_tree_root *root) +{ +struct radix_tree_node *node =rcu_dereference_raw (root->xa_head); + +if (likely (radix_tree_is_internal_node (node))) { + node =entry_to_node (node); +return node_maxindex (node); + } + +return 0 ; +} +/* * Extend a radix tree so it can store key @index. */
net/qrtr/af_qrtr.c +6 -0
@@ -344,6 +344,12 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb,struct qrtr_hdr_v1 *hdr;size_t len = skb->len;int rc, confirm_rx; +unsigned long maxidx; + +if (to->sq_node ==QRTR_NODE_BCAST ) { + maxidx =radix_tree_maxindex (&node->qrtr_tx_flow); + to->sq_node = maxidx +1 ; + } confirm_rx =qrtr_tx_wait (node, to->sq_node, to->sq_port, type);if (confirm_rx <0 ) {
syzbot
syzbotRe: [syzbot] [arm-msm?] [net?] memory leak in radix_tree_insert
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [arm-msm?] [net?] memory leak in radix_tree_insert
Author: [email protected]
please test memory leak in radix_tree_insert
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 33cc938e65a9
include/linux/radix-tree.h +1 -0
@@ -254,6 +254,7 @@ unsigned int radix_tree_gang_lookup_tag_slot(const struct radix_tree_root *, void __rcu ***results, unsigned long first_index, unsigned int max_items, unsigned int tag);int radix_tree_tagged (const struct radix_tree_root *,unsigned int tag); +unsigned long radix_tree_maxindex (const struct radix_tree_root *root);static inline void radix_tree_preload_end (void ) {
lib/radix-tree.c +12 -0
@@ -404,6 +404,18 @@ static unsigned radix_tree_load_root(const struct radix_tree_root *root,return 0 ; } +unsigned long radix_tree_maxindex (const struct radix_tree_root *root) +{ +struct radix_tree_node *node =rcu_dereference_raw (root->xa_head); + +if (likely (radix_tree_is_internal_node (node))) { + node =entry_to_node (node); +return node_maxindex (node); + } + +return 0 ; +} +/* * Extend a radix tree so it can store key @index. */
net/qrtr/af_qrtr.c +9 -1
@@ -274,7 +274,8 @@ static int qrtr_tx_wait(struct qrtr_node *node, int dest_node, int dest_port, flow =kzalloc (sizeof (*flow),GFP_KERNEL );if (flow) {init_waitqueue_head (&flow->resume_tx); -if (radix_tree_insert (&node->qrtr_tx_flow, key, flow)) { +if (ret =radix_tree_insert (&node->qrtr_tx_flow, key, flow)) { +printk ("r: %d, k: %llu, f: %p, %s\n" , ret, key, flow, __func__);kfree (flow); flow =NULL ; }
@@ -344,6 +344,13 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb,struct qrtr_hdr_v1 *hdr;size_t len = skb->len;int rc, confirm_rx; +unsigned long maxidx; + +if (to->sq_node ==QRTR_NODE_BCAST ) { + maxidx =radix_tree_maxindex (&node->qrtr_tx_flow); + to->sq_node = maxidx +1 ; +printk ("mi: %llu, sn: %llu, %s\n" , maxidx, to->sq_node, __func__); + } confirm_rx =qrtr_tx_wait (node, to->sq_node, to->sq_port, type);if (confirm_rx <0 ) {
syzbot
syzbotRe: [syzbot] [arm-msm?] [net?] memory leak in radix_tree_insert
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [arm-msm?] [net?] memory leak in radix_tree_insert
Author: [email protected]
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 33cc938e65a9
lib/radix-tree.c +22 -4
@@ -613,12 +613,13 @@ static int __radix_tree_create(struct radix_tree_root *root, unsigned long index, struct radix_tree_node **nodep, void __rcu ***slotp) { - struct radix_tree_node *node = NULL, *child; + struct radix_tree_node *node = NULL, *child, *orig;void __rcu **slot = (void __rcu **)&root->xa_head;unsigned long maxindex; -unsigned int shift, offset =0 ; +unsigned int shift, offset =0 , mmshift =0 ;unsigned long max = index;gfp_t gfp =root_gfp_mask (root); +int ret; shift =radix_tree_load_root (root, &child, &maxindex);
@@ -628,7 +629,9 @@ static int __radix_tree_create(struct radix_tree_root *root,if (error <0 )return error; shift = error; + mmshift = error; child =rcu_dereference_raw (root->xa_head); + orig = child; }while (shift >0 ) {
@@ -637,8 +640,11 @@ static int __radix_tree_create(struct radix_tree_root *root,/* Have to add a child node. */ child =radix_tree_node_alloc (gfp, node, root, shift, offset,0 ,0 ); -if (!child) -return -ENOMEM ; +printk ("nc: %p\n" , child); +if (!child) { + ret = -ENOMEM ; + goto freec; + }rcu_assign_pointer (*slot,node_to_entry (child));if (node) node->count++;
@@ -656,6 +662,18 @@ static int __radix_tree_create(struct radix_tree_root *root,if (slotp) *slotp = slot;return 0 ; +freec: +if (mmshift >0 ) { +struct radix_tree_node *dn; +while (shift < mmshift) { +radix_tree_descend (orig, &dn, index); +printk ("dc: %p\n" , dn); + orig = orig->slots[0 ]; +radix_tree_node_rcu_free (&dn->rcu_head); + shift +=RADIX_TREE_MAP_SHIFT ; + } + } +return ret; }/*
syzbot
syzbotRe: [syzbot] [arm-msm?] [net?] memory leak in radix_tree_insert
In reply to syzbotFor archival purposes, forwarding an incoming command email to [email protected].
For archival purposes, forwarding an incoming command email to [email protected].
***
Subject: [arm-msm?] [net?] memory leak in radix_tree_insert
Author: [email protected]
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 33cc938e65a9
lib/radix-tree.c +21 -4
@@ -613,12 +613,13 @@ static int __radix_tree_create(struct radix_tree_root *root, unsigned long index, struct radix_tree_node **nodep, void __rcu ***slotp) { - struct radix_tree_node *node = NULL, *child; + struct radix_tree_node *node = NULL, *child, *orig;void __rcu **slot = (void __rcu **)&root->xa_head;unsigned long maxindex; -unsigned int shift, offset =0 ; +unsigned int shift, offset =0 , mmshift =0 ;unsigned long max = index;gfp_t gfp =root_gfp_mask (root); +int ret; shift =radix_tree_load_root (root, &child, &maxindex);
@@ -628,6 +629,7 @@ static int __radix_tree_create(struct radix_tree_root *root,if (error <0 )return error; shift = error; + mmshift = error; child =rcu_dereference_raw (root->xa_head); }
@@ -637,8 +639,11 @@ static int __radix_tree_create(struct radix_tree_root *root,/* Have to add a child node. */ child =radix_tree_node_alloc (gfp, node, root, shift, offset,0 ,0 ); -if (!child) -return -ENOMEM ; +printk ("nc: %p\n" , child); +if (!child) { + ret = -ENOMEM ; + goto freec; + }rcu_assign_pointer (*slot,node_to_entry (child));if (node) node->count++;
@@ -656,6 +661,18 @@ static int __radix_tree_create(struct radix_tree_root *root,if (slotp) *slotp = slot;return 0 ; +freec: +if (mmshift >0 ) { +struct radix_tree_node *pn; +while (shift < mmshift && node) { +printk ("dc: %p\n" , node); + pn = node->parent; +radix_tree_node_rcu_free (&node->rcu_head); + shift +=RADIX_TREE_MAP_SHIFT ; + node = pn; + } + } +return ret; }/*
PATCH 1/1 radix-tree: fix memory leak in radix_tree_insert
In reply to syzbot[Syz report]
BUG: memory leak
unreferenced object 0xffff88810bbf56d8 (size 576):
comm "syz-executor250", pid 5051, jiffies 4294951219 (age 12.920s)
hex dump (first 32 bytes):
3c 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 <...............
f0 a9 2d 0c 81 88 ff ff f0 56 bf 0b 81 88 ff ff ..-......V......
backtrace:
[<ffffffff81631398>] kmemleak_alloc_recursive include/linux/kmemleak.h:42 [inline]
[<ffffffff81631398>] slab_post_alloc_hook mm/slab.h:766 [inline]
[<ffffffff81631398>] slab_alloc_node mm/slub.c:3478 [inline]
[<ffffffff81631398>] slab_alloc mm/slub.c:3486 [inline]
[<ffffffff81631398>] __kmem_cache_alloc_lru mm/slub.c:3493 [inline]
[<ffffffff81631398>] kmem_cache_alloc+0x298/0x430 mm/slub.c:3502
[<ffffffff84b5094c>] radix_tree_node_alloc.constprop.0+0x7c/0x1a0 lib/radix-tree.c:276
[<ffffffff84b524cf>] __radix_tree_create lib/radix-tree.c:624 [inline]
[<ffffffff84b524cf>] radix_tree_insert+0x14f/0x360 lib/radix-tree.c:712
[<ffffffff84ae105d>] qrtr_tx_wait net/qrtr/af_qrtr.c:277 [inline]
[<ffffffff84ae105d>] qrtr_node_enqueue+0x57d/0x630 net/qrtr/af_qrtr.c:348
[<ffffffff84ae26f6>] qrtr_bcast_enqueue+0x66/0xd0 net/qrtr/af_qrtr.c:891
[<ffffffff84ae32d2>] qrtr_sendmsg+0x232/0x450 net/qrtr/af_qrtr.c:992
[<ffffffff83ec3c32>] sock_sendmsg_nosec net/socket.c:730 [inline]
[<ffffffff83ec3c32>] __sock_sendmsg+0x52/0xa0 net/socket.c:745
[<ffffffff83ec3d7b>] sock_write_iter+0xfb/0x180 net/socket.c:1158
[<ffffffff816961a7>] call_write_iter include/linux/fs.h:2020 [inline]
[<ffffffff816961a7>] new_sync_write fs/read_write.c:491 [inline]
[<ffffffff816961a7>] vfs_write+0x327/0x590 fs/read_write.c:584
[<ffffffff816966fb>] ksys_write+0x13b/0x170 fs/read_write.c:637
[<ffffffff84b6ddcf>] do_syscall_x64 arch/x86/entry/common.c:51 [inline]
[<ffffffff84b6ddcf>] do_syscall_64+0x3f/0x110 arch/x86/entry/common.c:82
[<ffffffff84c0008b>] entry_SYSCALL_64_after_hwframe+0x63/0x6b[Analysis]
When creating child nodes, if not all child nodes used to store indexes are created, so the child nodes created before the failure should be released.
--- lib/radix-tree.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-)
lib/radix-tree.c +18 -3
@@ -616,9 +616,10 @@ static int __radix_tree_create(struct radix_tree_root *root,struct radix_tree_node *node =NULL , *child;void __rcu **slot = (void __rcu **)&root->xa_head;unsigned long maxindex; -unsigned int shift, offset =0 ; +unsigned int shift, offset =0 , mmshift =0 ;unsigned long max = index;gfp_t gfp =root_gfp_mask (root); +int ret; shift =radix_tree_load_root (root, &child, &maxindex);
@@ -628,6 +629,7 @@ static int __radix_tree_create(struct radix_tree_root *root,if (error <0 )return error; shift = error; + mmshift = error; child =rcu_dereference_raw (root->xa_head); }
@@ -637,8 +639,10 @@ static int __radix_tree_create(struct radix_tree_root *root,/* Have to add a child node. */ child =radix_tree_node_alloc (gfp, node, root, shift, offset,0 ,0 ); -if (!child) -return -ENOMEM ; +if (!child) { + ret = -ENOMEM ; + goto freec; + }rcu_assign_pointer (*slot,node_to_entry (child));if (node) node->count++;
@@ -656,6 +660,17 @@ static int __radix_tree_create(struct radix_tree_root *root,if (slotp) *slotp = slot;return 0 ; +freec: +if (mmshift >0 ) { +struct radix_tree_node *pn; +while (shift < mmshift && node) { + pn = node->parent; +radix_tree_node_rcu_free (&node->rcu_head); + shift +=RADIX_TREE_MAP_SHIFT ; + node = pn; + } + } +return ret; }/*
Signature · 1 line
2.43.0
kernel test robot
build botRe: [PATCH] radix-tree: fix memory leak in radix_tree_insert
kernel test robot noticed the following build warnings:
Hi Lizhi,
kernel test robot noticed the following build warnings:
[auto build test WARNING on akpm-mm/mm-nonmm-unstable]
[also build test WARNING on linus/master v6.7-rc5 next-20231211] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Lizhi-Xu/radix-tree-fix-memory-leak-in-radix_tree_insert/20231211-174951 base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-nonmm-unstable patch link: https://lore.kernel.org/r/20231211094840.642118-1-lizhi.xu%40windriver.com patch subject: [PATCH] radix-tree: fix memory leak in radix_tree_insert config: i386-randconfig-061-20231212 (https://download.01.org/0day-ci/archive/20231212/[email protected]/config) compiler: gcc-7 (Ubuntu 7.5.0-6ubuntu2) 7.5.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231212/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
sparse warnings: (new ones prefixed by >>)
lib/radix-tree.c:266:36: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct xa_node *nodes @@ got struct xa_node [noderef] __rcu *parent @@
lib/radix-tree.c:266:36: sparse: expected struct xa_node *nodes
lib/radix-tree.c:266:36: sparse: got struct xa_node [noderef] __rcu *parent
lib/radix-tree.c:284:29: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct xa_node [noderef] __rcu *parent @@ got struct xa_node *parent @@
lib/radix-tree.c:284:29: sparse: expected struct xa_node [noderef] __rcu *parent
lib/radix-tree.c:284:29: sparse: got struct xa_node *parent
lib/radix-tree.c:344:38: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct xa_node [noderef] __rcu *parent @@ got struct xa_node *nodes @@
lib/radix-tree.c:344:38: sparse: expected struct xa_node [noderef] __rcu *parent
lib/radix-tree.c:344:38: sparse: got struct xa_node *nodes
lib/radix-tree.c:446:54: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct xa_node [noderef] __rcu *parent @@ got struct xa_node *node @@
lib/radix-tree.c:446:54: sparse: expected struct xa_node [noderef] __rcu *parent
lib/radix-tree.c:446:54: sparse: got struct xa_node *node
lib/radix-tree.c:558:24: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct xa_node *parent @@ got struct xa_node [noderef] __rcu *parent @@
lib/radix-tree.c:558:24: sparse: expected struct xa_node *parent
lib/radix-tree.c:558:24: sparse: got struct xa_node [noderef] __rcu *parent
>> lib/radix-tree.c:653:28: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct xa_node *pn @@ got struct xa_node [noderef] __rcu *parent @@
lib/radix-tree.c:653:28: sparse: expected struct xa_node *pn
lib/radix-tree.c:653:28: sparse: got struct xa_node [noderef] __rcu *parent
lib/radix-tree.c:687:31: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct xa_node *[assigned] child @@ got struct xa_node [noderef] __rcu *parent @@
lib/radix-tree.c:687:31: sparse: expected struct xa_node *[assigned] child
lib/radix-tree.c:687:31: sparse: got struct xa_node [noderef] __rcu *parent
lib/radix-tree.c:962:22: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct xa_node *node @@ got struct xa_node [noderef] __rcu *parent @@
lib/radix-tree.c:962:22: sparse: expected struct xa_node *node
lib/radix-tree.c:962:22: sparse: got struct xa_node [noderef] __rcu *parent
lib/radix-tree.c:1022:22: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct xa_node *node @@ got struct xa_node [noderef] __rcu *parent @@
lib/radix-tree.c:1022:22: sparse: expected struct xa_node *node
lib/radix-tree.c:1022:22: sparse: got struct xa_node [noderef] __rcu *parent
lib/radix-tree.c:1542:38: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct xa_node *[assigned] node @@ got struct xa_node [noderef] __rcu *parent @@
lib/radix-tree.c:1542:38: sparse: expected struct xa_node *[assigned] node
lib/radix-tree.c:1542:38: sparse: got struct xa_node [noderef] __rcu *parent
lib/radix-tree.c:1602:28: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct xa_node *nodes @@ got struct xa_node [noderef] __rcu *parent @@
lib/radix-tree.c:1602:28: sparse: expected struct xa_node *nodes
lib/radix-tree.c:1602:28: sparse: got struct xa_node [noderef] __rcu *parent
vim +653 lib/radix-tree.c
581
582 /**
583 * __radix_tree_create - create a slot in a radix tree
584 * @root: radix tree root
585 * @index: index key
586 * @nodep: returns node
587 * @slotp: returns slot
588 *
589 * Create, if necessary, and return the node and slot for an item
590 * at position @index in the radix tree @root.
591 *
592 * Until there is more than one item in the tree, no nodes are
593 * allocated and @root->xa_head is used as a direct slot instead of
594 * pointing to a node, in which case *@nodep will be NULL.
595 *
596 * Returns -ENOMEM, or 0 for success.
597 */
598 static int __radix_tree_create(struct radix_tree_root *root,
599 unsigned long index, struct radix_tree_node **nodep,
600 void __rcu ***slotp)
601 {
602 struct radix_tree_node *node = NULL, *child;
603 void __rcu **slot = (void __rcu **)&root->xa_head;
604 unsigned long maxindex;
605 unsigned int shift, offset = 0, mmshift = 0;
606 unsigned long max = index;
607 gfp_t gfp = root_gfp_mask(root);
608 int ret;
609
610 shift = radix_tree_load_root(root, &child, &maxindex);
611
612 /* Make sure the tree is high enough. */
613 if (max > maxindex) {
614 int error = radix_tree_extend(root, gfp, max, shift);
615 if (error < 0)
616 return error;
617 shift = error;
618 mmshift = error;
619 child = rcu_dereference_raw(root->xa_head);
620 }
621
622 while (shift > 0) {
623 shift -= RADIX_TREE_MAP_SHIFT;
624 if (child == NULL) {
625 /* Have to add a child node. */
626 child = radix_tree_node_alloc(gfp, node, root, shift,
627 offset, 0, 0);
628 if (!child) {
629 ret = -ENOMEM;
630 goto freec;
631 }
632 rcu_assign_pointer(*slot, node_to_entry(child));
633 if (node)
634 node->count++;
635 } else if (!radix_tree_is_internal_node(child))
636 break;
637
638 /* Go a level down */
639 node = entry_to_node(child);
640 offset = radix_tree_descend(node, &child, index);
641 slot = &node->slots[offset];
642 }
643
644 if (nodep)
645 *nodep = node;
646 if (slotp)
647 *slotp = slot;
648 return 0;
649 freec:
650 if (mmshift > 0) {
651 struct radix_tree_node *pn;
652 while (shift < mmshift && node) {
> 653 pn = node->parent;
654 radix_tree_node_rcu_free(&node->rcu_head);
655 shift += RADIX_TREE_MAP_SHIFT;
656 node = pn;
657 }
658 }
659 return ret;
660 }
661
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Re: [PATCH] radix-tree: fix memory leak in radix_tree_insert
Quoted 7 lines · kernel test robot
kernel test robot noticed the following build warnings:
lib/radix-tree.c:558:24: sparse: got structxa_node[noderef]__rcu*parentQuoted 1 line
Quoted 1 line
lib/radix-tree.c:653:28: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected structxa_node*pn @@ got structxa_node[noderef]__rcu*parent @@
lib/radix-tree.c:653:28: sparse: expected structxa_node*pn
651 structradix_tree_node*pn;
652 while (shift < mmshift && node) {Quoted 1 line
653 pn =
node->parent;
It can be clarified here that node->parent is the type just alloced as "struct radix_tree node *", so there is no need to use cast type conversion, Please ignore this warning.
BR,
Lizhi