Commit cdab10bf authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull selinux updates from Paul Moore:

 - Add LSM/SELinux/Smack controls and auditing for io-uring.

   As usual, the individual commit descriptions have more detail, but we
   were basically missing two things which we're adding here:

      + establishment of a proper audit context so that auditing of
        io-uring ops works similarly to how it does for syscalls (with
        some io-uring additions because io-uring ops are *not* syscalls)

      + additional LSM hooks to enable access control points for some of
        the more unusual io-uring features, e.g. credential overrides.

   The additional audit callouts and LSM hooks were done in conjunction
   with the io-uring folks, based on conversations and RFC patches
   earlier in the year.

 - Fixup the binder credential handling so that the proper credentials
   are used in the LSM hooks; the commit description and the code
   comment which is removed in these patches are helpful to understand
   the background and why this is the proper fix.

 - Enable SELinux genfscon policy support for securityfs, allowing
   improved SELinux filesystem labeling for other subsystems which make
   use of securityfs, e.g. IMA.

* tag 'selinux-pr-20211101' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
  security: Return xattr name from security_dentry_init_security()
  selinux: fix a sock regression in selinux_ip_postroute_compat()
  binder: use cred instead of task for getsecid
  binder: use cred instead of task for selinux checks
  binder: use euid from cred instead of using task
  LSM: Avoid warnings about potentially unused hook variables
  selinux: fix all of the W=1 build warnings
  selinux: make better use of the nf_hook_state passed to the NF hooks
  selinux: fix race condition when computing ocontext SIDs
  selinux: remove unneeded ipv6 hook wrappers
  selinux: remove the SELinux lockdown implementation
  selinux: enable genfscon labeling for securityfs
  Smack: Brutalist io_uring support
  selinux: add support for the io_uring access controls
  lsm,io_uring: add LSM hooks to io_uring
  io_uring: convert io_uring to the secure anon inode interface
  fs: add anon_inode_getfile_secure() similar to anon_inode_getfd_secure()
  audit: add filtering for io_uring records
  audit,io_uring,io-wq: add some basic audit support to io_uring
  audit: prepare audit_context for use in calling contexts beyond syscalls
