From 614be385521b08b849da1098625da591984738c0 Mon Sep 17 00:00:00 2001 From: Vladimir Murzin Date: Fri, 6 Mar 2015 16:37:45 +0000 Subject: irqchip: gic-v3: Fix out of bounds access to cpu_logical_map While playing with KASan support for arm64/arm the following appeared on boot: ================================================================== BUG: AddressSanitizer: out of bounds access in __asan_load8+0x14/0x1c at addr ffffffc000ad0dc0 Read of size 8 by task swapper/0/1 page:ffffffbdc202b400 count:1 mapcount:0 mapping: (null) index:0x0 flags: 0x400(reserved) page dumped because: kasan: bad access detected Address belongs to variable __cpu_logical_map+0x200/0x220 CPU: 2 PID: 1 Comm: swapper/0 Not tainted 3.19.0-rc6-next-20150129+ #481 Hardware name: FVP Base (DT) Call trace: [] dump_backtrace+0x0/0x184 [] show_stack+0x10/0x1c [] dump_stack+0xa0/0xf8 [] kasan_report_error+0x23c/0x264 [] check_memory_region+0xc0/0xe4 [] __asan_load8+0x10/0x1c [] gic_raise_softirq+0xc4/0x1b4 [] smp_send_reschedule+0x30/0x3c [] try_to_wake_up+0x394/0x434 [] wake_up_process+0x2c/0x6c [] wake_up_worker+0x38/0x48 [] insert_work+0xac/0xec [] __queue_work+0x1a8/0x374 [] queue_work_on+0x5c/0x7c [] call_usermodehelper_exec+0x170/0x188 [] kobject_uevent_env+0x650/0x6bc [] kobject_uevent+0xc/0x18 [] kset_register+0xa8/0xc8 [] bus_register+0x134/0x2e8 [] subsys_virtual_register+0x2c/0x5c [] wq_sysfs_init+0x14/0x20 [] do_one_initcall+0xa8/0x1fc [] kernel_init_freeable+0x1ec/0x294 [] kernel_init+0xc/0xec Memory state around the buggy address: ffffff80003e0820: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffffff80003e0830: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >ffffff80003e0840: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 00 ^ ffffff80003e0850: 00 00 fa fa fa fa fa fa 00 00 00 00 00 00 00 00 ================================================================== The reason for that cpumask_next() returns >= nr_cpu_ids if no further cpus set, but "==" condition is checked only, so we end up with out-of-bounds access to cpu_logical_map. Fix is by using the condition check for cpumask_next. Signed-off-by: Vladimir Murzin Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1425659870-11832-7-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/irqchip') diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 1c6dea2fbc34..fd8850def1b8 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -466,7 +466,7 @@ static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask, tlist |= 1 << (mpidr & 0xf); cpu = cpumask_next(cpu, mask); - if (cpu == nr_cpu_ids) + if (cpu >= nr_cpu_ids) goto out; mpidr = cpu_logical_map(cpu); -- cgit v1.2.1