diff options
-rw-r--r-- | fs/io-wq.c | 10 | ||||
-rw-r--r-- | fs/io_uring.c | 24 | ||||
-rw-r--r-- | fs/proc/base.c | 4 | ||||
-rw-r--r-- | include/linux/io_uring.h | 4 |
4 files changed, 41 insertions, 1 deletions
diff --git a/fs/io-wq.c b/fs/io-wq.c index 0c852b75384d..7cb3b4cb9b11 100644 --- a/fs/io-wq.c +++ b/fs/io-wq.c @@ -18,6 +18,7 @@ #include <linux/fs_struct.h> #include <linux/task_work.h> #include <linux/blk-cgroup.h> +#include <linux/audit.h> #include "io-wq.h" @@ -484,6 +485,10 @@ static void io_impersonate_work(struct io_worker *worker, io_wq_switch_creds(worker, work); current->signal->rlim[RLIMIT_FSIZE].rlim_cur = work->identity->fsize; io_wq_switch_blkcg(worker, work); +#ifdef CONFIG_AUDIT + current->loginuid = work->identity->loginuid; + current->sessionid = work->identity->sessionid; +#endif } static void io_assign_current_work(struct io_worker *worker, @@ -496,6 +501,11 @@ static void io_assign_current_work(struct io_worker *worker, cond_resched(); } +#ifdef CONFIG_AUDIT + current->loginuid = KUIDT_INIT(AUDIT_UID_UNSET); + current->sessionid = AUDIT_SID_UNSET; +#endif + spin_lock_irq(&worker->lock); worker->cur_work = work; spin_unlock_irq(&worker->lock); diff --git a/fs/io_uring.c b/fs/io_uring.c index 58c445b95085..b9ffe98f18bc 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -81,6 +81,7 @@ #include <linux/pagemap.h> #include <linux/io_uring.h> #include <linux/blk-cgroup.h> +#include <linux/audit.h> #define CREATE_TRACE_POINTS #include <trace/events/io_uring.h> @@ -327,6 +328,11 @@ struct io_ring_ctx { const struct cred *creds; +#ifdef CONFIG_AUDIT + kuid_t loginuid; + unsigned int sessionid; +#endif + struct completion ref_comp; struct completion sq_thread_comp; @@ -1057,6 +1063,10 @@ static void io_init_identity(struct io_identity *id) id->nsproxy = current->nsproxy; id->fs = current->fs; id->fsize = rlimit(RLIMIT_FSIZE); +#ifdef CONFIG_AUDIT + id->loginuid = current->loginuid; + id->sessionid = current->sessionid; +#endif refcount_set(&id->count, 1); } @@ -1316,6 +1326,11 @@ static bool io_grab_identity(struct io_kiocb *req) get_cred(id->creds); req->work.flags |= IO_WQ_WORK_CREDS; } +#ifdef CONFIG_AUDIT + if (!uid_eq(current->loginuid, id->loginuid) || + current->sessionid != id->sessionid) + return false; +#endif if (!(req->work.flags & IO_WQ_WORK_FS) && (def->work_flags & IO_WQ_WORK_FS)) { if (current->fs != id->fs) @@ -6755,6 +6770,10 @@ static int io_sq_thread(void *data) old_cred = override_creds(ctx->creds); } io_sq_thread_associate_blkcg(ctx, &cur_css); +#ifdef CONFIG_AUDIT + current->loginuid = ctx->loginuid; + current->sessionid = ctx->sessionid; +#endif ret |= __io_sq_thread(ctx, start_jiffies, cap_entries); @@ -9203,7 +9222,10 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p, ctx->compat = in_compat_syscall(); ctx->user = user; ctx->creds = get_current_cred(); - +#ifdef CONFIG_AUDIT + ctx->loginuid = current->loginuid; + ctx->sessionid = current->sessionid; +#endif ctx->sqo_task = get_task_struct(current); /* diff --git a/fs/proc/base.c b/fs/proc/base.c index aa69c35d904c..0f707003dda5 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1268,6 +1268,10 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf, kuid_t kloginuid; int rv; + /* Don't let kthreads write their own loginuid */ + if (current->flags & PF_KTHREAD) + return -EPERM; + rcu_read_lock(); if (current != pid_task(proc_pid(inode), PIDTYPE_PID)) { rcu_read_unlock(); diff --git a/include/linux/io_uring.h b/include/linux/io_uring.h index 28939820b6b0..868364cea3b7 100644 --- a/include/linux/io_uring.h +++ b/include/linux/io_uring.h @@ -15,6 +15,10 @@ struct io_identity { struct nsproxy *nsproxy; struct fs_struct *fs; unsigned long fsize; +#ifdef CONFIG_AUDIT + kuid_t loginuid; + unsigned int sessionid; +#endif refcount_t count; }; |