• Leon Romanovsky's avatar
    RDMA/uverbs: Protect from races between lookup and destroy of uobjects · 6623e3e3
    Leon Romanovsky authored
    The race is between lookup_get_idr_uobject and
    uverbs_idr_remove_uobj -> uverbs_uobject_put.
    
    We deliberately do not call sychronize_rcu after the idr_remove in
    uverbs_idr_remove_uobj for performance reasons, instead we call
    kfree_rcu() during uverbs_uobject_put.
    
    However, this means we can obtain pointers to uobj's that have
    already been released and must protect against krefing them
    using kref_get_unless_zero.
    
    ==================================================================
    BUG: KASAN: use-after-free in copy_ah_attr_from_uverbs.isra.2+0x860/0xa00
    Read of size 4 at addr ffff88005fda1ac8 by task syz-executor2/441
    
    CPU: 1 PID: 441 Comm: syz-executor2 Not tainted 4.15.0-rc2+ #56
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
    rel-1.7.5-0-ge51488c-20140602_164612-nilsson.home.kraxel.org 04/01/2014
    Call Trace:
    dump_stack+0x8d/0xd4
    print_address_description+0x73/0x290
    kasan_report+0x25c/0x370
    ? copy_ah_attr_from_uverbs.isra.2+0x860/0xa00
    copy_ah_attr_from_uverbs.isra.2+0x860/0xa00
    ? uverbs_try_lock_object+0x68/0xc0
    ? modify_qp.isra.7+0xdc4/0x10e0
    modify_qp.isra.7+0xdc4/0x10e0
    ib_uverbs_modify_qp+0xfe/0x170
    ? ib_uverbs_query_qp+0x970/0x970
    ? __lock_acquire+0xa11/0x1da0
    ib_uverbs_write+0x55a/0xad0
    ? ib_uverbs_query_qp+0x970/0x970
    ? ib_uverbs_query_qp+0x970/0x970
    ? ib_uverbs_open+0x760/0x760
    ? futex_wake+0x147/0x410
    ? sched_clock_cpu+0x18/0x180
    ? check_prev_add+0x1680/0x1680
    ? do_futex+0x3b6/0xa30
    ? sched_clock_cpu+0x18/0x180
    __vfs_write+0xf7/0x5c0
    ? ib_uverbs_open+0x760/0x760
    ? kernel_read+0x110/0x110
    ? lock_acquire+0x370/0x370
    ? __fget+0x264/0x3b0
    vfs_write+0x18a/0x460
    SyS_write+0xc7/0x1a0
    ? SyS_read+0x1a0/0x1a0
    ? trace_hardirqs_on_thunk+0x1a/0x1c
    entry_SYSCALL_64_fastpath+0x18/0x85
    RIP: 0033:0x448e29
    RSP: 002b:00007f443fee0c58 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
    RAX: ffffffffffffffda RBX: 00007f443fee16bc RCX: 0000000000448e29
    RDX: 0000000000000078 RSI: 00000000209f8000 RDI: 0000000000000012
    RBP: 000000000070bea0 R08: 0000000000000000 R09: 0000000000000000
    R10: 0000000000000000 R11: 0000000000000246 R12: 00000000ffffffff
    R13: 0000000000008e98 R14: 00000000006ebf38 R15: 0000000000000000
    
    Allocated by task 1:
    kmem_cache_alloc_trace+0x16c/0x2f0
    mlx5_alloc_cmd_msg+0x12e/0x670
    cmd_exec+0x419/0x1810
    mlx5_cmd_exec+0x40/0x70
    mlx5_core_mad_ifc+0x187/0x220
    mlx5_MAD_IFC+0xd7/0x1b0
    mlx5_query_mad_ifc_gids+0x1f3/0x650
    mlx5_ib_query_gid+0xa4/0xc0
    ib_query_gid+0x152/0x1a0
    ib_query_port+0x21e/0x290
    mlx5_port_immutable+0x30f/0x490
    ib_register_device+0x5dd/0x1130
    mlx5_ib_add+0x3e7/0x700
    mlx5_add_device+0x124/0x510
    mlx5_register_interface+0x11f/0x1c0
    mlx5_ib_init+0x56/0x61
    do_one_initcall+0xa3/0x250
    kernel_init_freeable+0x309/0x3b8
    kernel_init+0x14/0x180
    ret_from_fork+0x24/0x30
    
    Freed by task 1:
    kfree+0xeb/0x2f0
    mlx5_free_cmd_msg+0xcd/0x140
    cmd_exec+0xeba/0x1810
    mlx5_cmd_exec+0x40/0x70
    mlx5_core_mad_ifc+0x187/0x220
    mlx5_MAD_IFC+0xd7/0x1b0
    mlx5_query_mad_ifc_gids+0x1f3/0x650
    mlx5_ib_query_gid+0xa4/0xc0
    ib_query_gid+0x152/0x1a0
    ib_query_port+0x21e/0x290
    mlx5_port_immutable+0x30f/0x490
    ib_register_device+0x5dd/0x1130
    mlx5_ib_add+0x3e7/0x700
    mlx5_add_device+0x124/0x510
    mlx5_register_interface+0x11f/0x1c0
    mlx5_ib_init+0x56/0x61
    do_one_initcall+0xa3/0x250
    kernel_init_freeable+0x309/0x3b8
    kernel_init+0x14/0x180
    ret_from_fork+0x24/0x30
    
    The buggy address belongs to the object at ffff88005fda1ab0
    which belongs to the cache kmalloc-32 of size 32
    The buggy address is located 24 bytes inside of
    32-byte region [ffff88005fda1ab0, ffff88005fda1ad0)
    The buggy address belongs to the page:
    page:00000000d5655c19 count:1 mapcount:0 mapping: (null)
    index:0xffff88005fda1fc0
    flags: 0x4000000000000100(slab)
    raw: 4000000000000100 0000000000000000 ffff88005fda1fc0 0000000180550008
    raw: ffffea00017f6780 0000000400000004 ffff88006c803980 0000000000000000
    page dumped because: kasan: bad access detected
    
    Memory state around the buggy address:
    ffff88005fda1980: fc fc fb fb fb fb fc fc fb fb fb fb fc fc fb fb
    ffff88005fda1a00: fb fb fc fc fb fb fb fb fc fc 00 00 00 00 fc fc
    ffff88005fda1a80: fb fb fb fb fc fc fb fb fb fb fc fc fb fb fb fb
    ffff88005fda1b00: fc fc 00 00 00 00 fc fc fb fb fb fb fc fc fb fb
    ffff88005fda1b80: fb fb fc fc fb fb fb fb fc fc fb fb fb fb fc fc
    ==================================================================@
    
    Cc: syzkaller <syzkaller@googlegroups.com>
    Cc: <stable@vger.kernel.org> # 4.11
    Fixes: 38321256 ("IB/core: Add support for idr types")
    Reported-by: default avatarNoa Osherovich <noaos@mellanox.com>
    Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
    Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
    6623e3e3
rdma_core.c 22.2 KB