io-wq: inherit audit loginuid and sessionid
Make sure the async io-wq workers inherit the loginuid and sessionid from the original task, and restore them to unset once we're done with the async work item. While at it, disable the ability for kernel threads to write to their own loginuid. Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
d8a6df10aa
commit
4ea33a976b
10
fs/io-wq.c
10
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);
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user