21 Sep, 2016

1 commit

  • While running a compile on arm64, I hit a memory exposure

    usercopy: kernel memory exposure attempt detected from fffffc0000f3b1a8 (buffer_head) (1 bytes)
    ------------[ cut here ]------------
    kernel BUG at mm/usercopy.c:75!
    Internal error: Oops - BUG: 0 [#1] SMP
    Modules linked in: ip6t_rpfilter ip6t_REJECT
    nf_reject_ipv6 xt_conntrack ip_set nfnetlink ebtable_broute bridge stp
    llc ebtable_nat ip6table_security ip6table_raw ip6table_nat
    nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle
    iptable_security iptable_raw iptable_nat nf_conntrack_ipv4
    nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle
    ebtable_filter ebtables ip6table_filter ip6_tables vfat fat xgene_edac
    xgene_enet edac_core i2c_xgene_slimpro i2c_core at803x realtek xgene_dma
    mdio_xgene gpio_dwapb gpio_xgene_sb xgene_rng mailbox_xgene_slimpro nfsd
    auth_rpcgss nfs_acl lockd grace sunrpc xfs libcrc32c sdhci_of_arasan
    sdhci_pltfm sdhci mmc_core xhci_plat_hcd gpio_keys
    CPU: 0 PID: 19744 Comm: updatedb Tainted: G W 4.8.0-rc3-threadinfo+ #1
    Hardware name: AppliedMicro X-Gene Mustang Board/X-Gene Mustang Board, BIOS 3.06.12 Aug 12 2016
    task: fffffe03df944c00 task.stack: fffffe00d128c000
    PC is at __check_object_size+0x70/0x3f0
    LR is at __check_object_size+0x70/0x3f0
    ...
    [] __check_object_size+0x70/0x3f0
    [] filldir64+0x158/0x1a0
    [] __fat_readdir+0x4a0/0x558 [fat]
    [] fat_readdir+0x34/0x40 [fat]
    [] iterate_dir+0x190/0x1e0
    [] SyS_getdents64+0x88/0x120
    [] el0_svc_naked+0x24/0x28

    fffffc0000f3b1a8 is a module address. Modules may have compiled in
    strings which could get copied to userspace. In this instance, it
    looks like "." which matches with a size of 1 byte. Extend the
    is_vmalloc_addr check to be is_vmalloc_or_module_addr to cover
    all possible cases.

    Signed-off-by: Laura Abbott
    Signed-off-by: Kees Cook

    Laura Abbott
     

08 Sep, 2016

1 commit

  • A custom allocator without __GFP_COMP that copies to userspace has been
    found in vmw_execbuf_process[1], so this disables the page-span checker
    by placing it behind a CONFIG for future work where such things can be
    tracked down later.

    [1] https://bugzilla.redhat.com/show_bug.cgi?id=1373326

    Reported-by: Vinson Lee
    Fixes: f5509cc18daa ("mm: Hardened usercopy")
    Signed-off-by: Kees Cook

    Kees Cook
     

23 Aug, 2016

2 commits

  • When running with a local patch which moves the '_stext' symbol to the
    very beginning of the kernel text area, I got the following panic with
    CONFIG_HARDENED_USERCOPY:

    usercopy: kernel memory exposure attempt detected from ffff88103dfff000 () (4096 bytes)
    ------------[ cut here ]------------
    kernel BUG at mm/usercopy.c:79!
    invalid opcode: 0000 [#1] SMP
    ...
    CPU: 0 PID: 4800 Comm: cp Not tainted 4.8.0-rc3.after+ #1
    Hardware name: Dell Inc. PowerEdge R720/0X3D66, BIOS 2.5.4 01/22/2016
    task: ffff880817444140 task.stack: ffff880816274000
    RIP: 0010:[] __check_object_size+0x76/0x413
    RSP: 0018:ffff880816277c40 EFLAGS: 00010246
    RAX: 000000000000006b RBX: ffff88103dfff000 RCX: 0000000000000000
    RDX: 0000000000000000 RSI: ffff88081f80dfa8 RDI: ffff88081f80dfa8
    RBP: ffff880816277c90 R08: 000000000000054c R09: 0000000000000000
    R10: 0000000000000005 R11: 0000000000000006 R12: 0000000000001000
    R13: ffff88103e000000 R14: ffff88103dffffff R15: 0000000000000001
    FS: 00007fb9d1750800(0000) GS:ffff88081f800000(0000) knlGS:0000000000000000
    CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 00000000021d2000 CR3: 000000081a08f000 CR4: 00000000001406f0
    Stack:
    ffff880816277cc8 0000000000010000 000000043de07000 0000000000000000
    0000000000001000 ffff880816277e60 0000000000001000 ffff880816277e28
    000000000000c000 0000000000001000 ffff880816277ce8 ffffffff8136c3a6
    Call Trace:
    [] copy_page_to_iter_iovec+0xa6/0x1c0
    [] copy_page_to_iter+0x16/0x90
    [] generic_file_read_iter+0x3e3/0x7c0
    [] ? xfs_file_buffered_aio_write+0xad/0x260 [xfs]
    [] ? down_read+0x12/0x40
    [] xfs_file_buffered_aio_read+0x51/0xc0 [xfs]
    [] xfs_file_read_iter+0x62/0xb0 [xfs]
    [] __vfs_read+0xdf/0x130
    [] vfs_read+0x8e/0x140
    [] SyS_read+0x55/0xc0
    [] do_syscall_64+0x67/0x160
    [] entry_SYSCALL64_slow_path+0x25/0x25
    RIP: 0033:[] 0x7fb9d0c33c00
    RSP: 002b:00007ffc9c262f28 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
    RAX: ffffffffffffffda RBX: fffffffffff8ffff RCX: 00007fb9d0c33c00
    RDX: 0000000000010000 RSI: 00000000021c3000 RDI: 0000000000000004
    RBP: 00000000021c3000 R08: 0000000000000000 R09: 00007ffc9c264d6c
    R10: 00007ffc9c262c50 R11: 0000000000000246 R12: 0000000000010000
    R13: 00007ffc9c2630b0 R14: 0000000000000004 R15: 0000000000010000
    Code: 81 48 0f 44 d0 48 c7 c6 90 4d a3 81 48 c7 c0 bb b3 a2 81 48 0f 44 f0 4d 89 e1 48 89 d9 48 c7 c7 68 16 a3 81 31 c0 e8 f4 57 f7 ff 0b 48 8d 90 00 40 00 00 48 39 d3 0f 83 22 01 00 00 48 39 c3
    RIP [] __check_object_size+0x76/0x413
    RSP

    The checked object's range [ffff88103dfff000, ffff88103e000000) is
    valid, so there shouldn't have been a BUG. The hardened usercopy code
    got confused because the range's ending address is the same as the
    kernel's text starting address at 0xffff88103e000000. The overlap check
    is slightly off.

    Fixes: f5509cc18daa ("mm: Hardened usercopy")
    Signed-off-by: Josh Poimboeuf
    Signed-off-by: Kees Cook

    Josh Poimboeuf
     
  • check_bogus_address() checked for pointer overflow using this expression,
    where 'ptr' has type 'const void *':

    ptr + n < ptr

    Since pointer wraparound is undefined behavior, gcc at -O2 by default
    treats it like the following, which would not behave as intended:

    (long)n < 0

    Fortunately, this doesn't currently happen for kernel code because kernel
    code is compiled with -fno-strict-overflow. But the expression should be
    fixed anyway to use well-defined integer arithmetic, since it could be
    treated differently by different compilers in the future or could be
    reported by tools checking for undefined behavior.

    Signed-off-by: Eric Biggers
    Signed-off-by: Kees Cook

    Eric Biggers
     

27 Jul, 2016

1 commit

  • This is the start of porting PAX_USERCOPY into the mainline kernel. This
    is the first set of features, controlled by CONFIG_HARDENED_USERCOPY. The
    work is based on code by PaX Team and Brad Spengler, and an earlier port
    from Casey Schaufler. Additional non-slab page tests are from Rik van Riel.

    This patch contains the logic for validating several conditions when
    performing copy_to_user() and copy_from_user() on the kernel object
    being copied to/from:
    - address range doesn't wrap around
    - address range isn't NULL or zero-allocated (with a non-zero copy size)
    - if on the slab allocator:
    - object size must be less than or equal to copy size (when check is
    implemented in the allocator, which appear in subsequent patches)
    - otherwise, object must not span page allocations (excepting Reserved
    and CMA ranges)
    - if on the stack
    - object must not extend before/after the current process stack
    - object must be contained by a valid stack frame (when there is
    arch/build support for identifying stack frames)
    - object must not overlap with kernel text

    Signed-off-by: Kees Cook
    Tested-by: Valdis Kletnieks
    Tested-by: Michael Ellerman

    Kees Cook