parents 6fedc280 15bf3239
Loading
Loading
Loading
Loading
+10 −17
Original line number Diff line number Diff line
@@ -2056,7 +2056,7 @@ static int binder_translate_binder(struct flat_binder_object *fp,
		ret = -EINVAL;
		goto done;
	}
	if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) {
	if (security_binder_transfer_binder(proc->cred, target_proc->cred)) {
		ret = -EPERM;
		goto done;
	}
@@ -2102,7 +2102,7 @@ static int binder_translate_handle(struct flat_binder_object *fp,
				  proc->pid, thread->pid, fp->handle);
		return -EINVAL;
	}
	if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) {
	if (security_binder_transfer_binder(proc->cred, target_proc->cred)) {
		ret = -EPERM;
		goto done;
	}
@@ -2190,7 +2190,7 @@ static int binder_translate_fd(u32 fd, binder_size_t fd_offset,
		ret = -EBADF;
		goto err_fget;
	}
	ret = security_binder_transfer_file(proc->tsk, target_proc->tsk, file);
	ret = security_binder_transfer_file(proc->cred, target_proc->cred, file);
	if (ret < 0) {
		ret = -EPERM;
		goto err_security;
@@ -2595,8 +2595,8 @@ static void binder_transaction(struct binder_proc *proc,
			return_error_line = __LINE__;
			goto err_invalid_target_handle;
		}
		if (security_binder_transaction(proc->tsk,
						target_proc->tsk) < 0) {
		if (security_binder_transaction(proc->cred,
						target_proc->cred) < 0) {
			return_error = BR_FAILED_REPLY;
			return_error_param = -EPERM;
			return_error_line = __LINE__;
@@ -2711,7 +2711,7 @@ static void binder_transaction(struct binder_proc *proc,
		t->from = thread;
	else
		t->from = NULL;
	t->sender_euid = task_euid(proc->tsk);
	t->sender_euid = proc->cred->euid;
	t->to_proc = target_proc;
	t->to_thread = target_thread;
	t->code = tr->code;
@@ -2722,16 +2722,7 @@ static void binder_transaction(struct binder_proc *proc,
		u32 secid;
		size_t added_size;

		/*
		 * Arguably this should be the task's subjective LSM secid but
		 * we can't reliably access the subjective creds of a task
		 * other than our own so we must use the objective creds, which
		 * are safe to access.  The downside is that if a task is
		 * temporarily overriding it's creds it will not be reflected
		 * here; however, it isn't clear that binder would handle that
		 * case well anyway.
		 */
		security_task_getsecid_obj(proc->tsk, &secid);
		security_cred_getsecid(proc->cred, &secid);
		ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
		if (ret) {
			return_error = BR_FAILED_REPLY;
@@ -4353,6 +4344,7 @@ static void binder_free_proc(struct binder_proc *proc)
	}
	binder_alloc_deferred_release(&proc->alloc);
	put_task_struct(proc->tsk);
	put_cred(proc->cred);
	binder_stats_deleted(BINDER_STAT_PROC);
	kfree(proc);
}
@@ -4564,7 +4556,7 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp,
		ret = -EBUSY;
		goto out;
	}
	ret = security_binder_set_context_mgr(proc->tsk);
	ret = security_binder_set_context_mgr(proc->cred);
	if (ret < 0)
		goto out;
	if (uid_valid(context->binder_context_mgr_uid)) {
@@ -5055,6 +5047,7 @@ static int binder_open(struct inode *nodp, struct file *filp)
	spin_lock_init(&proc->outer_lock);
	get_task_struct(current->group_leader);
	proc->tsk = current->group_leader;
	proc->cred = get_cred(filp->f_cred);
	INIT_LIST_HEAD(&proc->todo);
	init_waitqueue_head(&proc->freeze_wait);
	proc->default_priority = task_nice(current);
+4 −0
Original line number Diff line number Diff line
@@ -364,6 +364,9 @@ struct binder_ref {
 *                        (invariant after initialized)
 * @tsk                   task_struct for group_leader of process
 *                        (invariant after initialized)
 * @cred                  struct cred associated with the `struct file`
 *                        in binder_open()
 *                        (invariant after initialized)
 * @deferred_work_node:   element for binder_deferred_list
 *                        (protected by binder_deferred_lock)
 * @deferred_work:        bitmap of deferred work to perform
@@ -426,6 +429,7 @@ struct binder_proc {
	struct list_head waiting_threads;
	int pid;
	struct task_struct *tsk;
	const struct cred *cred;
	struct hlist_node deferred_work_node;
	int deferred_work;
	int outstanding_txns;
+29 −0
Original line number Diff line number Diff line
@@ -148,6 +148,35 @@ struct file *anon_inode_getfile(const char *name,
}
EXPORT_SYMBOL_GPL(anon_inode_getfile);

/**
 * anon_inode_getfile_secure - Like anon_inode_getfile(), but creates a new
 *                             !S_PRIVATE anon inode rather than reuse the
 *                             singleton anon inode and calls the
 *                             inode_init_security_anon() LSM hook.  This
 *                             allows for both the inode to have its own
 *                             security context and for the LSM to enforce
 *                             policy on the inode's creation.
 *
 * @name:    [in]    name of the "class" of the new file
 * @fops:    [in]    file operations for the new file
 * @priv:    [in]    private data for the new file (will be file's private_data)
 * @flags:   [in]    flags
 * @context_inode:
 *           [in]    the logical relationship with the new inode (optional)
 *
 * The LSM may use @context_inode in inode_init_security_anon(), but a
 * reference to it is not held.  Returns the newly created file* or an error
 * pointer.  See the anon_inode_getfile() documentation for more information.
 */
struct file *anon_inode_getfile_secure(const char *name,
				       const struct file_operations *fops,
				       void *priv, int flags,
				       const struct inode *context_inode)
{
	return __anon_inode_getfile(name, fops, priv, flags,
				    context_inode, true);
}

static int __anon_inode_getfd(const char *name,
			      const struct file_operations *fops,
			      void *priv, int flags,
+1 −2
Original line number Diff line number Diff line
@@ -1311,7 +1311,7 @@ int ceph_security_init_secctx(struct dentry *dentry, umode_t mode,
	int err;

	err = security_dentry_init_security(dentry, mode, &dentry->d_name,
					    &as_ctx->sec_ctx,
					    &name, &as_ctx->sec_ctx,
					    &as_ctx->sec_ctxlen);
	if (err < 0) {
		WARN_ON_ONCE(err != -EOPNOTSUPP);
@@ -1335,7 +1335,6 @@ int ceph_security_init_secctx(struct dentry *dentry, umode_t mode,
	 * It only supports single security module and only selinux has
	 * dentry_init_security hook.
	 */
	name = XATTR_NAME_SELINUX;
	name_len = strlen(name);
	err = ceph_pagelist_reserve(pagelist,
				    4 * 2 + name_len + as_ctx->sec_ctxlen);
+4 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <linux/rculist_nulls.h>
#include <linux/cpu.h>
#include <linux/tracehook.h>
#include <linux/audit.h>
#include <uapi/linux/io_uring.h>

#include "io-wq.h"
@@ -593,6 +594,8 @@ static int io_wqe_worker(void *data)
	snprintf(buf, sizeof(buf), "iou-wrk-%d", wq->task->pid);
	set_task_comm(current, buf);

	audit_alloc_kernel(current);

	while (!test_bit(IO_WQ_BIT_EXIT, &wq->state)) {
		long ret;

@@ -631,6 +634,7 @@ static int io_wqe_worker(void *data)
		io_worker_handle_work(worker);
	}

	audit_free(current);
	io_worker_exit(worker);
	return 0;
}
Loading