提交 0213acd0 编写于 作者: L Luo Meng 提交者: Yongqiang Liu

io_uring: fix UAF in get_files_struct()

hulk inclusion
category: bugfix
bugzilla: 186337, https://gitee.com/openeuler/kernel/issues/I4XA09
CVE: NA

--------------------------------

If two tasks are running concurrently as follows:
     task1                                        |       task2
io_uring_enter                                    |  io_wqe_worker
  io_submit_sqes                                  |
    io_submit_sqe                                 |
      io_queue_sqe                                |
        io_req_defer                              |
          io_req_defer_prep                       |
            io_prep_work_files                    |
              io_grab_files                       |
                req->work.files = current->files  |
          io_queue_async_work                     |
            __io_queue_async_work                 |
              io_wq_enqueue                       |
                io_wqe_insert_work                |
                                                  |  io_worker_handle_work
                                                  |    io_impersonate_work
                                                  |      current->files = work->files

And then, one of the concurrency UAF can be shown as below:
          free                                          use (task3 ls -l /proc/io_wqe_worker id/fd )
do_exit // tsk = current = work->files            |
  exit_files				          |
    put_files_struct			          |
      tsk->files // tsk->files = work->files      |
	                                          |  iterate_dir
					          |    proc_readfd_common
                                                  |      p = get_proc_task(file_inode(file))
                                                  |       get_files_struct
                                                  |         files = task->files
                                                  |         atomic_inc(&files->count)

The root cause of UAF bugs is when get req->work.files doesn't add refcount.
The mainline commit 0f212204(io_uring: don't rely on weak ->files references)
fixes this problem, based on this commit to resolved the problme.
Signed-off-by: NLuo Meng <luomeng12@huawei.com>
Reviewed-by: NZhang Yi <yi.zhang@huawei.com>
Signed-off-by: NYongqiang Liu <liuyongqiang13@huawei.com>
上级 76f51e9e
...@@ -5613,6 +5613,7 @@ static void __io_clean_op(struct io_kiocb *req) ...@@ -5613,6 +5613,7 @@ static void __io_clean_op(struct io_kiocb *req)
wake_up(&ctx->inflight_wait); wake_up(&ctx->inflight_wait);
spin_unlock_irqrestore(&ctx->inflight_lock, flags); spin_unlock_irqrestore(&ctx->inflight_lock, flags);
req->flags &= ~REQ_F_INFLIGHT; req->flags &= ~REQ_F_INFLIGHT;
put_files_struct(req->work.files);
} }
} }
...@@ -5990,7 +5991,7 @@ static int io_grab_files(struct io_kiocb *req) ...@@ -5990,7 +5991,7 @@ static int io_grab_files(struct io_kiocb *req)
if (fcheck(ctx->ring_fd) == ctx->ring_file) { if (fcheck(ctx->ring_fd) == ctx->ring_file) {
list_add(&req->inflight_entry, &ctx->inflight_list); list_add(&req->inflight_entry, &ctx->inflight_list);
req->flags |= REQ_F_INFLIGHT; req->flags |= REQ_F_INFLIGHT;
req->work.files = current->files; req->work.files = get_files_struct(current);
ret = 0; ret = 0;
} }
spin_unlock_irq(&ctx->inflight_lock); spin_unlock_irq(&ctx->inflight_lock);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册