Skip to content
  • Stephen Boyd's avatar
    ARM: 7810/1: perf: Fix array out of bounds access in armpmu_map_hw_event() · d9f96635
    Stephen Boyd authored
    
    
    Vince Weaver reports an oops in the ARM perf event code while
    running his perf_fuzzer tool on a pandaboard running v3.11-rc4.
    
    Unable to handle kernel paging request at virtual address 73fd14cc
    pgd = eca6c000
    [73fd14cc] *pgd=00000000
    Internal error: Oops: 5 [#1] SMP ARM
    Modules linked in: snd_soc_omap_hdmi omapdss snd_soc_omap_abe_twl6040 snd_soc_twl6040 snd_soc_omap snd_soc_omap_hdmi_card snd_soc_omap_mcpdm snd_soc_omap_mcbsp snd_soc_core snd_compress regmap_spi snd_pcm snd_page_alloc snd_timer snd soundcore
    CPU: 1 PID: 2790 Comm: perf_fuzzer Not tainted 3.11.0-rc4 #6
    task: eddcab80 ti: ed892000 task.ti: ed892000
    PC is at armpmu_map_event+0x20/0x88
    LR is at armpmu_event_init+0x38/0x280
    pc : [<c001c3e4>]    lr : [<c001c17c>]    psr: 60000013
    sp : ed893e40  ip : ecececec  fp : edfaec00
    r10: 00000000  r9 : 00000000  r8 : ed8c3ac0
    r7 : ed8c3b5c  r6 : edfaec00  r5 : 00000000  r4 : 00000000
    r3 : 000000ff  r2 : c0496144  r1 : c049611c  r0 : edfaec00
    Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
    Control: 10c5387d  Table: aca6c04a  DAC: 00000015
    Process perf_fuzzer (pid: 2790, stack limit = 0xed892240)
    Stack: (0xed893e40 to 0xed894000)
    3e40: 00000800 c001c17c 00000002 c008a748 00000001 00000000 00000000 c00bf078
    3e60: 00000000 edfaee50 00000000 00000000 00000000 edfaec00 ed8c3ac0 edfaec00
    3e80: 00000000 c073ffac ed893f20 c00bf180 00000001 00000000 c00bf078 ed893f20
    3ea0: 00000000 ed8c3ac0 00000000 00000000 00000000 c0cb0818 eddcab80 c00bf440
    3ec0: ed893f20 00000000 eddcab80 eca76800 00000000 eca76800 00000000 00000000
    3ee0: 00000000 ec984c80 eddcab80 c00bfe68 00000000 00000000 00000000 00000080
    3f00: 00000000 ed892000 00000000 ed892030 00000004 ecc7e3c8 ecc7e3c8 00000000
    3f20: 00000000 00000048 ecececec 00000000 00000000 00000000 00000000 00000000
    3f40: 00000000 00000000 00297810 00000000 00000000 00000000 00000000 00000000
    3f60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    3f80: 00000002 00000002 000103a4 00000002 0000016c c00128e8 ed892000 00000000
    3fa0: 00090998 c0012700 00000002 000103a4 00090ab8 00000000 00000000 0000000f
    3fc0: 00000002 000103a4 00000002 0000016c 00090ab0 00090ab8 000107a0 00090998
    3fe0: bed92be0 bed92bd0 0000b785 b6e8f6d0 40000010 00090ab8 00000000 00000000
    [<c001c3e4>] (armpmu_map_event+0x20/0x88) from [<c001c17c>] (armpmu_event_init+0x38/0x280)
    [<c001c17c>] (armpmu_event_init+0x38/0x280) from [<c00bf180>] (perf_init_event+0x108/0x180)
    [<c00bf180>] (perf_init_event+0x108/0x180) from [<c00bf440>] (perf_event_alloc+0x248/0x40c)
    [<c00bf440>] (perf_event_alloc+0x248/0x40c) from [<c00bfe68>] (SyS_perf_event_open+0x4f4/0x8fc)
    [<c00bfe68>] (SyS_perf_event_open+0x4f4/0x8fc) from [<c0012700>] (ret_fast_syscall+0x0/0x48)
    Code: 0a000005 e3540004 0a000016 e3540000 (0791010c)
    
    This is because event->attr.config in armpmu_event_init()
    contains a very large number copied directly from userspace and
    is never checked against the size of the array indexed in
    armpmu_map_hw_event(). Fix the problem by checking the value of
    config before indexing the array and rejecting invalid config
    values.
    
    Reported-by: default avatarVince Weaver <vincent.weaver@maine.edu>
    Tested-by: default avatarVince Weaver <vincent.weaver@maine.edu>
    Acked-by: default avatarWill Deacon <will.deacon@arm.com>
    Signed-off-by: default avatarStephen Boyd <sboyd@codeaurora.org>
    Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
    d9f96635