Hi openeuler-ci-bot, welcome to the openEuler Community.
I'm the Bot here serving you. You can find the instructions on how to interact with me at Here.
If you have any questions, please contact the SIG: Kernel, and any of the maintainers.
In the Linux kernel, the following vulnerability has been resolved:bpf: Call free_htab_elem() after htab_unlock_bucket()For htab of maps, when the map is removed from the htab, it may hold thelast reference of the map. bpf_map_fd_put_ptr() will invokebpf_map_free_id() to free the id of the removed map element. However,bpf_map_fd_put_ptr() is invoked while holding a bucket lock(raw_spin_lock_t), and bpf_map_free_id() attempts to acquire map_idr_lock(spinlock_t), triggering the following lockdep warning: ============================= [ BUG: Invalid wait context ] 6.11.0-rc4+ #49 Not tainted ----------------------------- test_maps/4881 is trying to lock: ffffffff84884578 (map_idr_lock){+...}-{3:3}, at: bpf_map_free_id.part.0+0x21/0x70 other info that might help us debug this: context-{5:5} 2 locks held by test_maps/4881: #0: ffffffff846caf60 (rcu_read_lock){....}-{1:3}, at: bpf_fd_htab_map_update_elem+0xf9/0x270 #1: ffff888149ced148 (&htab->lockdep_key#2){....}-{2:2}, at: htab_map_update_elem+0x178/0xa80 stack backtrace: CPU: 0 UID: 0 PID: 4881 Comm: test_maps Not tainted 6.11.0-rc4+ #49 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), ... Call Trace: <TASK> dump_stack_lvl+0x6e/0xb0 dump_stack+0x10/0x20 __lock_acquire+0x73e/0x36c0 lock_acquire+0x182/0x450 _raw_spin_lock_irqsave+0x43/0x70 bpf_map_free_id.part.0+0x21/0x70 bpf_map_put+0xcf/0x110 bpf_map_fd_put_ptr+0x9a/0xb0 free_htab_elem+0x69/0xe0 htab_map_update_elem+0x50f/0xa80 bpf_fd_htab_map_update_elem+0x131/0x270 htab_map_update_elem+0x50f/0xa80 bpf_fd_htab_map_update_elem+0x131/0x270 bpf_map_update_value+0x266/0x380 __sys_bpf+0x21bb/0x36b0 __x64_sys_bpf+0x45/0x60 x64_sys_call+0x1b2a/0x20d0 do_syscall_64+0x5d/0x100 entry_SYSCALL_64_after_hwframe+0x76/0x7eOne way to fix the lockdep warning is using raw_spinlock_t formap_idr_lock as well. However, bpf_map_alloc_id() invokesidr_alloc_cyclic() after acquiring map_idr_lock, it will trigger asimilar lockdep warning because the slab s lock (s->cpu_slab->lock) isstill a spinlock.Instead of changing map_idr_lock s type, fix the issue by invokinghtab_put_fd_value() after htab_unlock_bucket(). However, only deferringthe invocation of htab_put_fd_value() is not enough, because the old mappointers in htab of maps can not be saved during batched deletion.Therefore, also defer the invocation of free_htab_elem(), so theseto-be-freed elements could be linked together similar to lru map.There are four callers for ->map_fd_put_ptr:(1) alloc_htab_elem() (through htab_put_fd_value())It invokes ->map_fd_put_ptr() under a raw_spinlock_t. The invocation ofhtab_put_fd_value() can not simply move after htab_unlock_bucket(),because the old element has already been stashed in htab->extra_elems.It may be reused immediately after htab_unlock_bucket() and theinvocation of htab_put_fd_value() after htab_unlock_bucket() may releasethe newly-added element incorrectly. Therefore, saving the map pointerof the old element for htab of maps before unlocking the bucket andreleasing the map_ptr after unlock. Beside the map pointer in the oldelement, should do the same thing for the special fields in the oldelement as well.(2) free_htab_elem() (through htab_put_fd_value())Its caller includes __htab_map_lookup_and_delete_elem(),htab_map_delete_elem() and __htab_map_lookup_and_delete_batch().For htab_map_delete_elem(), simply invoke free_htab_elem() afterhtab_unlock_bucket(). For __htab_map_lookup_and_delete_batch(), justlike lru map, linking the to-be-freed element into node_to_free listand invoking free_htab_elem() for these element after unlock. It is safeto reuse batch_flink as the link for node_to_free, because theseelements have been removed from the hash llist.Because htab of maps doesn t support lookup_and_delete operation,__htab_map_lookup_and_delete_elem() doesn t have the problem, so keptit as---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Call free_htab_elem() after htab_unlock_bucket()For htab of maps, when the map is removed from the htab, it may hold thelast reference of the map. bpf_map_fd_put_ptr() will invokebpf_map_free_id() to free the id of the removed map element. However,bpf_map_fd_put_ptr() is invoked while holding a bucket lock(raw_spin_lock_t), and bpf_map_free_id() attempts to acquire map_idr_lock(spinlock_t), triggering the following lockdep warning: ============================= [ BUG: Invalid wait context ] 6.11.0-rc4+ #49 Not tainted ----------------------------- test_maps/4881 is trying to lock: ffffffff84884578 (map_idr_lock){+...}-{3:3}, at: bpf_map_free_id.part.0+0x21/0x70 other info that might help us debug this: context-{5:5} 2 locks held by test_maps/4881: #0: ffffffff846caf60 (rcu_read_lock){....}-{1:3}, at: bpf_fd_htab_map_update_elem+0xf9/0x270 #1: ffff888149ced148 (&htab->lockdep_key#2){....}-{2:2}, at: htab_map_update_elem+0x178/0xa80 stack backtrace: CPU: 0 UID: 0 PID: 4881 Comm: test_maps Not tainted 6.11.0-rc4+ #49 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), ... Call Trace: <TASK> dump_stack_lvl+0x6e/0xb0 dump_stack+0x10/0x20 __lock_acquire+0x73e/0x36c0 lock_acquire+0x182/0x450 _raw_spin_lock_irqsave+0x43/0x70 bpf_map_free_id.part.0+0x21/0x70 bpf_map_put+0xcf/0x110 bpf_map_fd_put_ptr+0x9a/0xb0 free_htab_elem+0x69/0xe0 htab_map_update_elem+0x50f/0xa80 bpf_fd_htab_map_update_elem+0x131/0x270 htab_map_update_elem+0x50f/0xa80 bpf_fd_htab_map_update_elem+0x131/0x270 bpf_map_update_value+0x266/0x380 __sys_bpf+0x21bb/0x36b0 __x64_sys_bpf+0x45/0x60 x64_sys_call+0x1b2a/0x20d0 do_syscall_64+0x5d/0x100 entry_SYSCALL_64_after_hwframe+0x76/0x7eOne way to fix the lockdep warning is using raw_spinlock_t formap_idr_lock as well. However, bpf_map_alloc_id() invokesidr_alloc_cyclic() after acquiring map_idr_lock, it will trigger asimilar lockdep warning because the slab s lock (s->cpu_slab->lock) isstill a spinlock.Instead of changing map_idr_lock s type, fix the issue by invokinghtab_put_fd_value() after htab_unlock_bucket(). However, only deferringthe invocation of htab_put_fd_value() is not enough, because the old mappointers in htab of maps can not be saved during batched deletion.Therefore, also defer the invocation of free_htab_elem(), so theseto-be-freed elements could be linked together similar to lru map.There are four callers for ->map_fd_put_ptr:(1) alloc_htab_elem() (through htab_put_fd_value())It invokes ->map_fd_put_ptr() under a raw_spinlock_t. The invocation ofhtab_put_fd_value() can not simply move after htab_unlock_bucket(),because the old element has already been stashed in htab->extra_elems.It may be reused immediately after htab_unlock_bucket() and theinvocation of htab_put_fd_value() after htab_unlock_bucket() may releasethe newly-added element incorrectly. Therefore, saving the map pointerof the old element for htab of maps before unlocking the bucket andreleasing the map_ptr after unlock. Beside the map pointer in the oldelement, should do the same thing for the special fields in the oldelement as well.(2) free_htab_elem() (through htab_put_fd_value())Its caller includes __htab_map_lookup_and_delete_elem(),htab_map_delete_elem() and __htab_map_lookup_and_delete_batch().For htab_map_delete_elem(), simply invoke free_htab_elem() afterhtab_unlock_bucket(). For __htab_map_lookup_and_delete_batch(), justlike lru map, linking the to-be-freed element into node_to_free listand invoking free_htab_elem() for these element after unlock. It is safeto reuse batch_flink as the link for node_to_free, because theseelements have been removed from the hash llist.Because htab of maps doesn t support lookup_and_delete operation,__htab_map_lookup_and_delete_elem() doesn t have the problem, so keptit as---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Call free_htab_elem() after htab_unlock_bucket()For htab of maps, when the map is removed from the htab, it may hold thelast reference of the map. bpf_map_fd_put_ptr() will invokebpf_map_free_id() to free the id of the removed map element. However,bpf_map_fd_put_ptr() is invoked while holding a bucket lock(raw_spin_lock_t), and bpf_map_free_id() attempts to acquire map_idr_lock(spinlock_t), triggering the following lockdep warning: ============================= [ BUG: Invalid wait context ] 6.11.0-rc4+ #49 Not tainted ----------------------------- test_maps/4881 is trying to lock: ffffffff84884578 (map_idr_lock){+...}-{3:3}, at: bpf_map_free_id.part.0+0x21/0x70 other info that might help us debug this: context-{5:5} 2 locks held by test_maps/4881: #0: ffffffff846caf60 (rcu_read_lock){....}-{1:3}, at: bpf_fd_htab_map_update_elem+0xf9/0x270 #1: ffff888149ced148 (&htab->lockdep_key#2){....}-{2:2}, at: htab_map_update_elem+0x178/0xa80 stack backtrace: CPU: 0 UID: 0 PID: 4881 Comm: test_maps Not tainted 6.11.0-rc4+ #49 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), ... Call Trace: <TASK> dump_stack_lvl+0x6e/0xb0 dump_stack+0x10/0x20 __lock_acquire+0x73e/0x36c0 lock_acquire+0x182/0x450 _raw_spin_lock_irqsave+0x43/0x70 bpf_map_free_id.part.0+0x21/0x70 bpf_map_put+0xcf/0x110 bpf_map_fd_put_ptr+0x9a/0xb0 free_htab_elem+0x69/0xe0 htab_map_update_elem+0x50f/0xa80 bpf_fd_htab_map_update_elem+0x131/0x270 htab_map_update_elem+0x50f/0xa80 bpf_fd_htab_map_update_elem+0x131/0x270 bpf_map_update_value+0x266/0x380 __sys_bpf+0x21bb/0x36b0 __x64_sys_bpf+0x45/0x60 x64_sys_call+0x1b2a/0x20d0 do_syscall_64+0x5d/0x100 entry_SYSCALL_64_after_hwframe+0x76/0x7eOne way to fix the lockdep warning is using raw_spinlock_t formap_idr_lock as well. However, bpf_map_alloc_id() invokesidr_alloc_cyclic() after acquiring map_idr_lock, it will trigger asimilar lockdep warning because the slab s lock (s->cpu_slab->lock) isstill a spinlock.Instead of changing map_idr_lock s type, fix the issue by invokinghtab_put_fd_value() after htab_unlock_bucket(). However, only deferringthe invocation of htab_put_fd_value() is not enough, because the old mappointers in htab of maps can not be saved during batched deletion.Therefore, also defer the invocation of free_htab_elem(), so theseto-be-freed elements could be linked together similar to lru map.There are four callers for ->map_fd_put_ptr:(1) alloc_htab_elem() (through htab_put_fd_value())It invokes ->map_fd_put_ptr() under a raw_spinlock_t. The invocation ofhtab_put_fd_value() can not simply move after htab_unlock_bucket(),because the old element has already been stashed in htab->extra_elems.It may be reused immediately after htab_unlock_bucket() and theinvocation of htab_put_fd_value() after htab_unlock_bucket() may releasethe newly-added element incorrectly. Therefore, saving the map pointerof the old element for htab of maps before unlocking the bucket andreleasing the map_ptr after unlock. Beside the map pointer in the oldelement, should do the same thing for the special fields in the oldelement as well.(2) free_htab_elem() (through htab_put_fd_value())Its caller includes __htab_map_lookup_and_delete_elem(),htab_map_delete_elem() and __htab_map_lookup_and_delete_batch().For htab_map_delete_elem(), simply invoke free_htab_elem() afterhtab_unlock_bucket(). For __htab_map_lookup_and_delete_batch(), justlike lru map, linking the to-be-freed element into node_to_free listand invoking free_htab_elem() for these element after unlock. It is safeto reuse batch_flink as the link for node_to_free, because theseelements have been removed from the hash llist.Because htab of maps doesn t support lookup_and_delete operation,__htab_map_lookup_and_delete_elem() doesn t have the problem, so keptit as---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Call free_htab_elem() after htab_unlock_bucket()For htab of maps, when the map is removed from the htab, it may hold thelast reference of the map. bpf_map_fd_put_ptr() will invokebpf_map_free_id() to free the id of the removed map element. However,bpf_map_fd_put_ptr() is invoked while holding a bucket lock(raw_spin_lock_t), and bpf_map_free_id() attempts to acquire map_idr_lock(spinlock_t), triggering the following lockdep warning: ============================= [ BUG: Invalid wait context ] 6.11.0-rc4+ #49 Not tainted ----------------------------- test_maps/4881 is trying to lock: ffffffff84884578 (map_idr_lock){+...}-{3:3}, at: bpf_map_free_id.part.0+0x21/0x70 other info that might help us debug this: context-{5:5} 2 locks held by test_maps/4881: #0: ffffffff846caf60 (rcu_read_lock){....}-{1:3}, at: bpf_fd_htab_map_update_elem+0xf9/0x270 #1: ffff888149ced148 (&htab->lockdep_key#2){....}-{2:2}, at: htab_map_update_elem+0x178/0xa80 stack backtrace: CPU: 0 UID: 0 PID: 4881 Comm: test_maps Not tainted 6.11.0-rc4+ #49 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), ... Call Trace: <TASK> dump_stack_lvl+0x6e/0xb0 dump_stack+0x10/0x20 __lock_acquire+0x73e/0x36c0 lock_acquire+0x182/0x450 _raw_spin_lock_irqsave+0x43/0x70 bpf_map_free_id.part.0+0x21/0x70 bpf_map_put+0xcf/0x110 bpf_map_fd_put_ptr+0x9a/0xb0 free_htab_elem+0x69/0xe0 htab_map_update_elem+0x50f/0xa80 bpf_fd_htab_map_update_elem+0x131/0x270 htab_map_update_elem+0x50f/0xa80 bpf_fd_htab_map_update_elem+0x131/0x270 bpf_map_update_value+0x266/0x380 __sys_bpf+0x21bb/0x36b0 __x64_sys_bpf+0x45/0x60 x64_sys_call+0x1b2a/0x20d0 do_syscall_64+0x5d/0x100 entry_SYSCALL_64_after_hwframe+0x76/0x7eOne way to fix the lockdep warning is using raw_spinlock_t formap_idr_lock as well. However, bpf_map_alloc_id() invokesidr_alloc_cyclic() after acquiring map_idr_lock, it will trigger asimilar lockdep warning because the slab s lock (s->cpu_slab->lock) isstill a spinlock.Instead of changing map_idr_lock s type, fix the issue by invokinghtab_put_fd_value() after htab_unlock_bucket(). However, only deferringthe invocation of htab_put_fd_value() is not enough, because the old mappointers in htab of maps can not be saved during batched deletion.Therefore, also defer the invocation of free_htab_elem(), so theseto-be-freed elements could be linked together similar to lru map.There are four callers for ->map_fd_put_ptr:(1) alloc_htab_elem() (through htab_put_fd_value())It invokes ->map_fd_put_ptr() under a raw_spinlock_t. The invocation ofhtab_put_fd_value() can not simply move after htab_unlock_bucket(),because the old element has already been stashed in htab->extra_elems.It may be reused immediately after htab_unlock_bucket() and theinvocation of htab_put_fd_value() after htab_unlock_bucket() may releasethe newly-added element incorrectly. Therefore, saving the map pointerof the old element for htab of maps before unlocking the bucket andreleasing the map_ptr after unlock. Beside the map pointer in the oldelement, should do the same thing for the special fields in the oldelement as well.(2) free_htab_elem() (through htab_put_fd_value())Its caller includes __htab_map_lookup_and_delete_elem(),htab_map_delete_elem() and __htab_map_lookup_and_delete_batch().For htab_map_delete_elem(), simply invoke free_htab_elem() afterhtab_unlock_bucket(). For __htab_map_lookup_and_delete_batch(), justlike lru map, linking the to-be-freed element into node_to_free listand invoking free_htab_elem() for these element after unlock. It is safeto reuse batch_flink as the link for node_to_free, because theseelements have been removed from the hash llist.Because htab of maps doesn t support lookup_and_delete operation,__htab_map_lookup_and_delete_elem() doesn t have the problem, so keptit as---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Call free_htab_elem() after htab_unlock_bucket()For htab of maps, when the map is removed from the htab, it may hold thelast reference of the map. bpf_map_fd_put_ptr() will invokebpf_map_free_id() to free the id of the removed map element. However,bpf_map_fd_put_ptr() is invoked while holding a bucket lock(raw_spin_lock_t), and bpf_map_free_id() attempts to acquire map_idr_lock(spinlock_t), triggering the following lockdep warning: ============================= [ BUG: Invalid wait context ] 6.11.0-rc4+ #49 Not tainted ----------------------------- test_maps/4881 is trying to lock: ffffffff84884578 (map_idr_lock){+...}-{3:3}, at: bpf_map_free_id.part.0+0x21/0x70 other info that might help us debug this: context-{5:5} 2 locks held by test_maps/4881: #0: ffffffff846caf60 (rcu_read_lock){....}-{1:3}, at: bpf_fd_htab_map_update_elem+0xf9/0x270 #1: ffff888149ced148 (&htab->lockdep_key#2){....}-{2:2}, at: htab_map_update_elem+0x178/0xa80 stack backtrace: CPU: 0 UID: 0 PID: 4881 Comm: test_maps Not tainted 6.11.0-rc4+ #49 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), ... Call Trace: <TASK> dump_stack_lvl+0x6e/0xb0 dump_stack+0x10/0x20 __lock_acquire+0x73e/0x36c0 lock_acquire+0x182/0x450 _raw_spin_lock_irqsave+0x43/0x70 bpf_map_free_id.part.0+0x21/0x70 bpf_map_put+0xcf/0x110 bpf_map_fd_put_ptr+0x9a/0xb0 free_htab_elem+0x69/0xe0 htab_map_update_elem+0x50f/0xa80 bpf_fd_htab_map_update_elem+0x131/0x270 htab_map_update_elem+0x50f/0xa80 bpf_fd_htab_map_update_elem+0x131/0x270 bpf_map_update_value+0x266/0x380 __sys_bpf+0x21bb/0x36b0 __x64_sys_bpf+0x45/0x60 x64_sys_call+0x1b2a/0x20d0 do_syscall_64+0x5d/0x100 entry_SYSCALL_64_after_hwframe+0x76/0x7eOne way to fix the lockdep warning is using raw_spinlock_t formap_idr_lock as well. However, bpf_map_alloc_id() invokesidr_alloc_cyclic() after acquiring map_idr_lock, it will trigger asimilar lockdep warning because the slab s lock (s->cpu_slab->lock) isstill a spinlock.Instead of changing map_idr_lock s type, fix the issue by invokinghtab_put_fd_value() after htab_unlock_bucket(). However, only deferringthe invocation of htab_put_fd_value() is not enough, because the old mappointers in htab of maps can not be saved during batched deletion.Therefore, also defer the invocation of free_htab_elem(), so theseto-be-freed elements could be linked together similar to lru map.There are four callers for ->map_fd_put_ptr:(1) alloc_htab_elem() (through htab_put_fd_value())It invokes ->map_fd_put_ptr() under a raw_spinlock_t. The invocation ofhtab_put_fd_value() can not simply move after htab_unlock_bucket(),because the old element has already been stashed in htab->extra_elems.It may be reused immediately after htab_unlock_bucket() and theinvocation of htab_put_fd_value() after htab_unlock_bucket() may releasethe newly-added element incorrectly. Therefore, saving the map pointerof the old element for htab of maps before unlocking the bucket andreleasing the map_ptr after unlock. Beside the map pointer in the oldelement, should do the same thing for the special fields in the oldelement as well.(2) free_htab_elem() (through htab_put_fd_value())Its caller includes __htab_map_lookup_and_delete_elem(),htab_map_delete_elem() and __htab_map_lookup_and_delete_batch().For htab_map_delete_elem(), simply invoke free_htab_elem() afterhtab_unlock_bucket(). For __htab_map_lookup_and_delete_batch(), justlike lru map, linking the to-be-freed element into node_to_free listand invoking free_htab_elem() for these element after unlock. It is safeto reuse batch_flink as the link for node_to_free, because theseelements have been removed from the hash llist.Because htab of maps doesn t support lookup_and_delete operation,__htab_map_lookup_and_delete_elem() doesn t have the problem, so keptit as---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Call free_htab_elem() after htab_unlock_bucket()For htab of maps, when the map is removed from the htab, it may hold thelast reference of the map. bpf_map_fd_put_ptr() will invokebpf_map_free_id() to free the id of the removed map element. However,bpf_map_fd_put_ptr() is invoked while holding a bucket lock(raw_spin_lock_t), and bpf_map_free_id() attempts to acquire map_idr_lock(spinlock_t), triggering the following lockdep warning: ============================= [ BUG: Invalid wait context ] 6.11.0-rc4+ #49 Not tainted ----------------------------- test_maps/4881 is trying to lock: ffffffff84884578 (map_idr_lock){+...}-{3:3}, at: bpf_map_free_id.part.0+0x21/0x70 other info that might help us debug this: context-{5:5} 2 locks held by test_maps/4881: #0: ffffffff846caf60 (rcu_read_lock){....}-{1:3}, at: bpf_fd_htab_map_update_elem+0xf9/0x270 #1: ffff888149ced148 (&htab->lockdep_key#2){....}-{2:2}, at: htab_map_update_elem+0x178/0xa80 stack backtrace: CPU: 0 UID: 0 PID: 4881 Comm: test_maps Not tainted 6.11.0-rc4+ #49 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), ... Call Trace: <TASK> dump_stack_lvl+0x6e/0xb0 dump_stack+0x10/0x20 __lock_acquire+0x73e/0x36c0 lock_acquire+0x182/0x450 _raw_spin_lock_irqsave+0x43/0x70 bpf_map_free_id.part.0+0x21/0x70 bpf_map_put+0xcf/0x110 bpf_map_fd_put_ptr+0x9a/0xb0 free_htab_elem+0x69/0xe0 htab_map_update_elem+0x50f/0xa80 bpf_fd_htab_map_update_elem+0x131/0x270 htab_map_update_elem+0x50f/0xa80 bpf_fd_htab_map_update_elem+0x131/0x270 bpf_map_update_value+0x266/0x380 __sys_bpf+0x21bb/0x36b0 __x64_sys_bpf+0x45/0x60 x64_sys_call+0x1b2a/0x20d0 do_syscall_64+0x5d/0x100 entry_SYSCALL_64_after_hwframe+0x76/0x7eOne way to fix the lockdep warning is using raw_spinlock_t formap_idr_lock as well. However, bpf_map_alloc_id() invokesidr_alloc_cyclic() after acquiring map_idr_lock, it will trigger asimilar lockdep warning because the slab s lock (s->cpu_slab->lock) isstill a spinlock.Instead of changing map_idr_lock s type, fix the issue by invokinghtab_put_fd_value() after htab_unlock_bucket(). However, only deferringthe invocation of htab_put_fd_value() is not enough, because the old mappointers in htab of maps can not be saved during batched deletion.Therefore, also defer the invocation of free_htab_elem(), so theseto-be-freed elements could be linked together similar to lru map.There are four callers for ->map_fd_put_ptr:(1) alloc_htab_elem() (through htab_put_fd_value())It invokes ->map_fd_put_ptr() under a raw_spinlock_t. The invocation ofhtab_put_fd_value() can not simply move after htab_unlock_bucket(),because the old element has already been stashed in htab->extra_elems.It may be reused immediately after htab_unlock_bucket() and theinvocation of htab_put_fd_value() after htab_unlock_bucket() may releasethe newly-added element incorrectly. Therefore, saving the map pointerof the old element for htab of maps before unlocking the bucket andreleasing the map_ptr after unlock. Beside the map pointer in the oldelement, should do the same thing for the special fields in the oldelement as well.(2) free_htab_elem() (through htab_put_fd_value())Its caller includes __htab_map_lookup_and_delete_elem(),htab_map_delete_elem() and __htab_map_lookup_and_delete_batch().For htab_map_delete_elem(), simply invoke free_htab_elem() afterhtab_unlock_bucket(). For __htab_map_lookup_and_delete_batch(), justlike lru map, linking the to-be-freed element into node_to_free listand invoking free_htab_elem() for these element after unlock. It is safeto reuse batch_flink as the link for node_to_free, because theseelements have been removed from the hash llist.Because htab of maps doesn t support lookup_and_delete operation,__htab_map_lookup_and_delete_elem() doesn t have the problem, so keptit as---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Call free_htab_elem() after htab_unlock_bucket()For htab of maps, when the map is removed from the htab, it may hold thelast reference of the map. bpf_map_fd_put_ptr() will invokebpf_map_free_id() to free the id of the removed map element. However,bpf_map_fd_put_ptr() is invoked while holding a bucket lock(raw_spin_lock_t), and bpf_map_free_id() attempts to acquire map_idr_lock(spinlock_t), triggering the following lockdep warning: ============================= [ BUG: Invalid wait context ] 6.11.0-rc4+ #49 Not tainted ----------------------------- test_maps/4881 is trying to lock: ffffffff84884578 (map_idr_lock){+...}-{3:3}, at: bpf_map_free_id.part.0+0x21/0x70 other info that might help us debug this: context-{5:5} 2 locks held by test_maps/4881: #0: ffffffff846caf60 (rcu_read_lock){....}-{1:3}, at: bpf_fd_htab_map_update_elem+0xf9/0x270 #1: ffff888149ced148 (&htab->lockdep_key#2){....}-{2:2}, at: htab_map_update_elem+0x178/0xa80 stack backtrace: CPU: 0 UID: 0 PID: 4881 Comm: test_maps Not tainted 6.11.0-rc4+ #49 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), ... Call Trace: <TASK> dump_stack_lvl+0x6e/0xb0 dump_stack+0x10/0x20 __lock_acquire+0x73e/0x36c0 lock_acquire+0x182/0x450 _raw_spin_lock_irqsave+0x43/0x70 bpf_map_free_id.part.0+0x21/0x70 bpf_map_put+0xcf/0x110 bpf_map_fd_put_ptr+0x9a/0xb0 free_htab_elem+0x69/0xe0 htab_map_update_elem+0x50f/0xa80 bpf_fd_htab_map_update_elem+0x131/0x270 htab_map_update_elem+0x50f/0xa80 bpf_fd_htab_map_update_elem+0x131/0x270 bpf_map_update_value+0x266/0x380 __sys_bpf+0x21bb/0x36b0 __x64_sys_bpf+0x45/0x60 x64_sys_call+0x1b2a/0x20d0 do_syscall_64+0x5d/0x100 entry_SYSCALL_64_after_hwframe+0x76/0x7eOne way to fix the lockdep warning is using raw_spinlock_t formap_idr_lock as well. However, bpf_map_alloc_id() invokesidr_alloc_cyclic() after acquiring map_idr_lock, it will trigger asimilar lockdep warning because the slab s lock (s->cpu_slab->lock) isstill a spinlock.Instead of changing map_idr_lock s type, fix the issue by invokinghtab_put_fd_value() after htab_unlock_bucket(). However, only deferringthe invocation of htab_put_fd_value() is not enough, because the old mappointers in htab of maps can not be saved during batched deletion.Therefore, also defer the invocation of free_htab_elem(), so theseto-be-freed elements could be linked together similar to lru map.There are four callers for ->map_fd_put_ptr:(1) alloc_htab_elem() (through htab_put_fd_value())It invokes ->map_fd_put_ptr() under a raw_spinlock_t. The invocation ofhtab_put_fd_value() can not simply move after htab_unlock_bucket(),because the old element has already been stashed in htab->extra_elems.It may be reused immediately after htab_unlock_bucket() and theinvocation of htab_put_fd_value() after htab_unlock_bucket() may releasethe newly-added element incorrectly. Therefore, saving the map pointerof the old element for htab of maps before unlocking the bucket andreleasing the map_ptr after unlock. Beside the map pointer in the oldelement, should do the same thing for the special fields in the oldelement as well.(2) free_htab_elem() (through htab_put_fd_value())Its caller includes __htab_map_lookup_and_delete_elem(),htab_map_delete_elem() and __htab_map_lookup_and_delete_batch().For htab_map_delete_elem(), simply invoke free_htab_elem() afterhtab_unlock_bucket(). For __htab_map_lookup_and_delete_batch(), justlike lru map, linking the to-be-freed element into node_to_free listand invoking free_htab_elem() for these element after unlock. It is safeto reuse batch_flink as the link for node_to_free, because theseelements have been removed from the hash llist.Because htab of maps doesn t support lookup_and_delete operation,__htab_map_lookup_and_delete_elem() doesn t have the problem, so keptit as---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Call free_htab_elem() after htab_unlock_bucket()For htab of maps, when the map is removed from the htab, it may hold thelast reference of the map. bpf_map_fd_put_ptr() will invokebpf_map_free_id() to free the id of the removed map element. However,bpf_map_fd_put_ptr() is invoked while holding a bucket lock(raw_spin_lock_t), and bpf_map_free_id() attempts to acquire map_idr_lock(spinlock_t), triggering the following lockdep warning: ============================= [ BUG: Invalid wait context ] 6.11.0-rc4+ #49 Not tainted ----------------------------- test_maps/4881 is trying to lock: ffffffff84884578 (map_idr_lock){+...}-{3:3}, at: bpf_map_free_id.part.0+0x21/0x70 other info that might help us debug this: context-{5:5} 2 locks held by test_maps/4881: #0: ffffffff846caf60 (rcu_read_lock){....}-{1:3}, at: bpf_fd_htab_map_update_elem+0xf9/0x270 #1: ffff888149ced148 (&htab->lockdep_key#2){....}-{2:2}, at: htab_map_update_elem+0x178/0xa80 stack backtrace: CPU: 0 UID: 0 PID: 4881 Comm: test_maps Not tainted 6.11.0-rc4+ #49 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), ... Call Trace: <TASK> dump_stack_lvl+0x6e/0xb0 dump_stack+0x10/0x20 __lock_acquire+0x73e/0x36c0 lock_acquire+0x182/0x450 _raw_spin_lock_irqsave+0x43/0x70 bpf_map_free_id.part.0+0x21/0x70 bpf_map_put+0xcf/0x110 bpf_map_fd_put_ptr+0x9a/0xb0 free_htab_elem+0x69/0xe0 htab_map_update_elem+0x50f/0xa80 bpf_fd_htab_map_update_elem+0x131/0x270 htab_map_update_elem+0x50f/0xa80 bpf_fd_htab_map_update_elem+0x131/0x270 bpf_map_update_value+0x266/0x380 __sys_bpf+0x21bb/0x36b0 __x64_sys_bpf+0x45/0x60 x64_sys_call+0x1b2a/0x20d0 do_syscall_64+0x5d/0x100 entry_SYSCALL_64_after_hwframe+0x76/0x7eOne way to fix the lockdep warning is using raw_spinlock_t formap_idr_lock as well. However, bpf_map_alloc_id() invokesidr_alloc_cyclic() after acquiring map_idr_lock, it will trigger asimilar lockdep warning because the slab s lock (s->cpu_slab->lock) isstill a spinlock.Instead of changing map_idr_lock s type, fix the issue by invokinghtab_put_fd_value() after htab_unlock_bucket(). However, only deferringthe invocation of htab_put_fd_value() is not enough, because the old mappointers in htab of maps can not be saved during batched deletion.Therefore, also defer the invocation of free_htab_elem(), so theseto-be-freed elements could be linked together similar to lru map.There are four callers for ->map_fd_put_ptr:(1) alloc_htab_elem() (through htab_put_fd_value())It invokes ->map_fd_put_ptr() under a raw_spinlock_t. The invocation ofhtab_put_fd_value() can not simply move after htab_unlock_bucket(),because the old element has already been stashed in htab->extra_elems.It may be reused immediately after htab_unlock_bucket() and theinvocation of htab_put_fd_value() after htab_unlock_bucket() may releasethe newly-added element incorrectly. Therefore, saving the map pointerof the old element for htab of maps before unlocking the bucket andreleasing the map_ptr after unlock. Beside the map pointer in the oldelement, should do the same thing for the special fields in the oldelement as well.(2) free_htab_elem() (through htab_put_fd_value())Its caller includes __htab_map_lookup_and_delete_elem(),htab_map_delete_elem() and __htab_map_lookup_and_delete_batch().For htab_map_delete_elem(), simply invoke free_htab_elem() afterhtab_unlock_bucket(). For __htab_map_lookup_and_delete_batch(), justlike lru map, linking the to-be-freed element into node_to_free listand invoking free_htab_elem() for these element after unlock. It is safeto reuse batch_flink as the link for node_to_free, because theseelements have been removed from the hash llist.Because htab of maps doesn t support lookup_and_delete operation,__htab_map_lookup_and_delete_elem() doesn t have the problem, so keptit as---truncated---
In the Linux kernel, the following vulnerability has been resolved:bpf: Call free_htab_elem() after htab_unlock_bucket()For htab of maps, when the map is removed from the htab, it may hold thelast reference of the map. bpf_map_fd_put_ptr() will invokebpf_map_free_id() to free the id of the removed map element. However,bpf_map_fd_put_ptr() is invoked while holding a bucket lock(raw_spin_lock_t), and bpf_map_free_id() attempts to acquire map_idr_lock(spinlock_t), triggering the following lockdep warning: ============================= [ BUG: Invalid wait context ] 6.11.0-rc4+ #49 Not tainted ----------------------------- test_maps/4881 is trying to lock: ffffffff84884578 (map_idr_lock){+...}-{3:3}, at: bpf_map_free_id.part.0+0x21/0x70 other info that might help us debug this: context-{5:5} 2 locks held by test_maps/4881: #0: ffffffff846caf60 (rcu_read_lock){....}-{1:3}, at: bpf_fd_htab_map_update_elem+0xf9/0x270 #1: ffff888149ced148 (&htab->lockdep_key#2){....}-{2:2}, at: htab_map_update_elem+0x178/0xa80 stack backtrace: CPU: 0 UID: 0 PID: 4881 Comm: test_maps Not tainted 6.11.0-rc4+ #49 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), ... Call Trace: <TASK> dump_stack_lvl+0x6e/0xb0 dump_stack+0x10/0x20 __lock_acquire+0x73e/0x36c0 lock_acquire+0x182/0x450 _raw_spin_lock_irqsave+0x43/0x70 bpf_map_free_id.part.0+0x21/0x70 bpf_map_put+0xcf/0x110 bpf_map_fd_put_ptr+0x9a/0xb0 free_htab_elem+0x69/0xe0 htab_map_update_elem+0x50f/0xa80 bpf_fd_htab_map_update_elem+0x131/0x270 htab_map_update_elem+0x50f/0xa80 bpf_fd_htab_map_update_elem+0x131/0x270 bpf_map_update_value+0x266/0x380 __sys_bpf+0x21bb/0x36b0 __x64_sys_bpf+0x45/0x60 x64_sys_call+0x1b2a/0x20d0 do_syscall_64+0x5d/0x100 entry_SYSCALL_64_after_hwframe+0x76/0x7eOne way to fix the lockdep warning is using raw_spinlock_t formap_idr_lock as well. However, bpf_map_alloc_id() invokesidr_alloc_cyclic() after acquiring map_idr_lock, it will trigger asimilar lockdep warning because the slab s lock (s->cpu_slab->lock) isstill a spinlock.Instead of changing map_idr_lock s type, fix the issue by invokinghtab_put_fd_value() after htab_unlock_bucket(). However, only deferringthe invocation of htab_put_fd_value() is not enough, because the old mappointers in htab of maps can not be saved during batched deletion.Therefore, also defer the invocation of free_htab_elem(), so theseto-be-freed elements could be linked together similar to lru map.There are four callers for ->map_fd_put_ptr:(1) alloc_htab_elem() (through htab_put_fd_value())It invokes ->map_fd_put_ptr() under a raw_spinlock_t. The invocation ofhtab_put_fd_value() can not simply move after htab_unlock_bucket(),because the old element has already been stashed in htab->extra_elems.It may be reused immediately after htab_unlock_bucket() and theinvocation of htab_put_fd_value() after htab_unlock_bucket() may releasethe newly-added element incorrectly. Therefore, saving the map pointerof the old element for htab of maps before unlocking the bucket andreleasing the map_ptr after unlock. Beside the map pointer in the oldelement, should do the same thing for the special fields in the oldelement as well.(2) free_htab_elem() (through htab_put_fd_value())Its caller includes __htab_map_lookup_and_delete_elem(),htab_map_delete_elem() and __htab_map_lookup_and_delete_batch().For htab_map_delete_elem(), simply invoke free_htab_elem() afterhtab_unlock_bucket(). For __htab_map_lookup_and_delete_batch(), justlike lru map, linking the to-be-freed element into node_to_free listand invoking free_htab_elem() for these element after unlock. It is safeto reuse batch_flink as the link for node_to_free, because theseelements have been removed from the hash llist.Because htab of maps doesn t support lookup_and_delete operation,__htab_map_lookup_and_delete_elem() doesn t have the problem, so keptit as---truncated---