Message ID | 20241009180816.83591-9-rppt@kernel.org |
---|---|
State | New |
Headers | show |
Series | x86/module: use large ROX pages for text allocations | expand |
On (24/10/09 21:08), Mike Rapoport wrote: > From: "Mike Rapoport (Microsoft)" <rppt@kernel.org> > > Enable execmem's cache of PMD_SIZE'ed pages mapped as ROX for module > text allocations. > With this modprobe disappoints kmemleak [ 12.700128] kmemleak: Found object by alias at 0xffffffffa000a000 [ 12.702179] CPU: 5 UID: 0 PID: 410 Comm: modprobe Tainted: G N 6.12.0-rc2+ #760 [ 12.704656] Tainted: [N]=TEST [ 12.705526] Call Trace: [ 12.706250] <TASK> [ 12.706888] dump_stack_lvl+0x3e/0xdb [ 12.707961] __find_and_get_object+0x100/0x110 [ 12.709256] kmemleak_no_scan+0x2e/0xb0 [ 12.710354] kmemleak_load_module+0xad/0xe0 [ 12.711557] load_module+0x2391/0x45a0 [ 12.712507] __se_sys_finit_module+0x4e0/0x7a0 [ 12.713599] do_syscall_64+0x54/0xf0 [ 12.714477] ? irqentry_exit_to_user_mode+0x33/0x100 [ 12.715696] entry_SYSCALL_64_after_hwframe+0x4b/0x53 [ 12.716931] RIP: 0033:0x7fc7af51f059 [ 12.717816] Code: 08 89 e8 5b 5d c3 66 2e 0f 1f 84 00 00 00 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 8f 1d 0d 00 f7 d8 64 89 01 48 [ 12.722324] RSP: 002b:00007ffc1d0b0c18 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 [ 12.724173] RAX: ffffffffffffffda RBX: 00005618a9439b20 RCX: 00007fc7af51f059 [ 12.725884] RDX: 0000000000000000 RSI: 000056187aea098b RDI: 0000000000000003 [ 12.727617] RBP: 0000000000000000 R08: 0000000000000060 R09: 00005618a943af60 [ 12.729361] R10: 0000000000000038 R11: 0000000000000246 R12: 000056187aea098b [ 12.731101] R13: 0000000000040000 R14: 00005618a9439ac0 R15: 0000000000000000 [ 12.732814] </TASK> [ 12.733362] kmemleak: Object 0xffffffffa0000000 (size 2097152): [ 12.734800] kmemleak: comm "modprobe", pid 410, jiffies 4294880489 [ 12.736334] kmemleak: min_count = 2 [ 12.737228] kmemleak: count = 0 [ 12.738043] kmemleak: flags = 0x5 [ 12.738917] kmemleak: checksum = 0 [ 12.739783] kmemleak: backtrace: [ 12.740606] kmemleak_vmalloc+0x29/0xc0 [ 12.741532] kasan_alloc_module_shadow+0xbe/0xe0 [ 12.742649] execmem_vmalloc+0x116/0x220 [ 12.743596] execmem_alloc+0xfb/0x3d0 [ 12.744479] load_module+0x1e84/0x45a0 [ 12.745383] __se_sys_finit_module+0x4e0/0x7a0 [ 12.746452] do_syscall_64+0x54/0xf0 [ 12.747319] entry_SYSCALL_64_after_hwframe+0x4b/0x53 [ 12.748772] kmemleak: Not scanning unknown object at 0xffffffffa000a000 [ 12.750364] CPU: 5 UID: 0 PID: 410 Comm: modprobe Tainted: G N 6.12.0-rc2+ #760 [ 12.752441] Tainted: [N]=TEST [ 12.753165] Call Trace: [ 12.753760] <TASK> [ 12.754279] dump_stack_lvl+0x3e/0xdb [ 12.755165] kmemleak_load_module+0xad/0xe0 [ 12.756165] load_module+0x2391/0x45a0 [ 12.757068] __se_sys_finit_module+0x4e0/0x7a0 [ 12.758135] do_syscall_64+0x54/0xf0 [ 12.759099] ? irqentry_exit_to_user_mode+0x33/0x100 [ 12.760292] entry_SYSCALL_64_after_hwframe+0x4b/0x53 [ 12.761508] RIP: 0033:0x7fc7af51f059 [ 12.762372] Code: 08 89 e8 5b 5d c3 66 2e 0f 1f 84 00 00 00 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 8f 1d 0d 00 f7 d8 64 89 01 48 [ 12.772361] RSP: 002b:00007ffc1d0b0c18 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 [ 12.774957] RAX: ffffffffffffffda RBX: 00005618a9439b20 RCX: 00007fc7af51f059 [ 12.776635] RDX: 0000000000000000 RSI: 000056187aea098b RDI: 0000000000000003 [ 12.778283] RBP: 0000000000000000 R08: 0000000000000060 R09: 00005618a943af60 [ 12.779949] R10: 0000000000000038 R11: 0000000000000246 R12: 000056187aea098b [ 12.781619] R13: 0000000000040000 R14: 00005618a9439ac0 R15: 0000000000000000 [ 12.783319] </TASK>
On Thu, Oct 10, 2024 at 05:30:33PM +0900, Sergey Senozhatsky wrote: > On (24/10/09 21:08), Mike Rapoport wrote: > > From: "Mike Rapoport (Microsoft)" <rppt@kernel.org> > > > > Enable execmem's cache of PMD_SIZE'ed pages mapped as ROX for module > > text allocations. > > > > With this modprobe disappoints kmemleak > > [ 12.700128] kmemleak: Found object by alias at 0xffffffffa000a000 > [ 12.702179] CPU: 5 UID: 0 PID: 410 Comm: modprobe Tainted: G N 6.12.0-rc2+ #760 > [ 12.704656] Tainted: [N]=TEST > [ 12.705526] Call Trace: > [ 12.706250] <TASK> > [ 12.706888] dump_stack_lvl+0x3e/0xdb > [ 12.707961] __find_and_get_object+0x100/0x110 > [ 12.709256] kmemleak_no_scan+0x2e/0xb0 > [ 12.710354] kmemleak_load_module+0xad/0xe0 > [ 12.711557] load_module+0x2391/0x45a0 > [ 12.712507] __se_sys_finit_module+0x4e0/0x7a0 > [ 12.713599] do_syscall_64+0x54/0xf0 > [ 12.714477] ? irqentry_exit_to_user_mode+0x33/0x100 > [ 12.715696] entry_SYSCALL_64_after_hwframe+0x4b/0x53 > [ 12.716931] RIP: 0033:0x7fc7af51f059 > [ 12.717816] Code: 08 89 e8 5b 5d c3 66 2e 0f 1f 84 00 00 00 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 8f 1d 0d 00 f7 d8 64 89 01 48 > [ 12.722324] RSP: 002b:00007ffc1d0b0c18 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 > [ 12.724173] RAX: ffffffffffffffda RBX: 00005618a9439b20 RCX: 00007fc7af51f059 > [ 12.725884] RDX: 0000000000000000 RSI: 000056187aea098b RDI: 0000000000000003 > [ 12.727617] RBP: 0000000000000000 R08: 0000000000000060 R09: 00005618a943af60 > [ 12.729361] R10: 0000000000000038 R11: 0000000000000246 R12: 000056187aea098b > [ 12.731101] R13: 0000000000040000 R14: 00005618a9439ac0 R15: 0000000000000000 > [ 12.732814] </TASK> Below is a quick fix, I'll revisit module - kmemleak interaction in v6 diff --git a/kernel/module/debug_kmemleak.c b/kernel/module/debug_kmemleak.c index b4cc03842d70..df873dad049d 100644 --- a/kernel/module/debug_kmemleak.c +++ b/kernel/module/debug_kmemleak.c @@ -14,7 +14,8 @@ void kmemleak_load_module(const struct module *mod, { /* only scan writable, non-executable sections */ for_each_mod_mem_type(type) { - if (type != MOD_DATA && type != MOD_INIT_DATA) + if (type != MOD_DATA && type != MOD_INIT_DATA && + !mod->mem[type].is_rox) kmemleak_no_scan(mod->mem[type].base); } }
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index eb503f53c319..a0ec99fb9385 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -1053,6 +1053,15 @@ unsigned long arch_max_swapfile_size(void) #ifdef CONFIG_EXECMEM static struct execmem_info execmem_info __ro_after_init; +static void execmem_fill_trapping_insns(void *ptr, size_t size, bool writeable) +{ + /* fill memory with INT3 instructions */ + if (writeable) + memset(ptr, INT3_INSN_OPCODE, size); + else + text_poke_set(ptr, INT3_INSN_OPCODE, size); +} + struct execmem_info __init *execmem_arch_setup(void) { unsigned long start, offset = 0; @@ -1063,8 +1072,23 @@ struct execmem_info __init *execmem_arch_setup(void) start = MODULES_VADDR + offset; execmem_info = (struct execmem_info){ + .fill_trapping_insns = execmem_fill_trapping_insns, .ranges = { - [EXECMEM_DEFAULT] = { + [EXECMEM_MODULE_TEXT] = { + .flags = EXECMEM_KASAN_SHADOW | EXECMEM_ROX_CACHE, + .start = start, + .end = MODULES_END, + .pgprot = PAGE_KERNEL_ROX, + .alignment = MODULE_ALIGN, + }, + [EXECMEM_KPROBES ... EXECMEM_BPF] = { + .flags = EXECMEM_KASAN_SHADOW, + .start = start, + .end = MODULES_END, + .pgprot = PAGE_KERNEL, + .alignment = MODULE_ALIGN, + }, + [EXECMEM_MODULE_DATA] = { .flags = EXECMEM_KASAN_SHADOW, .start = start, .end = MODULES_END,