From: "GONG, Ruiqi" gongruiqi1@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6DRJ1 CVE: NA
----------------------------------------
After backporting commit cfff75d8973a ("selinux: reorder hooks to make runtime disable less broken") to the 4.19 kernel of openEuler-1.0-LTS, various kernel panic problems were still triggered by running the POC of the aforementioned commit.
Here's a case from selinux_file_alloc_security():
BUG: unable to handle kernel NULL pointer dereference at 0000000000000004 PGD 8000000002273067 P4D 8000000002273067 PUD 225c067 PMD 0 Oops: 0000 [#1] SMP PTI CPU: 0 PID: 299 Comm: exe Tainted: G OE 4.19.90+ #7 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014 RIP: 0010:selinux_file_alloc_security+0x2a/0x50 Code: 0f 1f 44 00 00 55 be c0 80 60 00 53 48 89 fb 48 8b 3d c2 f3 98 01 65 48 8b 04 25 80 64 01 00 48 8b 80 b8 0a 00 00 48 8b 40 78 <8b> 68 04 e8 ce ce ee ff 48 85 c0 74 11 89 28 89 68 04 48 89 83 c0 RSP: 0018:ffffa3ff40967c48 EFLAGS: 00010282 RAX: 0000000000000000 RBX: ffff94e881b6a600 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 00000000006080c0 RDI: ffff94e8811472c0 RBP: ffff94e881b6a600 R08: 0000000000000100 R09: 0000000000000000 R10: ffff94e881b6a600 R11: 0000000000000020 R12: ffff94e881b6a600 R13: 0000000000000041 R14: ffffa3ff40967d10 R15: ffff94e882202c80 FS: 00000000007d28c0(0000) GS:ffff94e8be800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000004 CR3: 0000000002862000 CR4: 00000000000006f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: security_file_alloc+0x22/0x40 __alloc_file+0x52/0x110 alloc_empty_file+0x41/0xb0 path_openat+0x43/0x280 do_filp_open+0x91/0x100 ? filemap_map_pages+0x424/0x460 ? do_fault+0x21b/0x4c0 do_open_execat+0x79/0x180 __do_execve_file.isra.0+0x6dd/0x8b0 __x64_sys_execve+0x35/0x40 do_syscall_64+0x63/0x250 ? async_page_fault+0x8/0x30 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x49a5db Code: 41 89 01 eb da 66 2e 0f 1f 84 00 00 00 00 00 f7 d8 64 41 89 01 eb d6 0f 1f 84 00 00 00 00 00 f3 0f 1e fa b8 3b 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007ffce51a0148 EFLAGS: 00000246 ORIG_RAX: 000000000000003b RAX: ffffffffffffffda RBX: 00000000007d4ee0 RCX: 000000000049a5db RDX: 00000000007d4f08 RSI: 00000000007d4ee0 RDI: 00000000007d4f48 RBP: 00000000007d4f48 R08: fefefefefefefeff R09: fefefeff666d686f R10: 00000000007d2b90 R11: 0000000000000246 R12: 00000000007d4f08 R13: 0000000000655894 R14: 00000000007d4f08 R15: 00000000007d3ed0 Modules linked in: e1000(OE) CR2: 0000000000000004 ---[ end trace 4a826955419bd28a ]--- RIP: 0010:selinux_file_alloc_security+0x2a/0x50 Code: 0f 1f 44 00 00 55 be c0 80 60 00 53 48 89 fb 48 8b 3d c2 f3 98 01 65 48 8b 04 25 80 64 01 00 48 8b 80 b8 0a 00 00 48 8b 40 78 <8b> 68 04 e8 ce ce ee ff 48 85 c0 74 11 89 28 89 68 04 48 89 83 c0 RSP: 0018:ffffa3ff40967c48 EFLAGS: 00010282 RAX: 0000000000000000 RBX: ffff94e881b6a600 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 00000000006080c0 RDI: ffff94e8811472c0 RBP: ffff94e881b6a600 R08: 0000000000000100 R09: 0000000000000000 R10: ffff94e881b6a600 R11: 0000000000000020 R12: ffff94e881b6a600 R13: 0000000000000041 R14: ffffa3ff40967d10 R15: ffff94e882202c80 FS: 00000000007d28c0(0000) GS:ffff94e8be800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000004 CR3: 0000000002862000 CR4: 00000000000006f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Kernel panic - not syncing: Fatal exception Kernel Offset: 0x33400000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) ---[ end Kernel panic - not syncing: Fatal exception ]---
Another one from selinux_inode_alloc_security():
BUG: unable to handle kernel NULL pointer dereference at 0000000000000004 PGD 8000000002187067 P4D 8000000002187067 PUD 2170067 PMD 0 Oops: 0000 [#1] SMP PTI CPU: 7 PID: 521 Comm: ping Tainted: G OE 4.19.90+ #8 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014 RIP: 0010:selinux_inode_alloc_security+0x2a/0x80 Code: 0f 1f 44 00 00 55 be 40 80 60 00 53 48 89 fb 48 8b 3d 6a 0c 99 01 65 48 8b 04 25 80 64 01 00 48 8b 80 b8 0a 00 00 48 8b 40 78 <8b> 68 04 e8 6e e7 ee ff 48 85 c0 74 36 48 8d 50 08 c7 40 24 00 00 RSP: 0018:ffffbd7741077b08 EFLAGS: 00010282 RAX: 0000000000000000 RBX: ffff95c48251e738 RCX: 0000000000000000 RDX: ffffffff85d11344 RSI: 0000000000608040 RDI: ffff95c481004380 RBP: ffff95c48251e738 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: ffff95c48251e738 R13: ffff95c4822ac2c0 R14: ffffbd7741077dd0 R15: 0000000000000000 FS: 00000000018f08c0(0000) GS:ffff95c4be9c0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000004 CR3: 00000000022dc000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: security_inode_alloc+0x2a/0x40 inode_init_always+0x1b9/0x1d0 alloc_inode+0x2f/0x90 new_inode_pseudo+0xd/0x60 new_inode+0x13/0x30 proc_pid_make_inode+0x18/0xb0 proc_pid_instantiate+0x1e/0x90 proc_pid_lookup+0x4e/0x80 proc_root_lookup+0x18/0x40 __lookup_slow+0x94/0x160 lookup_slow+0x36/0x50 walk_component+0x1c4/0x340 ? inode_permission+0x35/0x1a0 link_path_walk.part.0+0x1af/0x540 ? proc_ns_get_link+0xb0/0xb0 path_lookupat.isra.0+0x4e/0x230 filename_lookup+0xae/0x180 ? simple_attr_release+0x20/0x20 ? strncpy_from_user+0x47/0x160 do_readlinkat+0x5d/0x130 __x64_sys_readlink+0x1b/0x20 do_syscall_64+0x63/0x250 ? async_page_fault+0x8/0x30 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x5185e3 Code: 53 48 81 ec 00 10 00 00 48 83 0c 24 00 48 83 ec 08 ba 00 10 00 00 48 8d 3d f7 af 15 00 b8 59 00 00 00 48 89 e5 48 89 ee 0f 05 <3d> 00 f0 ff ff 77 5e 85 c0 7e 5a 0f b6 14 24 80 fa 5b 74 51 80 fa RSP: 002b:00007ffe7aa96960 EFLAGS: 00000206 ORIG_RAX: 0000000000000059 RAX: ffffffffffffffda RBX: 0000000000400770 RCX: 00000000005185e3 RDX: 0000000000001000 RSI: 00007ffe7aa96960 RDI: 00000000006735cd RBP: 00007ffe7aa96960 R08: 0000000000000003 R09: 00007ffe7aa97a64 R10: 0000000000671d9a R11: 0000000000000206 R12: 00007ffe7aa97b58 R13: 00007ffe7aa97b80 R14: 0000000000690018 R15: 0000000000000000 Modules linked in: e1000(OE) CR2: 0000000000000004 ---[ end trace a5121fc2d5201098 ]--- RIP: 0010:selinux_inode_alloc_security+0x2a/0x80 Code: 0f 1f 44 00 00 55 be 40 80 60 00 53 48 89 fb 48 8b 3d 6a 0c 99 01 65 48 8b 04 25 80 64 01 00 48 8b 80 b8 0a 00 00 48 8b 40 78 <8b> 68 04 e8 6e e7 ee ff 48 85 c0 74 36 48 8d 50 08 c7 40 24 00 00 RSP: 0018:ffffbd7741077b08 EFLAGS: 00010282 RAX: 0000000000000000 RBX: ffff95c48251e738 RCX: 0000000000000000 RDX: ffffffff85d11344 RSI: 0000000000608040 RDI: ffff95c481004380 RBP: ffff95c48251e738 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: ffff95c48251e738 R13: ffff95c4822ac2c0 R14: ffffbd7741077dd0 R15: 0000000000000000 FS: 00000000018f08c0(0000) GS:ffff95c4be9c0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000004 CR3: 00000000022dc000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Kernel panic - not syncing: Fatal exception Kernel Offset: 0x3000000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) ---[ end Kernel panic - not syncing: Fatal exception ]---
These problems were all caused by accessing a credential's tsec being NULL. Given that many "allocating" hooks would access tsec as well (e.g. selinux_{key,bpf_{map,prog}}_alloc, selinux_ib_alloc_security etc), make a fourth block and move cred hooks of allocating tsec out there.
Signed-off-by: GONG, Ruiqi gongruiqi1@huawei.com Reviewed-by: Wang Weiyang wangweiyang2@huawei.com Reviewed-by: Xiu Jianfeng xiujianfeng@huawei.com Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com --- security/selinux/hooks.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 85ac12d6b2f4..3550ded07457 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -7055,7 +7055,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(task_alloc, selinux_task_alloc), LSM_HOOK_INIT(cred_free, selinux_cred_free), - LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare), LSM_HOOK_INIT(cred_transfer, selinux_cred_transfer), LSM_HOOK_INIT(cred_getsecid, selinux_cred_getsecid), LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as), @@ -7207,7 +7206,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), LSM_HOOK_INIT(inode_alloc_security, selinux_inode_alloc_security), LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security), - LSM_HOOK_INIT(cred_alloc_blank, selinux_cred_alloc_blank), LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security), LSM_HOOK_INIT(secid_to_secctx, selinux_secid_to_secctx), LSM_HOOK_INIT(inode_getsecctx, selinux_inode_getsecctx), @@ -7232,6 +7230,12 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(bpf_map_alloc_security, selinux_bpf_map_alloc), LSM_HOOK_INIT(bpf_prog_alloc_security, selinux_bpf_prog_alloc), #endif + + /* + * Hooks with tsec allocation should be kept until the really last + */ + LSM_HOOK_INIT(cred_alloc_blank, selinux_cred_alloc_blank), + LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare), };
static __init int selinux_init(void)