Commit 4ea33a97 authored by Jens Axboe's avatar Jens Axboe
Browse files

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: default avatarJens Axboe <axboe@kernel.dk>
parent d8a6df10
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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);
+23 −1
Original line number Diff line number Diff line
@@ -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);

	/*
+4 −0
Original line number Diff line number Diff line
@@ -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();
+4 −0
Original line number Diff line number Diff line
@@ -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;
};