]> git.hungrycats.org Git - linux/commitdiff
io_uring: reference ->nsproxy for file table commands
authorJens Axboe <axboe@kernel.dk>
Sat, 19 Sep 2020 02:13:06 +0000 (20:13 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 1 Nov 2020 11:45:35 +0000 (12:45 +0100)
commit 9b8284921513fc1ea57d87777283a59b05862f03 upstream.

If we don't get and assign the namespace for the async work, then certain
paths just don't work properly (like /dev/stdin, /proc/mounts, etc).
Anything that references the current namespace of the given task should
be assigned for async work on behalf of that task.

Cc: stable@vger.kernel.org # v5.5+
Reported-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/io-wq.c
fs/io-wq.h
fs/io_uring.c

index cb9e5a444fba7a3cce76ff1b4f2780395fde8d52..5257bb943d766776b50e81cb4706f1dd2492a160 100644 (file)
@@ -60,6 +60,7 @@ struct io_worker {
        const struct cred *cur_creds;
        const struct cred *saved_creds;
        struct files_struct *restore_files;
+       struct nsproxy *restore_nsproxy;
        struct fs_struct *restore_fs;
 };
 
@@ -153,6 +154,7 @@ static bool __io_worker_unuse(struct io_wqe *wqe, struct io_worker *worker)
 
                task_lock(current);
                current->files = worker->restore_files;
+               current->nsproxy = worker->restore_nsproxy;
                task_unlock(current);
        }
 
@@ -318,6 +320,7 @@ static void io_worker_start(struct io_wqe *wqe, struct io_worker *worker)
 
        worker->flags |= (IO_WORKER_F_UP | IO_WORKER_F_RUNNING);
        worker->restore_files = current->files;
+       worker->restore_nsproxy = current->nsproxy;
        worker->restore_fs = current->fs;
        io_wqe_inc_running(wqe, worker);
 }
@@ -454,6 +457,7 @@ static void io_impersonate_work(struct io_worker *worker,
        if (work->files && current->files != work->files) {
                task_lock(current);
                current->files = work->files;
+               current->nsproxy = work->nsproxy;
                task_unlock(current);
        }
        if (work->fs && current->fs != work->fs)
index 071f1a9978002675c48294ad518a725c52c0bd05..9be6def2b5a6f3225345b7917c25b50a98ee00e1 100644 (file)
@@ -88,6 +88,7 @@ struct io_wq_work {
        struct files_struct *files;
        struct mm_struct *mm;
        const struct cred *creds;
+       struct nsproxy *nsproxy;
        struct fs_struct *fs;
        unsigned flags;
 };
index ce6b241edd10d0b557b3ffbe77b0efa1e0b718fa..7e616aeebe5c1591d752f64e6d190b713334b8d7 100644 (file)
@@ -1456,6 +1456,7 @@ static void io_req_drop_files(struct io_kiocb *req)
        spin_unlock_irqrestore(&ctx->inflight_lock, flags);
        req->flags &= ~REQ_F_INFLIGHT;
        put_files_struct(req->work.files);
+       put_nsproxy(req->work.nsproxy);
        req->work.files = NULL;
 }
 
@@ -5685,6 +5686,8 @@ static int io_grab_files(struct io_kiocb *req)
                return 0;
 
        req->work.files = get_files_struct(current);
+       get_nsproxy(current->nsproxy);
+       req->work.nsproxy = current->nsproxy;
        req->flags |= REQ_F_INFLIGHT;
 
        spin_lock_irq(&ctx->inflight_lock);