All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hengqi Chen <hengqi.chen@gmail.com>
To: linux-kernel@vger.kernel.org, bpf@vger.kernel.org
Cc: keescook@chromium.org, luto@amacapital.net, wad@chromium.org,
	alexyonghe@tencent.com, hengqi.chen@gmail.com
Subject: [RFC PATCH 2/2] seccomp: Introduce SECCOMP_ATTACH_FILTER operation
Date: Tue,  3 Oct 2023 08:38:36 +0000	[thread overview]
Message-ID: <20231003083836.100706-3-hengqi.chen@gmail.com> (raw)
In-Reply-To: <20231003083836.100706-1-hengqi.chen@gmail.com>

The SECCOMP_ATTACH_FILTER operation is used to attach
a loaded filter to the current process. The loaded filter
is represented by a fd which is either returned by the
SECCOMP_LOAD_FILTER operation or obtained from bpffs using
bpf syscall.

Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com>
---
 include/uapi/linux/seccomp.h |  1 +
 kernel/seccomp.c             | 74 ++++++++++++++++++++++++++++++++++--
 2 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/include/uapi/linux/seccomp.h b/include/uapi/linux/seccomp.h
index ee2c83697810..fbe30262fdfc 100644
--- a/include/uapi/linux/seccomp.h
+++ b/include/uapi/linux/seccomp.h
@@ -17,6 +17,7 @@
 #define SECCOMP_GET_ACTION_AVAIL	2
 #define SECCOMP_GET_NOTIF_SIZES		3
 #define SECCOMP_LOAD_FILTER		4
+#define SECCOMP_ATTACH_FILTER		5
 
 /* Valid flags for SECCOMP_SET_MODE_FILTER */
 #define SECCOMP_FILTER_FLAG_TSYNC		(1UL << 0)
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 7aff22f56a91..adfafee4c3da 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -862,7 +862,7 @@ static void seccomp_cache_prepare(struct seccomp_filter *sfilter)
 #endif /* SECCOMP_ARCH_NATIVE */
 
 /**
- * seccomp_attach_filter: validate and attach filter
+ * seccomp_do_attach_filter: validate and attach filter
  * @flags:  flags to change filter behavior
  * @filter: seccomp filter to add to the current process
  *
@@ -873,8 +873,8 @@ static void seccomp_cache_prepare(struct seccomp_filter *sfilter)
  *     seccomp mode or did not have an ancestral seccomp filter
  *   - in NEW_LISTENER mode: the fd of the new listener
  */
-static long seccomp_attach_filter(unsigned int flags,
-				  struct seccomp_filter *filter)
+static long seccomp_do_attach_filter(unsigned int flags,
+				     struct seccomp_filter *filter)
 {
 	unsigned long total_insns;
 	struct seccomp_filter *walker;
@@ -1969,7 +1969,7 @@ static long seccomp_set_mode_filter(unsigned int flags,
 		goto out;
 	}
 
-	ret = seccomp_attach_filter(flags, prepared);
+	ret = seccomp_do_attach_filter(flags, prepared);
 	if (ret)
 		goto out;
 	/* Do not free the successfully attached filter. */
@@ -2050,6 +2050,62 @@ static long seccomp_load_filter(const char __user *filter)
 out:
 	return ret;
 }
+
+static long seccomp_attach_filter(const char __user *ufd)
+{
+	const unsigned long seccomp_mode = SECCOMP_MODE_FILTER;
+	struct seccomp_filter *sfilter;
+	struct bpf_prog *prog;
+	struct file *filp;
+	int flags = 0;
+	int fd, ret;
+
+	if (copy_from_user(&fd, ufd, sizeof(fd)))
+		return -EFAULT;
+
+	filp = fget(fd);
+	if (!filp)
+		return -EBADF;
+
+	if (filp->f_op != &bpf_prog_fops) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	prog = filp->private_data;
+
+	sfilter = kzalloc(sizeof(*sfilter), GFP_KERNEL | __GFP_NOWARN);
+	if (!sfilter) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	sfilter->prog = prog;
+	refcount_set(&sfilter->refs, 1);
+	refcount_set(&sfilter->users, 1);
+	mutex_init(&sfilter->notify_lock);
+	init_waitqueue_head(&sfilter->wqh);
+
+	spin_lock_irq(&current->sighand->siglock);
+
+	ret = -EINVAL;
+	if (!seccomp_may_assign_mode(seccomp_mode))
+		goto out_unlock;
+
+	ret = seccomp_do_attach_filter(flags, sfilter);
+	if (ret)
+		goto out_unlock;
+
+	sfilter = NULL;
+	seccomp_assign_mode(current, seccomp_mode, flags);
+
+out_unlock:
+	spin_unlock_irq(&current->sighand->siglock);
+	seccomp_filter_free(sfilter);
+out:
+	fput(filp);
+	return ret;
+}
 #else
 static inline long seccomp_set_mode_filter(unsigned int flags,
 					   const char __user *filter)
@@ -2061,6 +2117,11 @@ static inline long seccomp_load_filter(const char __user *filter)
 {
 	return -EINVAL;
 }
+
+static inline long seccomp_attach_filter(const char __user *ufd)
+{
+	return -EINVAL;
+}
 #endif
 
 static long seccomp_get_action_avail(const char __user *uaction)
@@ -2127,6 +2188,11 @@ static long do_seccomp(unsigned int op, unsigned int flags,
 			return -EINVAL;
 
 		return seccomp_load_filter(uargs);
+	case SECCOMP_ATTACH_FILTER:
+		if (flags != 0)
+			return -EINVAL;
+
+		return seccomp_attach_filter(uargs);
 	default:
 		return -EINVAL;
 	}
-- 
2.34.1


  parent reply	other threads:[~2023-10-03  8:44 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-03  8:38 [RFC PATCH 0/2] seccomp: Split set filter into two steps Hengqi Chen
2023-10-03  8:38 ` [RFC PATCH 1/2] seccomp: Introduce SECCOMP_LOAD_FILTER operation Hengqi Chen
2023-10-03 16:17   ` kernel test robot
2023-10-03 16:28   ` kernel test robot
2023-10-03  8:38 ` Hengqi Chen [this message]
2023-10-03 20:28   ` [RFC PATCH 2/2] seccomp: Introduce SECCOMP_ATTACH_FILTER operation kernel test robot
2023-10-03 18:01 ` [RFC PATCH 0/2] seccomp: Split set filter into two steps Kees Cook
2023-10-06  7:58   ` Hengqi Chen
2023-10-04 14:03 ` Rodrigo Campos
2023-10-06  8:12   ` Hengqi Chen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231003083836.100706-3-hengqi.chen@gmail.com \
    --to=hengqi.chen@gmail.com \
    --cc=alexyonghe@tencent.com \
    --cc=bpf@vger.kernel.org \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=wad@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.