• James Hogan's avatar
    MIPS: stack protector: Fix per-task canary switch · 8b3c569a
    James Hogan authored
    Commit 1400eb65 (MIPS: r4k,octeon,r2300: stack protector: change canary
    per task) was merged in v3.11 and introduced assembly in the MIPS resume
    functions to update the value of the current canary in
    __stack_chk_guard. However it used PTR_L resulting in a load of the
    canary value, instead of PTR_LA to construct its address. The value is
    intended to be random but is then treated as an address in the
    subsequent LONG_S (store).
    
    This was observed to cause a fault and panic:
    
    CPU 0 Unable to handle kernel paging request at virtual address 139fea20, epc == 8000cc0c, ra == 8034f2a4
    Oops[#1]:
    ...
    $24   : 139fea20 1e1f7cb6
    ...
    Call Trace:
    [<8000cc0c>] resume+0xac/0x118
    [<8034f2a4>] __schedule+0x5f8/0x78c
    [<8034f4e0>] schedule_preempt_disabled+0x20/0x2c
    [<80348eec>] rest_init+0x74/0x84
    [<804dc990>] start_kernel+0x43c/0x454
    Code: 3c18804b  8f184030  8cb901f8 <af190000> 00c0e021  8cb002f0 8cb102f4  8cb202f8  8cb302fc
    
    This can also be forced by modifying
    arch/mips/include/asm/stackprotector.h so that the default
    __stack_chk_guard value is more likely to be a bad (or unaligned)
    pointer.
    
    Fix it to use PTR_LA instead, to load the address of the canary value,
    which the LONG_S can then use to write into it.
    
    Reported-by: bobjones (via #mipslinux on IRC)
    Signed-off-by: default avatarJames Hogan <james.hogan@imgtec.com>
    Cc: Ralf Baechle <ralf@linux-mips.org>
    Cc: Gregory Fong <gregory.0xf0@gmail.com>
    Cc: linux-mips@linux-mips.org
    Cc: stable@vger.kernel.org
    Patchwork: https://patchwork.linux-mips.org/patch/6026/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
    8b3c569a
r2300_switch.S 3.29 KB