summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorVladimir Murzin <vladimir.murzin@arm.com>2015-03-06 17:37:45 +0100
committerJason Cooper <jason@lakedaemon.net>2015-03-08 06:33:29 +0100
commit614be385521b08b849da1098625da591984738c0 (patch)
tree3cec5c193cac9f8d563c633c2571fe34185b60af /drivers
parentirqchip: gic: Fix unsafe locking reported by lockdep (diff)
downloadlinux-614be385521b08b849da1098625da591984738c0.tar.xz
linux-614be385521b08b849da1098625da591984738c0.zip
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: [<ffffffc00008a794>] dump_backtrace+0x0/0x184 [<ffffffc00008a928>] show_stack+0x10/0x1c [<ffffffc00075e46c>] dump_stack+0xa0/0xf8 [<ffffffc0001df490>] kasan_report_error+0x23c/0x264 [<ffffffc0001e0188>] check_memory_region+0xc0/0xe4 [<ffffffc0001dedf0>] __asan_load8+0x10/0x1c [<ffffffc000431294>] gic_raise_softirq+0xc4/0x1b4 [<ffffffc000091fc0>] smp_send_reschedule+0x30/0x3c [<ffffffc0000f0d1c>] try_to_wake_up+0x394/0x434 [<ffffffc0000f0de8>] wake_up_process+0x2c/0x6c [<ffffffc0000d9570>] wake_up_worker+0x38/0x48 [<ffffffc0000dbb50>] insert_work+0xac/0xec [<ffffffc0000dbd38>] __queue_work+0x1a8/0x374 [<ffffffc0000dbf60>] queue_work_on+0x5c/0x7c [<ffffffc0000d8a78>] call_usermodehelper_exec+0x170/0x188 [<ffffffc0004037b8>] kobject_uevent_env+0x650/0x6bc [<ffffffc000403830>] kobject_uevent+0xc/0x18 [<ffffffc00040292c>] kset_register+0xa8/0xc8 [<ffffffc0004d6c88>] bus_register+0x134/0x2e8 [<ffffffc0004d73b4>] subsys_virtual_register+0x2c/0x5c [<ffffffc000a76a4c>] wq_sysfs_init+0x14/0x20 [<ffffffc000082a28>] do_one_initcall+0xa8/0x1fc [<ffffffc000a70db4>] kernel_init_freeable+0x1ec/0x294 [<ffffffc00075aa5c>] 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 <vladimir.murzin@arm.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Link: https://lkml.kernel.org/r/1425659870-11832-7-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/irqchip/irq-gic-v3.c2
1 files changed, 1 insertions, 1 deletions
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);