• Jens Axboe's avatar
    io_uring: store SCM state in io_fixed_file->file_ptr · 5e45690a
    Jens Axboe authored
    A previous commit removed SCM accounting for non-unix sockets, as those
    are the only ones that can cause a fixed file reference. While that is
    true, it also means we're now dereferencing the file as part of the
    workqueue driven __io_sqe_files_unregister() after the process has
    exited. This isn't safe for SCM files, as unix gc may have already
    reaped them when the process exited. KASAN complains about this:
    
    [   12.307040] Freed by task 0:
    [   12.307592]  kasan_save_stack+0x28/0x4c
    [   12.308318]  kasan_set_track+0x28/0x38
    [   12.309049]  kasan_set_free_info+0x24/0x44
    [   12.309890]  ____kasan_slab_free+0x108/0x11c
    [   12.310739]  __kasan_slab_free+0x14/0x1c
    [   12.311482]  slab_free_freelist_hook+0xd4/0x164
    [   12.312382]  kmem_cache_free+0x100/0x1dc
    [   12.313178]  file_free_rcu+0x58/0x74
    [   12.313864]  rcu_core+0x59c/0x7c0
    [   12.314675]  rcu_core_si+0xc/0x14
    [   12.315496]  _stext+0x30c/0x414
    [   12.316287]
    [   12.316687] Last potentially related work creation:
    [   12.317885]  kasan_save_stack+0x28/0x4c
    [   12.318845]  __kasan_record_aux_stack+0x9c/0xb0
    [   12.319976]  kasan_record_aux_stack_noalloc+0x10/0x18
    [   12.321268]  call_rcu+0x50/0x35c
    [   12.322082]  __fput+0x2fc/0x324
    [   12.322873]  ____fput+0xc/0x14
    [   12.323644]  task_work_run+0xac/0x10c
    [   12.324561]  do_notify_resume+0x37c/0xe74
    [   12.325420]  el0_svc+0x5c/0x68
    [   12.326050]  el0t_64_sync_handler+0xb0/0x12c
    [   12.326918]  el0t_64_sync+0x164/0x168
    [   12.327657]
    [   12.327976] Second to last potentially related work creation:
    [   12.329134]  kasan_save_stack+0x28/0x4c
    [   12.329864]  __kasan_record_aux_stack+0x9c/0xb0
    [   12.330735]  kasan_record_aux_stack+0x10/0x18
    [   12.331576]  task_work_add+0x34/0xf0
    [   12.332284]  fput_many+0x11c/0x134
    [   12.332960]  fput+0x10/0x94
    [   12.333524]  __scm_destroy+0x80/0x84
    [   12.334213]  unix_destruct_scm+0xc4/0x144
    [   12.334948]  skb_release_head_state+0x5c/0x6c
    [   12.335696]  skb_release_all+0x14/0x38
    [   12.336339]  __kfree_skb+0x14/0x28
    [   12.336928]  kfree_skb_reason+0xf4/0x108
    [   12.337604]  unix_gc+0x1e8/0x42c
    [   12.338154]  unix_release_sock+0x25c/0x2dc
    [   12.338895]  unix_release+0x58/0x78
    [   12.339531]  __sock_release+0x68/0xec
    [   12.340170]  sock_close+0x14/0x20
    [   12.340729]  __fput+0x18c/0x324
    [   12.341254]  ____fput+0xc/0x14
    [   12.341763]  task_work_run+0xac/0x10c
    [   12.342367]  do_notify_resume+0x37c/0xe74
    [   12.343086]  el0_svc+0x5c/0x68
    [   12.343510]  el0t_64_sync_handler+0xb0/0x12c
    [   12.344086]  el0t_64_sync+0x164/0x168
    
    We have an extra bit we can use in file_ptr on 64-bit, use that to store
    whether this file is SCM'ed or not, avoiding the need to look at the
    file contents itself. This does mean that 32-bit will be stuck with SCM
    for all registered files, just like 64-bit did before the referenced
    commit.
    
    Fixes: 1f59bc0f ("io_uring: don't scm-account for non af_unix sockets")
    Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
    5e45690a
io_uring.c 294 KB