All of lore.kernel.org
 help / color / mirror / Atom feed
From: Maxime Coquelin <maxime.coquelin@redhat.com>
To: mst@redhat.com, jasowang@redhat.com, xuanzhuo@linux.alibaba.com,
	paul@paul-moore.com, jmorris@namei.org, serge@hallyn.com,
	stephen.smalley.work@gmail.com, eparis@parisplace.org,
	xieyongji@bytedance.com,
	virtualization@lists.linux-foundation.org,
	linux-kernel@vger.kernel.org,
	linux-security-module@vger.kernel.org, selinux@vger.kernel.org,
	david.marchand@redhat.com, lulu@redhat.com,
	casey@schaufler-ca.com
Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
Subject: [PATCH v5 4/4] vduse: Add LSM hook to check Virtio device type
Date: Tue, 12 Dec 2023 14:17:12 +0100	[thread overview]
Message-ID: <20231212131712.1816324-5-maxime.coquelin@redhat.com> (raw)
In-Reply-To: <20231212131712.1816324-1-maxime.coquelin@redhat.com>

This patch introduces a LSM hook for devices creation,
destruction (ioctl()) and opening (open()) operations,
checking the application is allowed to perform these
operations for the Virtio device type.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 MAINTAINERS                         |  1 +
 drivers/vdpa/vdpa_user/vduse_dev.c  | 13 ++++++++++++
 include/linux/lsm_hook_defs.h       |  2 ++
 include/linux/security.h            |  6 ++++++
 include/linux/vduse.h               | 14 +++++++++++++
 security/security.c                 | 15 ++++++++++++++
 security/selinux/hooks.c            | 32 +++++++++++++++++++++++++++++
 security/selinux/include/classmap.h |  2 ++
 8 files changed, 85 insertions(+)
 create mode 100644 include/linux/vduse.h

diff --git a/MAINTAINERS b/MAINTAINERS
index a0fb0df07b43..4e83b14358d2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -23040,6 +23040,7 @@ F:	drivers/net/virtio_net.c
 F:	drivers/vdpa/
 F:	drivers/virtio/
 F:	include/linux/vdpa.h
+F:	include/linux/vduse.h
 F:	include/linux/virtio*.h
 F:	include/linux/vringh.h
 F:	include/uapi/linux/virtio_*.h
diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c
index fa62825be378..59ab7eb62e20 100644
--- a/drivers/vdpa/vdpa_user/vduse_dev.c
+++ b/drivers/vdpa/vdpa_user/vduse_dev.c
@@ -8,6 +8,7 @@
  *
  */
 
+#include "linux/security.h"
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/cdev.h>
@@ -30,6 +31,7 @@
 #include <uapi/linux/virtio_blk.h>
 #include <uapi/linux/virtio_ring.h>
 #include <linux/mod_devicetable.h>
+#include <linux/vduse.h>
 
 #include "iova_domain.h"
 
@@ -1442,6 +1444,10 @@ static int vduse_dev_open(struct inode *inode, struct file *file)
 	if (dev->connected)
 		goto unlock;
 
+	ret = -EPERM;
+	if (security_vduse_perm_check(VDUSE_PERM_OPEN, dev->device_id))
+		goto unlock;
+
 	ret = 0;
 	dev->connected = true;
 	file->private_data = dev;
@@ -1664,6 +1670,9 @@ static int vduse_destroy_dev(char *name)
 	if (!dev)
 		return -EINVAL;
 
