• Hao Xu's avatar
    io_uring: fix potential req refcount underflow · 5b7aa38d
    Hao Xu authored
    For multishot mode, there may be cases like:
    
    iowq                                 original context
    io_poll_add
      _arm_poll()
      mask = vfs_poll() is not 0
      if mask
    (2)  io_poll_complete()
      compl_unlock
       (interruption happens
        tw queued to original
        context)
                                         io_poll_task_func()
                                         compl_lock
                                     (3) done = io_poll_complete() is true
                                         compl_unlock
                                         put req ref
    (1) if (poll->flags & EPOLLONESHOT)
          put req ref
    
    EPOLLONESHOT flag in (1) may be from (2) or (3), so there are multiple
    combinations that can cause ref underfow.
    Let's address it by:
    - check the return value in (2) as done
    - change (1) to if (done)
        in this way, we only do ref put in (1) if 'oneshot flag' is from
        (2)
    - do poll.done check in io_poll_task_func(), so that we won't put ref
      for the second time.
    Signed-off-by: default avatarHao Xu <haoxu@linux.alibaba.com>
    Link: https://lore.kernel.org/r/20210922101238.7177-4-haoxu@linux.alibaba.comSigned-off-by: default avatarJens Axboe <axboe@kernel.dk>
    5b7aa38d
io_uring.c 269 KB