diff options
author | Vincent Whitchurch <vincent.whitchurch@axis.com> | 2022-05-23 16:04:03 +0200 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2022-05-27 09:03:41 +0200 |
commit | 2a4a62a14be1947fa945c5c11ebf67326381a568 (patch) | |
tree | 73328f4daeb23d1e322bfe6675486db52c1b2344 /arch/x86/um | |
parent | um: chan_user: Fix winch_tramp() return value (diff) | |
download | linux-2a4a62a14be1947fa945c5c11ebf67326381a568.tar.xz linux-2a4a62a14be1947fa945c5c11ebf67326381a568.zip |
um: Fix out-of-bounds read in LDT setup
syscall_stub_data() expects the data_count parameter to be the number of
longs, not bytes.
==================================================================
BUG: KASAN: stack-out-of-bounds in syscall_stub_data+0x70/0xe0
Read of size 128 at addr 000000006411f6f0 by task swapper/1
CPU: 0 PID: 1 Comm: swapper Not tainted 5.18.0+ #18
Call Trace:
show_stack.cold+0x166/0x2a7
__dump_stack+0x3a/0x43
dump_stack_lvl+0x1f/0x27
print_report.cold+0xdb/0xf81
kasan_report+0x119/0x1f0
kasan_check_range+0x3a3/0x440
memcpy+0x52/0x140
syscall_stub_data+0x70/0xe0
write_ldt_entry+0xac/0x190
init_new_ldt+0x515/0x960
init_new_context+0x2c4/0x4d0
mm_init.constprop.0+0x5ed/0x760
mm_alloc+0x118/0x170
0x60033f48
do_one_initcall+0x1d7/0x860
0x60003e7b
kernel_init+0x6e/0x3d4
new_thread_handler+0x1e7/0x2c0
The buggy address belongs to stack of task swapper/1
and is located at offset 64 in frame:
init_new_ldt+0x0/0x960
This frame has 2 objects:
[32, 40) 'addr'
[64, 80) 'desc'
==================================================================
Fixes: 858259cf7d1c443c83 ("uml: maintain own LDT entries")
Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com>
Cc: stable@vger.kernel.org
Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'arch/x86/um')
-rw-r--r-- | arch/x86/um/ldt.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/arch/x86/um/ldt.c b/arch/x86/um/ldt.c index 3ee234b6234d..255a44dd415a 100644 --- a/arch/x86/um/ldt.c +++ b/arch/x86/um/ldt.c @@ -23,9 +23,11 @@ static long write_ldt_entry(struct mm_id *mm_idp, int func, { long res; void *stub_addr; + + BUILD_BUG_ON(sizeof(*desc) % sizeof(long)); + res = syscall_stub_data(mm_idp, (unsigned long *)desc, - (sizeof(*desc) + sizeof(long) - 1) & - ~(sizeof(long) - 1), + sizeof(*desc) / sizeof(long), addr, &stub_addr); if (!res) { unsigned long args[] = { func, |