+	if (security_vduse_perm_check(VDUSE_PERM_DESTROY, dev->device_id))
+		return -EPERM;
+
 	mutex_lock(&dev->lock);
 	if (dev->vdev || dev->connected) {
 		mutex_unlock(&dev->lock);
@@ -1828,6 +1837,10 @@ static int vduse_create_dev(struct vduse_dev_config *config,
 	int ret;
 	struct vduse_dev *dev;
 
+	ret = -EPERM;
+	if (security_vduse_perm_check(VDUSE_PERM_CREATE, config->device_id))
+		goto err;
+
 	ret = -EEXIST;
 	if (vduse_find_dev(config->name))
 		goto err;
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index ff217a5ce552..3930ab2ae974 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -419,3 +419,5 @@ LSM_HOOK(int, 0, uring_override_creds, const struct cred *new)
 LSM_HOOK(int, 0, uring_sqpoll, void)
 LSM_HOOK(int, 0, uring_cmd, struct io_uring_cmd *ioucmd)
 #endif /* CONFIG_IO_URING */
+
+LSM_HOOK(int, 0, vduse_perm_check, enum vduse_op_perm op_perm, u32 device_id)
diff --git a/include/linux/security.h b/include/linux/security.h
index 1d1df326c881..2a2054172394 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -32,6 +32,7 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/sockptr.h>
+#include <linux/vduse.h>
 
 struct linux_binprm;
 struct cred;
@@ -484,6 +485,7 @@ int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
 int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
 int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
 int security_locked_down(enum lockdown_reason what);
+int security_vduse_perm_check(enum vduse_op_perm op_perm, u32 device_id);
 #else /* CONFIG_SECURITY */
 
 static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data)
@@ -1395,6 +1397,10 @@ static inline int security_locked_down(enum lockdown_reason what)
 {
 	return 0;
 }
+static inline int security_vduse_perm_check(enum vduse_op_perm op_perm, u32 device_id)
+{
+	return 0;
+}
 #endif	/* CONFIG_SECURITY */
 
 #if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE)
diff --git a/include/linux/vduse.h b/include/linux/vduse.h
new file mode 100644
index 000000000000..7a20dcc43997
--- /dev/null
+++ b/include/linux/vduse.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_VDUSE_H
+#define _LINUX_VDUSE_H
+
+/*
+ * The permission required for a VDUSE device operation.
+ */
+enum vduse_op_perm {
+	VDUSE_PERM_CREATE,
+	VDUSE_PERM_DESTROY,
+	VDUSE_PERM_OPEN,
+};
+
+#endif /* _LINUX_VDUSE_H */
diff --git a/security/security.c b/security/security.c
index dcb3e7014f9b..150abf85f97d 100644
--- a/security/security.c
+++ b/security/security.c
@@ -5337,3 +5337,18 @@ int security_uring_cmd(struct io_uring_cmd *ioucmd)
 	return call_int_hook(uring_cmd, 0, ioucmd);
 }
 #endif /* CONFIG_IO_URING */
+
+/**
+ * security_vduse_perm_check() - Check if a VDUSE device type operation is allowed
+ * @op_perm: the operation type
+ * @device_id: the Virtio device ID
+ *
+ * Check whether the Virtio device creation is allowed
+ *
+ * Return: Returns 0 if permission is granted.
+ */
+int security_vduse_perm_check(enum vduse_op_perm op_perm, u32 device_id)
+{
+	return call_int_hook(vduse_perm_check, 0, op_perm, device_id);
+}
+EXPORT_SYMBOL(security_vduse_perm_check);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index feda711c6b7b..18845e4f682f 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -21,6 +21,8 @@
  *  Copyright (C) 2016 Mellanox Technologies
  */
 
+#include "av_permissions.h"
+#include "linux/vduse.h"
 #include <linux/init.h>
 #include <linux/kd.h>
 #include <linux/kernel.h>
@@ -92,6 +94,7 @@
 #include <linux/fsnotify.h>
 #include <linux/fanotify.h>
 #include <linux/io_uring.h>
+#include <uapi/linux/virtio_ids.h>
 
 #include "avc.h"
 #include "objsec.h"
@@ -6950,6 +6953,34 @@ static int selinux_uring_cmd(struct io_uring_cmd *ioucmd)
 }
 #endif /* CONFIG_IO_URING */
 
