• Al Viro's avatar
    aio: fix the "too late munmap()" race · c7b28555
    Al Viro authored
    Current code has put_ioctx() called asynchronously from aio_fput_routine();
    that's done *after* we have killed the request that used to pin ioctx,
    so there's nothing to stop io_destroy() waiting in wait_for_all_aios()
    from progressing.  As the result, we can end up with async call of
    put_ioctx() being the last one and possibly happening during exit_mmap()
    or elf_core_dump(), neither of which expects stray munmap() being done
    to them...
    We do need to prevent _freeing_ ioctx until aio_fput_routine() is done
    with that, but that's all we care about - neither io_destroy() nor
    exit_aio() will progress past wait_for_all_aios() until aio_fput_routine()
    does really_put_req(), so the ioctx teardown won't be done until then
    and we don't care about the contents of ioctx past that point.
    Since actual freeing of these suckers is RCU-delayed, we don't need to
    bump ioctx refcount when request goes into list for async removal.
    All we need is rcu_read_lock held just over the ->ctx_lock-protected
    area in aio_fput_routine().
    Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    Reviewed-by: default avatarJeff Moyer <jmoyer@redhat.com>
    Acked-by: default avatarBenjamin LaHaise <bcrl@kvack.org>
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
aio.c 47.9 KB