[Devel] [PATCH RH7 2/2] backport: x86/mm/numa: Fix kernel stack corruption in numa_init()->numa_clear_kernel_node_hotplug()

Konstantin Khorenko khorenko at virtuozzo.com
Wed Feb 3 07:42:46 PST 2016


Also presents in RH7.2 kernel-3.10.0-327.3.1.el7 kernel.

--
Best regards,

Konstantin Khorenko,
Virtuozzo Linux Kernel Team

On 01/30/2016 03:01 PM, Dmitry Safonov wrote:
> From: Dave Young <dyoung at redhat.com>
> commit 52c7ec2a1ef5ca9def7982ddcbdf8cc2798b9636
> x86/mm/numa: Fix kernel stack corruption in numa_init()->numa_clear_kernel_node_hotplug()
>
> I got below kernel panic during kdump test on Thinkpad T420
> laptop:
>
> [    0.000000] No NUMA configuration found
> [    0.000000] Faking a node at [mem 0x0000000000000000-0x0000000037ba4fff]
> [    0.000000] Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: ffffffff81d21910
>   ...
> [    0.000000] Call Trace:
> [    0.000000]  [<ffffffff817c2a26>] dump_stack+0x45/0x57
> [    0.000000]  [<ffffffff817bc8d2>] panic+0xd0/0x204
> [    0.000000]  [<ffffffff81d21910>] ? numa_clear_kernel_node_hotplug+0xe6/0xf2
> [    0.000000]  [<ffffffff8107741b>] __stack_chk_fail+0x1b/0x20
> [    0.000000]  [<ffffffff81d21910>] numa_clear_kernel_node_hotplug+0xe6/0xf2
> [    0.000000]  [<ffffffff81d21e5d>] numa_init+0x1a5/0x520
> [    0.000000]  [<ffffffff81d222b1>] x86_numa_init+0x19/0x3d
> [    0.000000]  [<ffffffff81d22460>] initmem_init+0x9/0xb
> [    0.000000]  [<ffffffff81d0d00c>] setup_arch+0x94f/0xc82
> [    0.000000]  [<ffffffff81d05120>] ? early_idt_handlers+0x120/0x120
> [    0.000000]  [<ffffffff817bd0bb>] ? printk+0x55/0x6b
> [    0.000000]  [<ffffffff81d05120>] ? early_idt_handlers+0x120/0x120
> [    0.000000]  [<ffffffff81d05d9b>] start_kernel+0xe8/0x4d6
> [    0.000000]  [<ffffffff81d05120>] ? early_idt_handlers+0x120/0x120
> [    0.000000]  [<ffffffff81d05120>] ? early_idt_handlers+0x120/0x120
> [    0.000000]  [<ffffffff81d055ee>] x86_64_start_reservations+0x2a/0x2c
> [    0.000000]  [<ffffffff81d05751>] x86_64_start_kernel+0x161/0x184
> [    0.000000] ---[ end Kernel panic - not syncing: stack-protector: Kernel sta
>
> This is caused by writing over the end of numa mask bitmap
> in numa_clear_kernel_node().
>
> numa_clear_kernel_node() tries to set the node id in a mask bitmap,
> by iterating all reserved regions and assuming that every region
> has a valid nid.
>
> This assumption is not true because there's an exception for some
> graphic memory quirks. See trim_snb_memory() in arch/x86/kernel/setup.c
>
> It is easily to reproduce the bug in the kdump kernel because kdump
> kernel use pre-reserved memory instead of the whole memory, but
> kexec pass other reserved memory ranges to 2nd kernel as well.
> like below in my test:
>
> kdump kernel ram 0x2d000000 - 0x37bfffff
> One of the reserved regions: 0x40000000 - 0x40100000 which
> includes 0x40004000, a page excluded in trim_snb_memory(). For
> this memblock reserved region the nid is not set, it is still
> default value MAX_NUMNODES. later node_set will set bit
> MAX_NUMNODES thus stack corruption happen.
>
> This also happens when booting with mem= kernel commandline
> during my test.
>
> Fixing it by adding a check, do not call node_set in case nid is
> MAX_NUMNODES.
>
> Signed-off-by: Dave Young <dyoung at redhat.com>
> Reviewed-by: Yasuaki Ishimatsu <isimatu.yasuaki at jp.fujitsu.com>
> Cc: Borislav Petkov <bp at alien8.de>
> Cc: H. Peter Anvin <hpa at zytor.com>
> Cc: Linus Torvalds <torvalds at linux-foundation.org>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: bhe at redhat.com
> Cc: qiuxishi at huawei.com
> Link: http://lkml.kernel.org/r/20150407134132.GA23522@dhcp-16-198.nay.redhat.com
> Signed-off-by: Ingo Molnar <mingo at kernel.org>
>
> [backport from mainline]
> https://jira.sw.ru/browse/PSBM-43010
> Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
> ---
>   arch/x86/mm/numa.c | 11 +++++++++--
>   1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
> index f11060b..b08f69d 100644
> --- a/arch/x86/mm/numa.c
> +++ b/arch/x86/mm/numa.c
> @@ -492,9 +492,16 @@ static void __init numa_clear_kernel_node_hotplug(void)
>   				  &memblock.reserved, mb->nid);
>   	}
>
> -	/* Mark all kernel nodes. */
> +	/*
> +	 * Mark all kernel nodes.
> +	 *
> +	 * When booting with mem=nn[kMG] or in a kdump kernel, numa_meminfo
> +	 * may not include all the memblock.reserved memory ranges because
> +	 * trim_snb_memory() reserves specific pages for Sandy Bridge graphics.
> +	 */
>   	for_each_memblock(reserved, r)
> -		node_set(r->nid, numa_kernel_nodes);
> +		if (r->nid != MAX_NUMNODES)
> +			node_set(r->nid, numa_kernel_nodes);
>
>   	/* Clear MEMBLOCK_HOTPLUG flag for memory in kernel nodes. */
>   	for (i = 0; i < numa_meminfo.nr_blks; i++) {
>


More information about the Devel mailing list