+static int selinux_vduse_perm_check(enum vduse_op_perm op_perm, u32 device_id)
+{
+	u32 requested_op, requested_type, sid = current_sid();
+	int ret;
+
+	if (op_perm == VDUSE_PERM_CREATE)
+		requested_op = VDUSE__CREATE;
+	else if (op_perm == VDUSE__DESTROY)
+		requested_op = VDUSE__DESTROY;
+	else if (op_perm == VDUSE_PERM_OPEN)
+		requested_op = VDUSE__OPEN;
+	else
+		return -EINVAL;
+
+	ret = avc_has_perm(sid, sid, SECCLASS_VDUSE, requested_op, NULL);
+	if (ret)
+		return ret;
+
+	if (device_id == VIRTIO_ID_NET)
+		requested_type = VDUSE__NET;
+	else if (device_id == VIRTIO_ID_BLOCK)
+		requested_type = VDUSE__BLOCK;
+	else
+		return -EINVAL;
+
+	return avc_has_perm(sid, sid, SECCLASS_VDUSE, requested_type, NULL);
+}
+
 /*
  * IMPORTANT NOTE: When adding new hooks, please be careful to keep this order:
  * 1. any hooks that don't belong to (2.) or (3.) below,
@@ -7243,6 +7274,7 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
 #ifdef CONFIG_PERF_EVENTS
 	LSM_HOOK_INIT(perf_event_alloc, selinux_perf_event_alloc),
 #endif
+	LSM_HOOK_INIT(vduse_perm_check, selinux_vduse_perm_check),
 };
 
 static __init int selinux_init(void)
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index a3c380775d41..b0a358cbac1c 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -256,6 +256,8 @@ const struct security_class_mapping secclass_map[] = {
 	  { "override_creds", "sqpoll", "cmd", NULL } },
 	{ "user_namespace",
 	  { "create", NULL } },
+	{ "vduse",
+	  { "create", "destroy", "open", "net", "block", NULL} },
 	{ NULL }
   };
 
-- 
2.43.0


  parent reply	other threads:[~2023-12-12 13:18 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-12 13:17 [PATCH v5 0/4] vduse: add support for networking devices Maxime Coquelin
2023-12-12 13:17 ` [PATCH v5 1/4] vduse: validate block features only with block devices Maxime Coquelin
2023-12-12 13:17 ` [PATCH v5 2/4] vduse: Temporarily disable control queue features Maxime Coquelin
2023-12-13  4:52   ` Jason Wang
2023-12-13 11:23     ` Maxime Coquelin
2023-12-18  2:50       ` Jason Wang
2023-12-18  9:21         ` Maxime Coquelin
2023-12-20  3:50           ` Jason Wang
2023-12-12 13:17 ` [PATCH v5 3/4] vduse: enable Virtio-net device type Maxime Coquelin
2023-12-12 13:17 ` Maxime Coquelin [this message]
2023-12-12 16:33   ` [PATCH v5 4/4] vduse: Add LSM hook to check Virtio " Casey Schaufler
2023-12-12 17:59     ` Michael S. Tsirkin
2023-12-12 22:55       ` Casey Schaufler
2023-12-16  4:18         ` Serge E. Hallyn
2023-12-18 17:21   ` Stephen Smalley
2023-12-18 17:33     ` Stephen Smalley
2024-01-04 10:14       ` Maxime Coquelin
2023-12-19 18:20     ` Paul Moore

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=20231212131712.1816324-5-maxime.coquelin@redhat.com \
    --to=maxime.coquelin@redhat.com \
    --cc=casey@schaufler-ca.com \
    --cc=david.marchand@redhat.com \
    --cc=eparis@parisplace.org \
    --cc=jasowang@redhat.com \
    --cc=jmorris@namei.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=lulu@redhat.com \
    --cc=mst@redhat.com \
    --cc=paul@paul-moore.com \
    --cc=selinux@vger.kernel.org \
    --cc=serge@hallyn.com \
    --cc=stephen.smalley.work@gmail.com \
    --cc=virtualization@lists.linux-foundation.org \
    --cc=xieyongji@bytedance.com \
    --cc=xuanzhuo@linux.alibaba.com \
    /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.