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, another kernel panic was triggered by running the POC of the aforementioned commit:
BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 PGD 800000001840b067 P4D 800000001840b067 PUD 1840c067 PMD 0 Oops: 0002 [#1] SMP PTI CPU: 7 PID: 273 Comm: exe Tainted: G OE 4.19.90+ #6 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_open+0x49/0xf0 Code: 00 00 00 65 48 8b 04 25 28 00 00 00 48 89 44 24 20 31 c0 4c 89 e7 e8 a6 ec ff ff 49 8b 44 24 38 48 c7 c7 e0 a5 13 97 8b 40 1c <89> 45 08 e8 6f 80 ff ff ba 02 00 00 00 89 45 0c 8b 43 44 8b 73 40 RSP: 0018:ffffbb7300867ba0 EFLAGS: 00010246 RAX: 0000000000000003 RBX: ffff9dc301961400 RCX: 00000000000081ed RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffffffff9713a5e0 RBP: 0000000000000000 R08: 0000000000000001 R09: ffff9dc301fedcb0 R10: 0000000000000007 R11: 7fffffffffffffff R12: ffff9dc30204fd70 R13: 0000000000000000 R14: ffff9dc301961410 R15: ffffbb7300867c70 FS: 0000000000d258c0(0000) GS:ffff9dc33e9c0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000008 CR3: 00000000022bc000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: ? generic_permission+0x10a/0x190 security_file_open+0x26/0x90 do_dentry_open+0xd9/0x380 do_last+0x197/0x8d0 path_openat+0x89/0x280 do_filp_open+0x91/0x100 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:00007ffe7b1cebd8 EFLAGS: 00000246 ORIG_RAX: 000000000000003b RAX: ffffffffffffffda RBX: 0000000000d27ee0 RCX: 000000000049a5db RDX: 0000000000d27f08 RSI: 0000000000d27ee0 RDI: 0000000000d27f48 RBP: 0000000000d27f48 R08: fefefefefefefeff R09: fefefeff666d686f R10: 0000000000d25b90 R11: 0000000000000246 R12: 0000000000d27f08 R13: 0000000000655894 R14: 0000000000d27f08 R15: 0000000000d26ed0 Modules linked in: e1000(OE) CR2: 0000000000000008 ---[ end trace e4eb884974c22e2d ]--- RIP: 0010:selinux_file_open+0x49/0xf0 Code: 00 00 00 65 48 8b 04 25 28 00 00 00 48 89 44 24 20 31 c0 4c 89 e7 e8 a6 ec ff ff 49 8b 44 24 38 48 c7 c7 e0 a5 13 97 8b 40 1c <89> 45 08 e8 6f 80 ff ff ba 02 00 00 00 89 45 0c 8b 43 44 8b 73 40 RSP: 0018:ffffbb7300867ba0 EFLAGS: 00010246 RAX: 0000000000000003 RBX: ffff9dc301961400 RCX: 00000000000081ed RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffffffff9713a5e0 RBP: 0000000000000000 R08: 0000000000000001 R09: ffff9dc301fedcb0 R10: 0000000000000007 R11: 7fffffffffffffff R12: ffff9dc30204fd70 R13: 0000000000000000 R14: ffff9dc301961410 R15: ffffbb7300867c70 FS: 0000000000d258c0(0000) GS:ffff9dc33e9c0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000008 CR3: 00000000022bc000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Kernel panic - not syncing: Fatal exception Kernel Offset: 0x14400000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) ---[ end Kernel panic - not syncing: Fatal exception ]---
The problem was caused by selinux_file_open() accessing a file's fsec being NULL, which indicated that the file_alloc_security hook should be deleted later (at least after the file_open hook) when disabling SELinux at runtime. Here I put it into the "allocating" part.
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 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index cd26c1199353..85ac12d6b2f4 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -7040,7 +7040,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(inode_copy_up_xattr, selinux_inode_copy_up_xattr),
LSM_HOOK_INIT(file_permission, selinux_file_permission), - LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security), LSM_HOOK_INIT(file_free_security, selinux_file_free_security), LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl), LSM_HOOK_INIT(mmap_file, selinux_mmap_file), @@ -7207,6 +7206,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(shm_alloc_security, selinux_shm_alloc_security), 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),
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)
From: Zhong Jinghua zhongjinghua@huawei.com
hulk inclusion category: bugfix bugzilla: 188413, https://gitee.com/openeuler/kernel/issues/I6GWYG CVE: NA
----------------------------------------
A panic error is like below:
nbd_genl_connect nbd_dev_add first_minor = index << part_shift; // index =-1 ... __device_add_disk blk_alloc_devt *devt = MKDEV(disk->major, disk->first_minor + part->partno); // part->partno = 0, first_minor = 11...110000 major is covered
There, index < 0 will reassign an index, but here disk->first_minor is assigned -1 << part_shift.
This causes to the creation of the device with the same major and minor device numbers each time the incoming index<0, and this will lead to creation of kobject failed: Warning: kobject_add_internal failed for 4095:1048544 with -EEXIST, don't try to register things with the same name in the same directory.
Fix it by moving the first_minor assignment down to after getting the new index.
Fixes: 01f7594e62e9 ("nbd: Fix use-after-free in blk_mq_free_rqs") Signed-off-by: Zhong Jinghua zhongjinghua@huawei.com Reviewed-by: Yu Kuai yukuai3@huawei.com Reviewed-by: Hou Tao houtao1@huawei.com Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com --- drivers/block/nbd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 8dbbd676d275..551b2f7da8ef 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -1706,7 +1706,6 @@ static int nbd_dev_add(int index) struct gendisk *disk; struct request_queue *q; int err = -ENOMEM; - int first_minor = index << part_shift;
nbd = kzalloc(sizeof(struct nbd_device), GFP_KERNEL); if (!nbd) @@ -1770,7 +1769,7 @@ static int nbd_dev_add(int index) refcount_set(&nbd->refs, 1); INIT_LIST_HEAD(&nbd->list); disk->major = NBD_MAJOR; - disk->first_minor = first_minor; + disk->first_minor = index << part_shift; disk->fops = &nbd_fops; disk->private_data = nbd; sprintf(disk->disk_name, "nbd%d", index);