lua-lsm: fix unregister and module lifetime handling - #16
Draft
chenzongyao200127 wants to merge 138 commits into
Draft
lua-lsm: fix unregister and module lifetime handling#16chenzongyao200127 wants to merge 138 commits into
chenzongyao200127 wants to merge 138 commits into
Conversation
This reverts commit 97169cd.
The folling is main instructions: export PATH="$(brew --prefix make)/libexec/gnubin:$PATH" export PATH="$(brew --prefix llvm)/bin:$PATH" export PATH="$(brew --prefix lld)/bin:$PATH" # Eliminate compile errors of scripts/mod/file2alias.c export HOSTCFLAGS="-D_UUID_T -D__GETHOSTUUID_H" # Maybe the symlink is missed on macOS #ln -s ../../../scripts/syscall.tbl arch/arm64/tools/syscall_64.tbl #ln -s qcom,sm8550-dispcc.h include/dt-bindings/clock/qcom,sm8650-dispcc.h #make ARCH=arm64 LLVM=1 #make LLVM=1 menuconfig #make LLVM=1 -j8 Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
When developing a dedicated LSM module, we need to operate on the file object within the LSM function, such as retrieving the path. However, in `security_file_alloc()`, the passed-in `filp` is only a valid pointer; the content of `filp` is completely uninitialized and entirely random, which confuses the LSM function. Therefore, it is necessary to call `security_file_alloc()` only after the main fields of the `filp` object have been initialized. This patch only moves the call to `security_file_alloc()` to the end of the `init_file()` function. Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Standard C provides basic library functions for jumping between functions. They were introduced to support the upcoming Lua language interpreter, which uses the setjmp/longjmp functions to implement exception handling. Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Standard C provides basic library functions for jumping between functions. They were introduced to support the upcoming Lua language interpreter, which uses the setjmp/longjmp functions to implement exception handling. Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Lua is an extension programming language designed to support general procedural programming with data description facilities. It also offers good support for object-oriented programming, functional programming, and data-driven programming. Lua is intended to be used as a powerful, light-weight scripting language for any program that needs one. Lua is implemented as a library, written in clean C (that is, in the common subset of ANSI C and C++). Lua is embedded in the kernel. Leveraging Lua's simplicity and powerful metaprogramming capabilities, it allows the use of scripting languages to develop complex security access control policies. The reason for choosing version 5.1 is that Lua has been mature enough since version 5.1, and secondly, LuaJIT may be introduced in the future for JIT acceleration. Currently, LuaJIT is compatible with version 5.1. Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
queue.h and tree.h are borrowed from freebsd
d342ae67192f ("uath: add support for GCMP-128 encryption")
bitmap.h is borrowed from bitops of latest netbsd.
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Fixes for queue and tree
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com> Co-developed-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
This module leverages Lua's metaprogramming capabilities to develop complex access control logic and policies in Lua. Let us using a programmatic approach close to natural language, significantly lowers the barrier to entry for developing LSM access control. This module has the following notable features: * Supports developing LSM policies as mini-programs or LSM plugins. Multiple mini-programs or LSM plugins can be loaded simultaneously, and dynamic, on-demand uninstallation is supported. * Each mini-program runs in a secure sandbox environment. Script errors will not trigger kernel panics, and mini-programs are isolated from each other, ensuring no impact. * Mini-programs interact with the kernel through a specific, limited API, ensuring kernel security. * The LSM module features deep integration with the Lua language, enabling the most natural way to share data and set kernel object attributes. Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com> Co-developed-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
The reason is that the modules_lock is held for a period of time during module registration. A softirq occurs within this critical section, and the softirq handler reenters the LSM function, causing a deadlock. This issue can be resolved by disabling softirq while holding the modules_lock lock during module registration. Some logs are as follows: [28031.294632] rcu: INFO: rcu_preempt self-detected stall on CPU [28031.294801] rcu: 2-...!: (886811 ticks this GP) idle=ea9c/1/0x4000000000000000 softirq=243287/243287 fqs=0 [28031.295043] rcu: (t=887418 jiffies g=263373 q=454 ncpus=4) [28031.295183] rcu: rcu_preempt kthread starved for 887418 jiffies! g263373 f0x0 RCU_GP_WAIT_FQS(5) ->state=0x0 ->cpu=2 [28031.295524] rcu: Unless rcu_preempt kthread gets sufficient CPU time, OOM is now expected behavior. [28031.295872] rcu: RCU grace-period kthread stack dump: [28031.296001] task:rcu_preempt state:R running task stack:0 pid:15 tgid:15 ppid:2 task_flags:0x208040 flags:0x00000010 [28031.296319] Call trace: [28031.296381] __switch_to+0x194/0x2b4 (T) [28031.296484] __schedule+0x5b4/0x980 [28031.296572] schedule+0x54/0xf8 [28031.296652] schedule_timeout+0x88/0xf8 [28031.296750] rcu_gp_fqs_loop+0x1c4/0x6b0 [28031.296851] rcu_gp_kthread+0x60/0x134 [28031.296946] kthread+0x140/0x254 [28031.297030] ret_from_fork+0x10/0x20 [28031.297123] Sending NMI from CPU 2 to CPUs 1: [28031.297242] NMI backtrace for cpu 1 [28031.297247] CPU: 1 UID: 0 PID: 81146 Comm: sh Not tainted 6.17.0-rc3+ #511 PREEMPT [28031.297249] Hardware name: QEMU QEMU Virtual Machine, BIOS edk2-stable202408-prebuilt.qemu.org 08/13/2024 [28031.297250] pstate: 01400005 (nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--) [28031.297250] pc : queued_read_lock_slowpath+0x80/0x14c [28031.297253] lr : _raw_read_lock_bh+0x64/0x68 [28031.297254] sp : ffff800088ee39e0 [28031.297254] x29: ffff800088ee39e0 x28: 0000000000002e2e x27: 0000000000000501 [28031.297256] x26: 0000000000000030 x25: 2f2f2f2f2f2f2f2f x24: 61c8864680b583eb [28031.297257] x23: fefefefefefefeff x22: 0000000000000000 x21: ffff0000c2671138 [28031.297257] x20: 0000000000000081 x19: 00001643fef959e4 x18: 0000000000000000 [28031.297258] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000 [28031.297259] x14: 0000000000000000 x13: 0000000000000000 x12: 8080808080808000 [28031.297259] x11: 000000000000002e x10: 0000000000000018 x9 : 0000000000000000 [28031.297260] x8 : 00000000000008ff x7 : 0000000000000000 x6 : 0000000000000000 [28031.297261] x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff800088ee3c98 [28031.297261] x2 : 0000000000000000 x1 : 0000000000013cee x0 : ffff8000818ae3c8 [28031.297262] Call trace: [28031.297262] queued_read_lock_slowpath+0x80/0x14c (P) [28031.297264] _raw_read_lock_bh+0x64/0x68 [28031.297265] lua_lsm_inode_permission+0x54/0x35c [28031.297268] security_inode_permission+0x54/0xb0 [28031.297269] inode_permission+0x64/0x170 [28031.297270] link_path_walk+0xb4/0x388 [28031.297272] path_lookupat+0x68/0x120 [28031.297272] filename_lookup+0xe0/0x1e0 [28031.297273] vfs_statx+0x7c/0x1a0 [28031.297276] vfs_fstatat+0xb4/0xe0 [28031.297277] __arm64_sys_newfstatat+0x68/0xa8 [28031.297278] invoke_syscall+0x40/0xf8 [28031.297280] el0_svc_common+0xa8/0xd8 [28031.297281] do_el0_svc+0x1c/0x28 [28031.297282] el0_svc+0x38/0x8c [28031.297283] el0t_64_sync_handler+0x84/0x12c [28031.297284] el0t_64_sync+0x198/0x19c [28031.298239] CPU: 2 UID: 0 PID: 81145 Comm: cat Not tainted 6.17.0-rc3+ #511 PREEMPT [28031.303082] Hardware name: QEMU QEMU Virtual Machine, BIOS edk2-stable202408-prebuilt.qemu.org 08/13/2024 [28031.303326] pstate: 01400005 (nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--) [28031.303504] pc : queued_read_lock_slowpath+0x80/0x14c [28031.303634] lr : _raw_read_lock_bh+0x64/0x68 [28031.303743] sp : ffff8000818ebe00 [28031.303828] x29: ffff8000818ebe00 x28: 0000000000000200 x27: 000000000000000a [28031.304011] x26: ffff800081788000 x25: ffff8000800fa104 x24: 0000000000000001 [28031.304192] x23: 0000000000000000 x22: 000000000000000a x21: 0000000000000000 [28031.304374] x20: ffff000008774600 x19: 00001643fef8ae04 x18: 0000000000000000 [28031.304556] x17: ffff80007e099000 x16: ffff8000818e8000 x15: 0000000000000000 [28031.304739] x14: 0000000000000004 x13: ffff0000ff6187a8 x12: 0000000000000002 [28031.304922] x11: ffff0000c2288a18 x10: 0000000000000018 x9 : 0000000000000000 [28031.305104] x8 : 00000000000008ff x7 : 7fffffffffffffff x6 : 00003d0900007d00 [28031.305285] x5 : ffff800081874120 x4 : 0000000000000008 x3 : ffff80008a153710 [28031.305470] x2 : 00000000000404d4 x1 : 00000000000138ce x0 : ffff8000818ae3c8 [28031.305651] Call trace: [28031.305714] queued_read_lock_slowpath+0x80/0x14c (P) [28031.305844] _raw_read_lock_bh+0x64/0x68 [28031.305945] lua_lsm_cred_free+0x54/0x2bc [28031.306048] security_cred_free+0x5c/0x90 [28031.306151] put_cred_rcu+0x28/0x15c [28031.306244] rcu_core+0x2c0/0x5e0 [28031.306330] rcu_core_si+0x10/0x1c [28031.306418] handle_softirqs+0xdc/0x200 [28031.306517] __do_softirq+0x14/0x20 [28031.306686] ____do_softirq+0x10/0x1c [28031.306782] call_on_irq_stack+0x30/0x48 [28031.306884] do_softirq_own_stack+0x1c/0x28 [28031.306993] __irq_exit_rcu+0x54/0xf8 [28031.307087] irq_exit_rcu+0x10/0x1c [28031.307176] el1_interrupt+0x38/0x54 [28031.307269] el1h_64_irq_handler+0x18/0x24 [28031.307375] el1h_64_irq+0x6c/0x70 [28031.307463] lua_module_register+0x550/0x588 (P) [28031.307582] register_write+0x78/0xac [28031.307676] vfs_write+0x160/0x3bc [28031.307764] ksys_write+0x70/0xe4 [28031.307849] __arm64_sys_write+0x1c/0x28 [28031.307950] invoke_syscall+0x40/0xf8 [28031.308044] el0_svc_common+0xa8/0xd8 [28031.308138] do_el0_svc+0x1c/0x28 [28031.308225] el0_svc+0x38/0x8c [28031.308311] el0t_64_sync_handler+0x84/0x12c [28031.308422] el0t_64_sync+0x198/0x19c
When interrupts are disabled, file system operations triggered by memory
allocation may cause a potential deadlock.
The log is as follows:
[ 37.041540] =====================================================
[ 37.041790] WARNING: SOFTIRQ-safe -> SOFTIRQ-unsafe lock order detected
[ 37.042170] 6.17.0-rc3+ #515 Tainted: G W
[ 37.042492] -----------------------------------------------------
[ 37.042953] cat/1610 [HC0[0]:SC0[2]:HE1:SE0] is trying to acquire:
[ 37.043316] ffff800081f2b9f8 (fs_reclaim){+.+.}-{0:0}, at: __kmalloc_noprof+0xb0/0x4d4
[ 37.043783]
[ 37.043783] and this task is already holding:
[ 37.044121] ffff0000c177e138 (&dict->lock){+.-.}-{3:3}, at: kvcache_incr+0x68/0x21c
[ 37.044569] which would create a new lock dependency:
[ 37.044861] (&dict->lock){+.-.}-{3:3} -> (fs_reclaim){+.+.}-{0:0}
[ 37.045222]
[ 37.045222] but this new dependency connects a SOFTIRQ-irq-safe lock:
[ 37.045685] (&dict->lock){+.-.}-{3:3}
[ 37.045687]
[ 37.045687] ... which became SOFTIRQ-irq-safe at:
[ 37.046273] lock_acquire+0x118/0x26c
[ 37.046479] _raw_write_lock+0x4c/0x88
[ 37.046736] kvcache_dict_free+0x24/0x104
[ 37.046950] lua_lsm_inode_free_security_rcu+0x1d4/0x274
[ 37.047231] inode_free_by_rcu+0x54/0x9c
[ 37.047442] rcu_core+0x474/0xa50
[ 37.047623] rcu_core_si+0x10/0x1c
[ 37.047805] handle_softirqs+0x178/0x42c
[ 37.048018] __do_softirq+0x14/0x20
[ 37.048205] ____do_softirq+0x10/0x1c
[ 37.048404] call_on_irq_stack+0x30/0x48
[ 37.048614] do_softirq_own_stack+0x1c/0x28
[ 37.048838] __irq_exit_rcu+0xd4/0x194
[ 37.049039] irq_exit_rcu+0x10/0x34
[ 37.049226] el1_interrupt+0x38/0x54
[ 37.049418] el1h_64_irq_handler+0x18/0x24
[ 37.049636] el1h_64_irq+0x6c/0x70
[ 37.049818] do_idle+0xe8/0x26c
[ 37.049994] cpu_startup_entry+0x34/0x38
[ 37.050206] kernel_init+0x0/0x128
[ 37.050389] start_kernel+0x304/0x3c0
[ 37.050659] __primary_switched+0x88/0x90
[ 37.050881]
[ 37.050881] to a SOFTIRQ-irq-unsafe lock:
[ 37.051169] (fs_reclaim){+.+.}-{0:0}
[ 37.051171]
[ 37.051171] ... which became SOFTIRQ-irq-unsafe at:
[ 37.051699] ...
[ 37.051704] lock_acquire+0x118/0x26c
[ 37.051997] fs_reclaim_acquire+0x64/0xd0
[ 37.052215] mem_cgroup_css_alloc+0xdc/0x6e4
[ 37.052436] cgroup_init_subsys+0x7c/0x1d0
[ 37.052642] cgroup_init+0x2d8/0x490
[ 37.052822] start_kernel+0x2f4/0x3c0
[ 37.053006] __primary_switched+0x88/0x90
[ 37.053210]
[ 37.053210] other info that might help us debug this:
[ 37.053210]
[ 37.053598] Possible interrupt unsafe locking scenario:
[ 37.053598]
[ 37.053929] CPU0 CPU1
[ 37.054152] ---- ----
[ 37.054372] lock(fs_reclaim);
[ 37.054649] local_irq_disable();
[ 37.055469] lock(&dict->lock);
[ 37.055751] lock(fs_reclaim);
[ 37.056024] <Interrupt>
[ 37.056151] lock(&dict->lock);
[ 37.056316]
[ 37.056316] *** DEADLOCK ***
[ 37.056316]
[ 37.056602] 2 locks held by cat/1610:
[ 37.056779] #0: ffff800081fdaf18 (modules_lock){++.-}-{3:3}, at: lua_lsm_file_permission+0x58/0x36c
[ 37.057221] openanolis#1: ffff0000c177e138 (&dict->lock){+.-.}-{3:3}, at: kvcache_incr+0x68/0x21c
[ 37.057611]
[ 37.057611] the dependencies between SOFTIRQ-irq-safe lock and the holding lock:
[ 37.058091] -> (&dict->lock){+.-.}-{3:3} {
[ 37.058303] HARDIRQ-ON-W at:
[ 37.058495] lock_acquire+0x118/0x26c
[ 37.058777] _raw_write_lock+0x4c/0x88
[ 37.059053] kvcache_dict_free+0x24/0x104
[ 37.059353] lua_lsm_file_free_security+0x210/0x2bc
[ 37.059691] security_file_free+0x5c/0xa4
[ 37.059991] __fput+0x1a0/0x2f0
[ 37.060242] delayed_fput+0x44/0x58
[ 37.060514] process_one_work+0x210/0x548
[ 37.060815] worker_thread+0x244/0x380
[ 37.061096] kthread+0x138/0x260
[ 37.061348] ret_from_fork+0x10/0x20
[ 37.061622] IN-SOFTIRQ-W at:
[ 37.061790] lock_acquire+0x118/0x26c
[ 37.062117] _raw_write_lock+0x4c/0x88
[ 37.062405] kvcache_dict_free+0x24/0x104
[ 37.062730] lua_lsm_inode_free_security_rcu+0x1d4/0x274
[ 37.063097] inode_free_by_rcu+0x54/0x9c
[ 37.063390] rcu_core+0x474/0xa50
[ 37.063652] rcu_core_si+0x10/0x1c
[ 37.063917] handle_softirqs+0x178/0x42c
[ 37.064213] __do_softirq+0x14/0x20
[ 37.064475] ____do_softirq+0x10/0x1c
[ 37.064739] call_on_irq_stack+0x30/0x48
[ 37.065014] do_softirq_own_stack+0x1c/0x28
[ 37.065307] __irq_exit_rcu+0xd4/0x194
[ 37.065583] irq_exit_rcu+0x10/0x34
[ 37.065901] el1_interrupt+0x38/0x54
[ 37.066155] el1h_64_irq_handler+0x18/0x24
[ 37.066399] el1h_64_irq+0x6c/0x70
[ 37.066660] do_idle+0xe8/0x26c
[ 37.066891] cpu_startup_entry+0x34/0x38
[ 37.067168] kernel_init+0x0/0x128
[ 37.067418] start_kernel+0x304/0x3c0
[ 37.067679] __primary_switched+0x88/0x90
[ 37.067959] INITIAL USE at:
[ 37.068115] lock_acquire+0x118/0x26c
[ 37.068375] _raw_write_lock+0x4c/0x88
[ 37.068637] kvcache_dict_free+0x24/0x104
[ 37.068917] lua_lsm_file_free_security+0x210/0x2bc
[ 37.069222] security_file_free+0x5c/0xa4
[ 37.069499] __fput+0x1a0/0x2f0
[ 37.069726] delayed_fput+0x44/0x58
[ 37.070043] process_one_work+0x210/0x548
[ 37.070282] worker_thread+0x244/0x380
[ 37.070499] kthread+0x138/0x260
[ 37.070713] ret_from_fork+0x10/0x20
[ 37.070923] }
[ 37.070992] ... key at: [<ffff800082ce7398>] kvcache_dict_init.__key+0x0/0x10
[ 37.071308]
[ 37.071308] the dependencies between the lock to be acquired
[ 37.071309] and SOFTIRQ-irq-unsafe lock:
[ 37.071759] -> (fs_reclaim){+.+.}-{0:0} {
[ 37.071923] HARDIRQ-ON-W at:
[ 37.072052] lock_acquire+0x118/0x26c
[ 37.072268] fs_reclaim_acquire+0x64/0xd0
[ 37.072499] mem_cgroup_css_alloc+0xdc/0x6e4
[ 37.072740] cgroup_init_subsys+0x7c/0x1d0
[ 37.072974] cgroup_init+0x2d8/0x490
[ 37.073187] start_kernel+0x2f4/0x3c0
[ 37.073403] __primary_switched+0x88/0x90
[ 37.073633] SOFTIRQ-ON-W at:
[ 37.073761] lock_acquire+0x118/0x26c
[ 37.074010] fs_reclaim_acquire+0x64/0xd0
[ 37.074241] mem_cgroup_css_alloc+0xdc/0x6e4
[ 37.074482] cgroup_init_subsys+0x7c/0x1d0
[ 37.074735] cgroup_init+0x2d8/0x490
[ 37.074947] start_kernel+0x2f4/0x3c0
[ 37.075160] __primary_switched+0x88/0x90
[ 37.075388] INITIAL USE at:
[ 37.075512] lock_acquire+0x118/0x26c
[ 37.075722] fs_reclaim_acquire+0x64/0xd0
[ 37.075944] mem_cgroup_css_alloc+0xdc/0x6e4
[ 37.076169] cgroup_init_subsys+0x7c/0x1d0
[ 37.076399] cgroup_init+0x2d8/0x490
[ 37.076598] start_kernel+0x2f4/0x3c0
[ 37.076798] __primary_switched+0x88/0x90
[ 37.077012] }
[ 37.077078] ... key at: [<ffff800081f2b9f8>] __fs_reclaim_map+0x0/0x30
[ 37.077349] ... acquired at:
[ 37.077464] fs_reclaim_acquire+0x64/0xd0
[ 37.077628] __kmalloc_noprof+0xb0/0x4d4
[ 37.077787] kvcache_incr+0xe0/0x21c
[ 37.077967] shdict_incr+0x34/0x44
[ 37.078108] luaD_precall+0x330/0x674
[ 37.078259] luaV_execute+0xaac/0x119c
[ 37.078413] luaD_call+0xb0/0x128
[ 37.078550] f_call+0x1c/0x28
[ 37.078692] luaD_rawrunprotected+0x7c/0xb8
[ 37.078862] luaD_pcall+0x40/0x184
[ 37.079003] lua_pcall+0xac/0x190
[ 37.079191] lua_lsm_file_permission+0x1fc/0x36c
[ 37.079379] security_file_permission+0x4c/0xa8
[ 37.079562] rw_verify_area+0x54/0x138
[ 37.079715] vfs_read+0xa4/0x2b0
[ 37.079846] ksys_read+0x70/0xe4
[ 37.079974] __arm64_sys_read+0x1c/0x28
[ 37.080123] invoke_syscall+0x40/0xf8
[ 37.080269] el0_svc_common+0xa8/0xd8
[ 37.080413] do_el0_svc+0x1c/0x28
[ 37.080544] el0_svc+0x50/0xcc
[ 37.080665] el0t_64_sync_handler+0x84/0x12c
[ 37.080831] el0t_64_sync+0x198/0x19c
[ 37.080975]
[ 37.081031]
[ 37.081031] stack backtrace:
[ 37.081195] CPU: 1 UID: 0 PID: 1610 Comm: cat Tainted: G W 6.17.0-rc3+ #515 PREEMPT
[ 37.081535] Tainted: [W]=WARN
[ 37.081646] Hardware name: QEMU QEMU Virtual Machine, BIOS edk2-stable202408-prebuilt.qemu.org 08/13/2024
[ 37.082039] Call trace:
[ 37.082130] show_stack+0x18/0x24 (C)
[ 37.082269] __dump_stack+0x28/0x38
[ 37.082400] dump_stack_lvl+0x64/0x84
[ 37.082537] dump_stack+0x18/0x24
[ 37.082688] __lock_acquire+0x2b2c/0x2b90
[ 37.082837] lock_acquire+0x118/0x26c
[ 37.082972] fs_reclaim_acquire+0x64/0xd0
[ 37.083119] __kmalloc_noprof+0xb0/0x4d4
[ 37.083264] kvcache_incr+0xe0/0x21c
[ 37.083395] shdict_incr+0x34/0x44
[ 37.083520] luaD_precall+0x330/0x674
[ 37.083656] luaV_execute+0xaac/0x119c
[ 37.083793] luaD_call+0xb0/0x128
[ 37.083916] f_call+0x1c/0x28
[ 37.084025] luaD_rawrunprotected+0x7c/0xb8
[ 37.084180] luaD_pcall+0x40/0x184
[ 37.084306] lua_pcall+0xac/0x190
[ 37.084428] lua_lsm_file_permission+0x1fc/0x36c
[ 37.084598] security_file_permission+0x4c/0xa8
[ 37.084765] rw_verify_area+0x54/0x138
[ 37.084902] vfs_read+0xa4/0x2b0
[ 37.085021] ksys_read+0x70/0xe4
[ 37.085139] __arm64_sys_read+0x1c/0x28
[ 37.085280] invoke_syscall+0x40/0xf8
[ 37.085416] el0_svc_common+0xa8/0xd8
[ 37.085553] do_el0_svc+0x1c/0x28
[ 37.085676] el0_svc+0x50/0xcc
[ 37.085790] el0t_64_sync_handler+0x84/0x12c
[ 37.086018] el0t_64_sync+0x198/0x19c
security_xfrm_state_pol_flow_match() is not a normal stacking hook. The hook default return value is 1, and the security core stops after the first registered implementation because the result is a boolean match decision. Lua-LSM currently generates a generic wrapper for the hook. If that wrapper is registered before SELinux, the XFRM lookup path can use the Lua-LSM result and never ask SELinux whether the state, policy, and flow labels match. A dispatch failure also falls back to the default value, which reports a match. Keep the hook out of lua_lsm_hook_supported() until Lua-LSM can provide semantics that do not shadow the provider that owns the XFRM decision. This hides it from registration, module introspection, and module load validation. Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
The lazy per-task VM path published lvm->L before moving the VM allocator userdata from the temporary build owner to the target task lvm. Unregister can observe any non-NULL lvm->L through task_call_func(). That window let it treat a half-initialized VM as ready and race with the first hook dispatch. Take the task VM refcount before first-use construction, move the allocator owner and stats before publication, and publish lvm->L only after the VM is ready. The unregister path now either sees an untouched VM or fails the idle-required get while the first dispatch owns the VM. Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
Keep the per-task Lua VM pointer NULL until hook dispatch needs it. This avoids VM allocation from task allocation and free paths when no Lua policy is active. Module unregister and task free still handle already-published states. Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
Leave object kvcache dictionaries uninitialized until Lua writes need storage. Reads and frees treat the zero state as empty. This reduces no-policy allocation work without changing object cleanup semantics. Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
Bypass stats, SRCU, VM preparation, and Lua dispatch when a hook has no active handlers. Keep the inactive cleanup allowlist for free hooks so postponed object teardown still runs for state created while policy was active. Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
Skip inactive cleanup before any Lua policy has been registered. Once a policy is accepted, keep the key enabled permanently so objects that outlive module unload still run free-hook cleanup. Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
Lazy kvcache initialization leaves a dictionary in INITING until __kvcache_dict_init() finishes. A same-CPU softirq hook can reenter the Lua path in that window, observe INITING for the current task's dictionary, and spin in kvcache_dict_ready() until the interrupted task context runs again. Disable bottom halves around the UNINIT -> INITING -> READY publication window so same-CPU softirq reentry cannot observe the transient state. While here, rename the inactive-cleanup static key from *_possible to *_armed to better match its one-way semantics after the first policy load. Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
chenzongyao200127
force-pushed
the
lua-lsm-unregister-lifetime-fixes
branch
from
July 9, 2026 07:11
3b3aa86 to
b752d84
Compare
chenzongyao200127
marked this pull request as draft
July 9, 2026 09:51
Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
lua_lsm_hook_supported() only excluded the procattr and xfrm hooks, so lua-LSM still registered the key, key-notification, perf_event, tun_dev and infiniband hooks. Those operate on object classes for which lua-LSM reserves no security blob (lbs_key, lbs_perf_event, lbs_tun_dev and lbs_ib are all 0), so a policy can neither attach nor manage state on them and the hooks were never usefully supported. Add them to the exclusion list so lua-LSM is not registered on hooks it cannot back, trimming its footprint on those paths. Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
The *_alloc_security prepare hooks ran kvcache_dict_init() on every LSM object blob at allocation time. Those blobs are kzalloc'd, and kvcache promotes the embedded dict from the zero UNINIT state to READY lazily on first use, so the eager init is redundant work on a hot allocation path (every inode, file, cred, ipc and sock). Drop the eager initializers and document that KVCACHE_DICT_UNINIT must stay the zero value, so a zero-filled blob is valid without them. Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
Each lua_lsm hook was a single function: a fast "no policy loaded" early return followed by the srcu walk and VM dispatch. The slow part takes the address of a local (the return slot passed to __prepare_) and uses callee-saved registers, so the compiler gave the whole function a stack frame and a -fstack-protector-strong canary. Even with no policy loaded, every guarded syscall then executed that prologue and two %gs canary accesses just to reach the early return, whereas an empty hook such as bpf_lsm's compiles to a bare "xor %eax, %eax; ret". Split each hook into a thin wrapper and a noinline slow path. When no policy is loaded both static branches are patched to nops, so the wrapper takes no local's address and needs no callee-saved registers: the compiler emits neither a stack frame nor a canary, and the idle path collapses to two nops and a constant return, matching the empty hook. The srcu walk, VM dispatch and inactive object cleanup move into the slow path, entered only once a policy is live. perf confirms the dormant stub then carries no frame or canary; the measurable gain is a few ns per guarded syscall on file-permission-heavy workloads. The residual per-hook cost is the LSM dispatch call itself, which this change does not touch. Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
Commit "lua-lsm: drop eager kvcache dict init" removed the eager kvcache_dict_init() from the *_alloc_security prepare hooks but missed task_blob_init(), which still initialized the task blob's dict on every task_alloc. The task blob is kzalloc'd like the other LSM object blobs, so its embedded dict starts in the zero UNINIT state and is promoted to READY lazily on first use; the eager init is the same redundant work. Drop it from task_blob_init() too. Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
shared[name] caches a Lua userdata that can outlive module unregister. The userdata used to hold a raw kvcache_dict pointer, while unregister freed the backing shared dict before every loaded VM was purged. If unregister left the module busy, later shared-dict access could dereference freed memory. Store a refcounted shared-dict wrapper in the userdata, tombstone shared dicts when unregister starts, and drop the module list reference only once unregister can finish. Allocate the Lua userdata slot before taking the per-userdata shared-dict reference, so allocation failures cannot leak the wrapper ref. Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
task_call_func() may run callbacks under pi_lock and, for runnable tasks, the runqueue lock. The unregister path used it to remove modules from other tasks' Lua VMs, which updates Lua tables and can run a full Lua GC. Stop doing remote task VM teardown from task_call_func(). Unregister now purges only the current task and per-cpu Lua VMs directly; other task VMs purge unloading modules lazily when they next enter Lua-LSM. Modules that still have loaded VMs remain zombie and unregister returns -EBUSY until the remaining VMs have purged them. Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
Lazy unload can drop a module's last VM-local reference after unregister() has already returned -EBUSY. In that case the module used to stay on the unloading list until another unregister() retried the final teardown. Queue a worker when lazy purge or task teardown drains nloaded to zero. The worker detaches the drained zombie under modules_mutex, waits for the modules_ss SRCU grace period, and then frees the module outside the mutex. Also skip purge attempts once nloaded is already zero and make lua_modules_free() explicitly rely on the caller's existing SRCU read-side protection. Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
Rely on workqueue serialization for async module finalization. Use SRCU callbacks for delayed module free after list removal. Rename VM-side unload helpers around dropping modules from Lua VMs. Name the loaded VM count explicitly. Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
Unregister used to return -EBUSY whenever a deactivated module still had loaded Lua VMs, even though the module's hooks no longer run and the finalize worker reclaims it asynchronously once loaded_vm_count drains to zero. Reporting an error for an operation that has, from the caller's point of view, already succeeded (the policy is stopped) is misleading and hard to script against. Return 0 in that case. The module stays on the list as ZOMBIE until the background worker frees it. Expose the module state (live/coming/going/ zombie) as a new column in /sys/kernel/security/lua/modules so the pending cleanup is observable. Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
When lua-lsm debug logging is disabled, __log_info() expands to an empty statement, so the loaded_vms locals in lvm_drop_module() and lvm_put_loaded_modules() are unused and trip -Werror=unused-variable. The lua_lsm_module_drop_from_vm() call has side effects (it decrements loaded_vm_count and may queue the finalize worker) and must stay, so annotate the locals with __maybe_unused. Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
chenzongyao200127
force-pushed
the
lua-lsm-unregister-lifetime-fixes
branch
from
July 31, 2026 07:42
097f152 to
f90a7a1
Compare
uudiin
pushed a commit
that referenced
this pull request
Aug 21, 2026
The xfstests' test-case generic/533 fails to execute correctly: FSTYP -- hfsplus PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.15.0-rc4+ #8 SMP PREEMPT_DYNAMIC Thu May 1 16:43:22 PDT 2025 MKFS_OPTIONS -- /dev/loop51 MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch generic/533 _check_generic_filesystem: filesystem on /dev/loop50 is inconsistent (see xfstests-dev/results//generic/533.full for details) The key reason of the issue is returning -ENOENT error code from hfsplus_find_attr(), __hfsplus_delete_attr(), hfsplus_delete_attr_nolock(), hfsplus_delete_all_attrs(). The file exists but we don't have any xattr for this file. Finally, -ENODATA error code is expected by application logic. This patch reworks xattr logic of HFS+ by means exchanging the -ENOENT error code on -ENODATA error code if xattr has not been found for existing file or folder. sudo ./check generic/533 FSTYP -- hfsplus PLATFORM -- Linux/x86_64 hfsplus-testing-0001 7.0.0-rc1+ #16 SMP PREEMPT_DYNAMIC Wed Mar 11 15:04:58 PDT 2026 MKFS_OPTIONS -- /dev/loop51 MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch generic/533 33s ... 32s Ran: generic/533 Passed all 1 tests Closes: hfs-linux-kernel/hfs-linux-kernel#184 cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> cc: Yangtao Li <frank.li@vivo.com> cc: linux-fsdevel@vger.kernel.org Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com> Link: https://lore.kernel.org/r/20260312221920.1422683-2-slava@dubeyko.com Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
uudiin
pushed a commit
that referenced
this pull request
Aug 21, 2026
The LLVM disassembler needs ISA extension features enabled to correctly decode instructions from those extensions. On aarch64, without these features, instructions like LSE atomics (e.g. ldaddal) are silently decoded as incorrect instructions and disassembly is truncated. Use LLVMCreateDisasmCPUFeatures() with "+all" features for aarch64 targets so that the disassembler can handle any instruction the kernel JIT might emit. Before: int bench_trigger_uprobe(void * ctx): bpf_prog_538c6a43d1c6b84c_bench_trigger_uprobe: ; int cpu = bpf_get_smp_processor_id(); 0: mov x9, x30 4: nop 8: stp x29, x30, [sp, #-16]! c: mov x29, sp 10: stp xzr, x26, [sp, #-16]! 14: mov x26, sp 18: mrs x10, SP_EL0 1c: ldr w7, [x10, #16] ; __sync_add_and_fetch(&hits[cpu & CPU_MASK].value, 1); 20: and w7, w7, #0xff ; __sync_add_and_fetch(&hits[cpu & CPU_MASK].value, 1); 24: lsl x7, x7, #7 28: mov x0, #-281474976710656 2c: movk x0, #32768, lsl #32 30: movk x0, #35407, lsl #16 34: add x0, x0, x7 38: mov x1, #1 ; __sync_add_and_fetch(&hits[cpu & CPU_MASK].value, 1); 3c: mov x1, #1 After: int bench_trigger_uprobe(void * ctx): bpf_prog_538c6a43d1c6b84c_bench_trigger_uprobe: ; int cpu = bpf_get_smp_processor_id(); 0: mov x9, x30 4: nop 8: stp x29, x30, [sp, #-16]! c: mov x29, sp 10: stp xzr, x26, [sp, #-16]! 14: mov x26, sp 18: mrs x10, SP_EL0 1c: ldr w7, [x10, #16] ; __sync_add_and_fetch(&hits[cpu & CPU_MASK].value, 1); 20: and w7, w7, #0xff ; __sync_add_and_fetch(&hits[cpu & CPU_MASK].value, 1); 24: lsl x7, x7, #7 28: mov x0, #-281474976710656 2c: movk x0, #32768, lsl #32 30: movk x0, #35407, lsl #16 34: add x0, x0, x7 38: mov x1, #1 ; __sync_add_and_fetch(&hits[cpu & CPU_MASK].value, 1); 3c: ldaddal x1, x1, [x0] ; return 0; 40: mov w7, #0 44: ldp xzr, x26, [sp], #16 48: ldp x29, x30, [sp], #16 4c: mov x0, x7 50: ret 54: nop 58: ldr x10, #8 5c: br x10 Signed-off-by: Puranjay Mohan <puranjay@kernel.org> Acked-by: Yonghong Song <yonghong.song@linux.dev> Acked-by: Leon Hwang <leon.hwang@linux.dev> Acked-by: Quentin Monnet <qmo@kernel.org> Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com> Link: https://lore.kernel.org/r/20260318172259.2882792-1-puranjay@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
uudiin
pushed a commit
that referenced
this pull request
Aug 21, 2026
Fix the IDR allocation flags by using atomic GFP
flags in non‑sleepable contexts to avoid the __might_sleep()
complaint.
268.290239] [drm] Initialized amdgpu 3.64.0 for 0000:03:00.0 on minor 0
[ 268.294900] BUG: sleeping function called from invalid context at ./include/linux/sched/mm.h:323
[ 268.295355] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 1744, name: modprobe
[ 268.295705] preempt_count: 1, expected: 0
[ 268.295886] RCU nest depth: 0, expected: 0
[ 268.296072] 2 locks held by modprobe/1744:
[ 268.296077] #0: ffff8c3a44abd1b8 (&dev->mutex){....}-{4:4}, at: __driver_attach+0xe4/0x210
[ 268.296100] #1: ffffffffc1a6ea78 (amdgpu_pasid_idr_lock){+.+.}-{3:3}, at: amdgpu_pasid_alloc+0x26/0xe0 [amdgpu]
[ 268.296494] CPU: 12 UID: 0 PID: 1744 Comm: modprobe Tainted: G U OE 6.19.0-custom #16 PREEMPT(voluntary)
[ 268.296498] Tainted: [U]=USER, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
[ 268.296499] Hardware name: AMD Majolica-RN/Majolica-RN, BIOS RMJ1009A 06/13/2021
[ 268.296501] Call Trace:
Fixes: 8f1de51 ("drm/amdgpu: prevent immediate PASID reuse case")
Signed-off-by: Prike Liang <Prike.Liang@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
uudiin
pushed a commit
that referenced
this pull request
Aug 21, 2026
Patch series "mm: cleanups around unmapping / zapping". A bunch of cleanups around unmapping and zapping. Mostly simplifications, code movements, documentation and renaming of zapping functions. With this series, we'll have the following high-level zap/unmap functions (excluding high-level folio zapping): * unmap_vmas() for actual unmapping (vmas will go away) * zap_vma(): zap all page table entries in a vma * zap_vma_for_reaping(): zap_vma() that must not block * zap_vma_range(): zap a range of page table entries * zap_vma_range_batched(): zap_vma_range() with more options and batching * zap_special_vma_range(): limited zap_vma_range() for modules * __zap_vma_range(): internal helper Patch #1 is not about unmapping/zapping, but I stumbled over it while verifying MADV_DONTNEED range handling. Patch #16 is related to [1], but makes sense even independent of that. This patch (of 16): madvise_vma_behavior()-> madvise_dontneed_free()->madvise_free_single_vma() is only called from madvise_walk_vmas() (a) After try_vma_read_lock() confirmed that the whole range falls into a single VMA (see is_vma_lock_sufficient()). (b) After adjusting the range to the VMA in the loop afterwards. madvise_dontneed_free() might drop the MM lock when handling userfaultfd, but it properly looks up the VMA again to adjust the range. So in madvise_free_single_vma(), the given range should always fall into a single VMA and should also span at least one page. Let's drop the error checks. The code now matches what we do in madvise_dontneed_single_vma(), where we call zap_vma_range_batched() that documents: "The range must fit into one VMA.". Although that function still adjusts that range, we'll change that soon. Link: https://lkml.kernel.org/r/20260227200848.114019-1-david@kernel.org Link: https://lkml.kernel.org/r/20260227200848.114019-2-david@kernel.org Link: https://lore.kernel.org/r/aYSKyr7StGpGKNqW@google.com [1] Signed-off-by: David Hildenbrand (Arm) <david@kernel.org> Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org> Cc: Alexander Gordeev <agordeev@linux.ibm.com> Cc: Alexei Starovoitov <ast@kernel.org> Cc: Alice Ryhl <aliceryhl@google.com> Cc: Andrii Nakryiko <andrii@kernel.org> Cc: Andy Lutomirski <luto@kernel.org> Cc: Arnaldo Carvalho de Melo <acme@kernel.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Arve <arve@android.com> Cc: "Borislav Petkov (AMD)" <bp@alien8.de> Cc: Carlos Llamas <cmllamas@google.com> Cc: Christian Borntraeger <borntraeger@linux.ibm.com> Cc: Christian Brauner <brauner@kernel.org> Cc: Claudio Imbrenda <imbrenda@linux.ibm.com> Cc: Daniel Borkman <daniel@iogearbox.net> Cc: Dave Airlie <airlied@gmail.com> Cc: David Ahern <dsahern@kernel.org> Cc: David Rientjes <rientjes@google.com> Cc: David S. Miller <davem@davemloft.net> Cc: Dimitri Sivanich <dimitri.sivanich@hpe.com> Cc: Eric Dumazet <edumazet@google.com> Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Hartley Sweeten <hsweeten@visionengravers.com> Cc: Heiko Carstens <hca@linux.ibm.com> Cc: Ian Abbott <abbotti@mev.co.uk> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jakub Kacinski <kuba@kernel.org> Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: Jann Horn <jannh@google.com> Cc: Janosch Frank <frankja@linux.ibm.com> Cc: Jarkko Sakkinen <jarkko@kernel.org> Cc: Jason Gunthorpe <jgg@ziepe.ca> Cc: Jonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Leon Romanovsky <leon@kernel.org> Cc: Liam Howlett <liam.howlett@oracle.com> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Michal Hocko <mhocko@suse.com> Cc: Miguel Ojeda <ojeda@kernel.org> Cc: Mike Rapoport <rppt@kernel.org> Cc: Namhyung kim <namhyung@kernel.org> Cc: Neal Cardwell <ncardwell@google.com> Cc: Paolo Abeni <pabeni@redhat.com> Cc: Pedro Falcato <pfalcato@suse.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Shakeel Butt <shakeel.butt@linux.dev> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Todd Kjos <tkjos@android.com> Cc: Tvrtko Ursulin <tursulin@ursulin.net> Cc: Vasily Gorbik <gor@linux.ibm.com> Cc: Vincenzo Frascino <vincenzo.frascino@arm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
uudiin
pushed a commit
that referenced
this pull request
Aug 21, 2026
Currently, the initialization of loongarch_jump_ops does not contain an
assignment to its .free field. This causes disasm_line__free() to fall
through to ins_ops__delete() for LoongArch jump instructions.
ins_ops__delete() will free ins_operands.source.raw and
ins_operands.source.name, and these fields overlaps with
ins_operands.jump.raw_comment and ins_operands.jump.raw_func_start.
Since in loongarch_jump__parse(), these two fields are populated by
strchr()-ing the same buffer, trying to free them will lead to undefined
behavior.
This invalid free usually leads to crashes:
Process 1712902 (perf) of user 1000 dumped core.
Stack trace of thread 1712902:
#0 0x00007fffef155c58 n/a (libc.so.6 + 0x95c58)
#1 0x00007fffef0f7a94 raise (libc.so.6 + 0x37a94)
#2 0x00007fffef0dd6a8 abort (libc.so.6 + 0x1d6a8)
#3 0x00007fffef145490 n/a (libc.so.6 + 0x85490)
#4 0x00007fffef1646f4 n/a (libc.so.6 + 0xa46f4)
#5 0x00007fffef164718 n/a (libc.so.6 + 0xa4718)
#6 0x00005555583a6764 __zfree (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x106764)
#7 0x000055555854fb70 disasm_line__free (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x2afb70)
#8 0x000055555853d618 annotated_source__purge (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x29d618)
#9 0x000055555852300c __hist_entry__tui_annotate (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x28300c)
#10 0x0000555558526718 do_annotate (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x286718)
#11 0x000055555852ed94 evsel__hists_browse (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x28ed94)
#12 0x000055555831fdd0 cmd_report (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x7fdd0)
#13 0x000055555839b644 handle_internal_command (/home/csmantle/dist/linux-arch/tools/perf/perf + 0xfb644)
#14 0x00005555582fe6ac main (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x5e6ac)
#15 0x00007fffef0ddd90 n/a (libc.so.6 + 0x1dd90)
#16 0x00007fffef0ddf0c __libc_start_main (libc.so.6 + 0x1df0c)
#17 0x00005555582fed10 _start (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x5ed10)
ELF object binary architecture: LoongArch
... and it can be confirmed with Valgrind:
==1721834== Invalid free() / delete / delete[] / realloc()
==1721834== at 0x4EA9014: free (in /usr/lib/valgrind/vgpreload_memcheck-loongarch64-linux.so)
==1721834== by 0x4106287: __zfree (zalloc.c:13)
==1721834== by 0x42ADC8F: disasm_line__free (in /home/csmantle/dist/linux-arch/tools/perf/perf)
==1721834== by 0x429B737: annotated_source__purge (in /home/csmantle/dist/linux-arch/tools/perf/perf)
==1721834== by 0x42811EB: __hist_entry__tui_annotate (in /home/csmantle/dist/linux-arch/tools/perf/perf)
==1721834== by 0x42848D7: do_annotate (in /home/csmantle/dist/linux-arch/tools/perf/perf)
==1721834== by 0x428CF33: evsel__hists_browse (in /home/csmantle/dist/linux-arch/tools/perf/perf)
==1721834== Address 0x7d34303 is 35 bytes inside a block of size 62 alloc'd
==1721834== at 0x4EA59B8: malloc (in /usr/lib/valgrind/vgpreload_memcheck-loongarch64-linux.so)
==1721834== by 0x6B80B6F: strdup (strdup.c:42)
==1721834== by 0x42AD917: disasm_line__new (in /home/csmantle/dist/linux-arch/tools/perf/perf)
==1721834== by 0x42AE5A3: symbol__disassemble_objdump (in /home/csmantle/dist/linux-arch/tools/perf/perf)
==1721834== by 0x42AF0A7: symbol__disassemble (in /home/csmantle/dist/linux-arch/tools/perf/perf)
==1721834== by 0x429B3CF: symbol__annotate (in /home/csmantle/dist/linux-arch/tools/perf/perf)
==1721834== by 0x429C233: symbol__annotate2 (in /home/csmantle/dist/linux-arch/tools/perf/perf)
==1721834== by 0x42804D3: __hist_entry__tui_annotate (in /home/csmantle/dist/linux-arch/tools/perf/perf)
==1721834== by 0x42848D7: do_annotate (in /home/csmantle/dist/linux-arch/tools/perf/perf)
==1721834== by 0x428CF33: evsel__hists_browse (in /home/csmantle/dist/linux-arch/tools/perf/perf)
This patch adds the missing free() specialization in loongarch_jump_ops,
which prevents disasm_line__free() from invoking the default cleanup
function.
Fixes: fb7fd2a ("perf annotate: Move raw_comment and raw_func_start fields out of 'struct ins_operands'")
Cc: stable@vger.kernel.org
Cc: WANG Rui <wangrui@loongson.cn>
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: WANG Xuerui <kernel@xen0n.name>
Cc: loongarch@lists.linux.dev
Signed-off-by: Rong Bao <rong.bao@csmantle.top>
Tested-by: WANG Rui <wangrui@loongson.cn>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
uudiin
pushed a commit
that referenced
this pull request
Aug 21, 2026
…g FLR During Function Level Reset recovery, the MANA driver reads hardware BAR0 registers that may temporarily contain garbage values. The SHM (Shared Memory) offset read from GDMA_REG_SHM_OFFSET is used to compute gc->shm_base, which is later dereferenced via readl() in mana_smc_poll_register(). If the hardware returns an unaligned or out-of-range value, the driver must not blindly use it, as this would propagate the hardware error into a kernel crash. The following crash was observed on an arm64 Hyper-V guest running kernel 6.17.0-3013-azure during VF reset recovery triggered by HWC timeout. [13291.785274] Unable to handle kernel paging request at virtual address ffff8000a200001b [13291.785311] Mem abort info: [13291.785332] ESR = 0x0000000096000021 [13291.785343] EC = 0x25: DABT (current EL), IL = 32 bits [13291.785355] SET = 0, FnV = 0 [13291.785363] EA = 0, S1PTW = 0 [13291.785372] FSC = 0x21: alignment fault [13291.785382] Data abort info: [13291.785391] ISV = 0, ISS = 0x00000021, ISS2 = 0x00000000 [13291.785404] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 [13291.785412] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 [13291.785421] swapper pgtable: 4k pages, 48-bit VAs, pgdp=00000014df3a1000 [13291.785432] [ffff8000a200001b] pgd=1000000100438403, p4d=1000000100438403, pud=1000000100439403, pmd=0068000fc2000711 [13291.785703] Internal error: Oops: 0000000096000021 [#1] SMP [13291.830975] Modules linked in: tls qrtr mana_ib ib_uverbs ib_core xt_owner xt_tcpudp xt_conntrack nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nft_compat nf_tables cfg80211 8021q garp mrp stp llc binfmt_misc joydev serio_raw nls_iso8859_1 hid_generic aes_ce_blk aes_ce_cipher polyval_ce ghash_ce sm4_ce_gcm sm4_ce_ccm sm4_ce sm4_ce_cipher hid_hyperv sm4 sm3_ce sha3_ce hv_netvsc hid vmgenid hyperv_keyboard hyperv_drm sch_fq_codel nvme_fabrics efi_pstore dm_multipath nfnetlink vsock_loopback vmw_vsock_virtio_transport_common hv_sock vmw_vsock_vmci_transport vmw_vmci vsock dmi_sysfs ip_tables x_tables autofs4 [13291.862630] CPU: 122 UID: 0 PID: 61796 Comm: kworker/122:2 Tainted: G W 6.17.0-3013-azure #13-Ubuntu VOLUNTARY [13291.869902] Tainted: [W]=WARN [13291.871901] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v4.1 01/08/2026 [13291.878086] Workqueue: events mana_serv_func [13291.880718] pstate: 62400005 (nZCv daif +PAN -UAO +TCO -DIT -SSBS BTYPE=--) [13291.884835] pc : mana_smc_poll_register+0x48/0xb0 [13291.887902] lr : mana_smc_setup_hwc+0x70/0x1c0 [13291.890493] sp : ffff8000ab79bbb0 [13291.892364] x29: ffff8000ab79bbb0 x28: ffff00410c8b5900 x27: ffff00410d630680 [13291.896252] x26: ffff004171f9fd80 x25: 000000016ed55000 x24: 000000017f37e000 [13291.899990] x23: 0000000000000000 x22: 000000016ed55000 x21: 0000000000000000 [13291.904497] x20: ffff8000a200001b x19: 0000000000004e20 x18: ffff8000a6183050 [13291.908308] x17: 0000000000000000 x16: 0000000000000000 x15: 000000000000000a [13291.912542] x14: 0000000000000004 x13: 0000000000000000 x12: 0000000000000000 [13291.916298] x11: 0000000000000000 x10: 0000000000000001 x9 : ffffc45006af1bd8 [13291.920945] x8 : ffff000151129000 x7 : 0000000000000000 x6 : 0000000000000000 [13291.925293] x5 : 000000015f214000 x4 : 000000017217a000 x3 : 000000016ed50000 [13291.930436] x2 : 000000016ed55000 x1 : 0000000000000000 x0 : ffff8000a1ffffff [13291.934342] Call trace: [13291.935736] mana_smc_poll_register+0x48/0xb0 (P) [13291.938611] mana_smc_setup_hwc+0x70/0x1c0 [13291.941113] mana_hwc_create_channel+0x1a0/0x3a0 [13291.944283] mana_gd_setup+0x16c/0x398 [13291.946584] mana_gd_resume+0x24/0x70 [13291.948917] mana_do_service+0x13c/0x1d0 [13291.951583] mana_serv_func+0x34/0x68 [13291.953732] process_one_work+0x168/0x3d0 [13291.956745] worker_thread+0x2ac/0x480 [13291.959104] kthread+0xf8/0x110 [13291.961026] ret_from_fork+0x10/0x20 [13291.963560] Code: d2807d00 9417c551 71000673 54000220 (b9400281) [13291.967299] ---[ end trace 0000000000000000 ]--- Disassembly of mana_smc_poll_register() around the crash site: Disassembly of section .text: 00000000000047c8 <mana_smc_poll_register>: 47c8: d503201f nop 47cc: d503201f nop 47d0: d503233f paciasp 47d4: f800865e str x30, [x18], #8 47d8: a9bd7bfd stp x29, x30, [sp, #-48]! 47dc: 910003fd mov x29, sp 47e0: a90153f3 stp x19, x20, [sp, #16] 47e4: 91007014 add x20, x0, #0x1c 47e8: 5289c413 mov w19, #0x4e20 47ec: f90013f5 str x21, [sp, #32] 47f0: 12001c35 and w21, w1, #0xff 47f4: 14000008 b 4814 <mana_smc_poll_register+0x4c> 47f8: 36f801e1 tbz w1, #31, 4834 <mana_smc_poll_register+0x6c> 47fc: 52800042 mov w2, #0x2 4800: d280fa01 mov x1, #0x7d0 4804: d2807d00 mov x0, #0x3e8 4808: 94000000 bl 0 <usleep_range_state> 480c: 71000673 subs w19, w19, #0x1 4810: 54000200 b.eq 4850 <mana_smc_poll_register+0x88> 4814: b9400281 ldr w1, [x20] <-- **** CRASHED HERE ***** 4818: d50331bf dmb oshld 481c: 2a0103e2 mov w2, w1 ... From the crash signature x20 = ffff8000a200001b, this address ends in 0x1b which is not 4-byte aligned, so the 'ldr w1, [x20]' instruction (readl) triggers the arm64 alignment fault (FSC = 0x21). The root cause is in mana_gd_init_vf_regs(), which computes: gc->shm_base = gc->bar0_va + mana_gd_r64(gc, GDMA_REG_SHM_OFFSET); The offset is used without any validation. The same problem exists in mana_gd_init_pf_regs() for sriov_base_off and sriov_shm_off. Fix this by validating all offsets before use: - VF: check shm_off is within BAR0, properly aligned to 4 bytes (readl requirement), and leaves room for the full 256-bit (32-byte) SMC aperture. - PF: check sriov_base_off is within BAR0, aligned to 8 bytes (readq requirement), and leaves room to safely read the sriov_shm_off register at sriov_base_off + GDMA_PF_REG_SHM_OFF. Then check sriov_shm_off leaves room for the full SMC aperture. All arithmetic uses subtraction rather than addition to avoid integer overflow on garbage values. Define SMC_APERTURE_SIZE (32 bytes, derived from the 256-bit aperture width) Return -EPROTO on invalid values. The existing recovery path in mana_serv_reset() already handles -EPROTO by falling through to PCI device rescan, giving the hardware another chance to present valid register values after reset. Fixes: 9bf6603 ("net: mana: Handle hardware recovery events when probing the device") Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com> Link: https://patch.msgid.link/afQUMClyjmBVfD+u@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net Signed-off-by: Paolo Abeni <pabeni@redhat.com>
uudiin
pushed a commit
that referenced
this pull request
Aug 21, 2026
pin_user_pages_fast() can partially succeed and return the number of pages that were actually pinned. However, the bio_integrity_map_user() does not handle this partial pinning. This leads to a general protection fault since bvec_from_pages() dereferences an unpinned page address, which is 0. To fix this, add a check to verify that all requested memory is pinned. If partial pinning occurs, unpin the memory and return -EFAULT. Kernel Oops: Oops: general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f] CPU: 0 UID: 0 PID: 1061 Comm: nvme-passthroug Not tainted 7.0.0-11783-g90957f9314e8-dirty #16 PREEMPT(lazy) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014 RIP: 0010:bio_integrity_map_user.cold+0x1b0/0x9d6 Fixes: 492c5d4 ("block: bio-integrity: directly map user buffers") Acked-by: Chao Shi <cshi008@fiu.edu> Acked-by: Weidong Zhu <weizhu@fiu.edu> Acked-by: Dave Tian <daveti@purdue.edu> Signed-off-by: Sungwoo Kim <iam@sung-woo.kim> Tested-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com> Link: linux-blktests/blktests#244 Link: https://patch.msgid.link/20260512050929.541397-2-iam@sung-woo.kim Signed-off-by: Jens Axboe <axboe@kernel.dk>
uudiin
pushed a commit
that referenced
this pull request
Aug 21, 2026
…softlockup We hit a real softlockup in an internal stress test environment. The workload was LTP memory/swap stress on a large arm64 machine, with 320 CPUs, about 1TB memory and an 8.6GB swap device. The system was under heavy load and the swap device had a large number of full clusters. The softlockup was triggered during a stress test after about 3 days. So, add periodic cond_resched() calls during large full_clusters reclaim operations to prevent softlockup issues. Detailed call trace as follow: PID: 3817773 TASK: ffff0883bb28b780 CPU: 48 COMMAND: "kworker/48:7" #0 [ffff800080183d10] __crash_kexec at ffffa4c1361e5de4 #1 [ffff800080183d90] panic at ffffa4c1360d5e9c #2 [ffff800080183e20] watchdog_timer_fn at ffffa4c136231fa8 ... #16 [ffff8000c4ad3cb0] swap_cache_del_folio at ffffa4c1363e1614 #17 [ffff8000c4ad3ce0] __try_to_reclaim_swap at ffffa4c1363e4bfc #18 [ffff8000c4ad3d40] swap_reclaim_full_clusters at ffffa4c1363e5474 #19 [ffff8000c4ad3da0] swap_reclaim_work at ffffa4c1363e550c #20 [ffff8000c4ad3dc0] process_one_work at ffffa4c136102edc #21 [ffff8000c4ad3e10] worker_thread at ffffa4c136103398 #22 [ffff8000c4ad3e70] kthread at ffffa4c13610d95c Link: https://lore.kernel.org/20260506130919.2298807-1-kerayhuang@tencent.com Fixes: 5168a68 ("mm, swap: avoid over reclaim of full clusters") Signed-off-by: Zijiang Huang <kerayhuang@tencent.com> Reviewed-by: Kairui Song <kasong@tencent.com> Reviewed-by: Hao Peng <flyingpeng@tencent.com> Reviewed-by: albinwyang <albinwyang@tencent.com> Reviewed-by: Baoquan He <baoquan.he@linux.dev> Acked-by: Chris Li <chrisl@kernel.org> Cc: Barry Song <baohua@kernel.org> Cc: Kairui Song <kasong@tencent.com> Cc: Kemeng Shi <shikemeng@huaweicloud.com> Cc: Nhat Pham <nphamcs@gmail.com> Cc: Youngjun Park <youngjun.park@lge.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Lua-LSM module unregister has to coordinate several lifetimes at once: the global module list protected by modules_ss SRCU, per-VM loaded module references, shared dictionaries cached in Lua userdata, and the contexts where VM teardown is allowed to run.
This series keeps those pieces ordered so unregister no longer frees state that can still be reached from an existing Lua VM, and so lazy unload can finish modules once the last VM-local reference is gone.
The series contains these commits:
Main fixes:
Please use Rebase and merge, or another merge mode that preserves the individual commits. Please do not squash this PR, since each commit has its own kernel-style subject and message.
Validation:
Signed-off-by: Zongyao Chen ZongYao.Chen@linux.alibaba.com