• Mateusz Guzik's avatar
    prctl: take mmap sem for writing to protect against others · ddf1d398
    Mateusz Guzik authored
    An unprivileged user can trigger an oops on a kernel with
    CONFIG_CHECKPOINT_RESTORE.
    
    proc_pid_cmdline_read takes mmap_sem for reading and obtains args + env
    start/end values. These get sanity checked as follows:
            BUG_ON(arg_start > arg_end);
            BUG_ON(env_start > env_end);
    
    These can be changed by prctl_set_mm. Turns out also takes the semaphore for
    reading, effectively rendering it useless. This results in:
    
      kernel BUG at fs/proc/base.c:240!
      invalid opcode: 0000 [#1] SMP
      Modules linked in: virtio_net
      CPU: 0 PID: 925 Comm: a.out Not tainted 4.4.0-rc8-next-20160105dupa+ #71
      Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
      task: ffff880077a68000 ti: ffff8800784d0000 task.ti: ffff8800784d0000
      RIP: proc_pid_cmdline_read+0x520/0x530
      RSP: 0018:ffff8800784d3db8  EFLAGS: 00010206
      RAX: ffff880077c5b6b0 RBX: ffff8800784d3f18 RCX: 0000000000000000
      RDX: 0000000000000002 RSI: 00007f78e8857000 RDI: 0000000000000246
      RBP: ffff8800784d3e40 R08: 0000000000000008 R09: 0000000000000001
      R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000050
      R13: 00007f78e8857800 R14: ffff88006fcef000 R15: ffff880077c5b600
      FS:  00007f78e884a740(0000) GS:ffff88007b200000(0000) knlGS:0000000000000000
      CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
      CR2: 00007f78e8361770 CR3: 00000000790a5000 CR4: 00000000000006f0
      Call Trace:
        __vfs_read+0x37/0x100
        vfs_read+0x82/0x130
        SyS_read+0x58/0xd0
        entry_SYSCALL_64_fastpath+0x12/0x76
      Code: 4c 8b 7d a8 eb e9 48 8b 9d 78 ff ff ff 4c 8b 7d 90 48 8b 03 48 39 45 a8 0f 87 f0 fe ff ff e9 d1 fe ff ff 4c 8b 7d 90 eb c6 0f 0b <0f> 0b 0f 0b 66 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00
      RIP   proc_pid_cmdline_read+0x520/0x530
      ---[ end trace 97882617ae9c6818 ]---
    
    Turns out there are instances where the code just reads aformentioned
    values without locking whatsoever - namely environ_read and get_cmdline.
    
    Interestingly these functions look quite resilient against bogus values,
    but I don't believe this should be relied upon.
    
    The first patch gets rid of the oops bug by grabbing mmap_sem for
    writing.
    
    The second patch is optional and puts locking around aformentioned
    consumers for safety.  Consumers of other fields don't seem to benefit
    from similar treatment and are left untouched.
    
    This patch (of 2):
    
    The code was taking the semaphore for reading, which does not protect
    against readers nor concurrent modifications.
    
    The problem could cause a sanity checks to fail in procfs's cmdline
    reader, resulting in an OOPS.
    
    Note that some functions perform an unlocked read of various mm fields,
    but they seem to be fine despite possible modificaton.
    Signed-off-by: default avatarMateusz Guzik <mguzik@redhat.com>
    Acked-by: default avatarCyrill Gorcunov <gorcunov@openvz.org>
    Cc: Alexey Dobriyan <adobriyan@gmail.com>
    Cc: Jarod Wilson <jarod@redhat.com>
    Cc: Jan Stancek <jstancek@redhat.com>
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Cc: Anshuman Khandual <anshuman.linux@gmail.com>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    ddf1d398
sys.c 57.5 KB