diff mbox series

[RESEND,RFC,v2,01/14] device_cgroup: Implement devcgroup hooks as lsm security hooks

Message ID 20231025094224.72858-2-michael.weiss@aisec.fraunhofer.de (mailing list archive)
State RFC
Headers show
Series device_cgroup: guard mknod for non-initial user namespace | expand

Checks

Context Check Description
bpf/vmtest-bpf-next-PR pending PR summary
bpf/vmtest-bpf-next-VM_Test-0 pending Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-5 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-1 success Logs for build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-4 success Logs for build for x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-3 success Logs for build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-7 pending Logs for test_maps on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-8 success Logs for test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-9 success Logs for test_maps on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-2 success Logs for build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-19 success Logs for test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-20 success Logs for test_progs_no_alu32_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-24 success Logs for test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-25 success Logs for test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-26 success Logs for test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-27 success Logs for test_verifier on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-28 success Logs for veristat
bpf/vmtest-bpf-next-VM_Test-10 success Logs for test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-6 success Logs for test_maps on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-12 success Logs for test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-13 success Logs for test_progs on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-14 success Logs for test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-16 success Logs for test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-17 success Logs for test_progs_no_alu32 on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-18 success Logs for test_progs_no_alu32_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-21 success Logs for test_progs_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-22 success Logs for test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-23 success Logs for test_progs_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-15 fail Logs for test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-11 success Logs for test_progs on s390x with gcc
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Guessed tree name to be net-next, async
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 1365 this patch: 1365
netdev/cc_maintainers warning 4 maintainers not CCed: tsi@tuyoix.net gregkh@linuxfoundation.org linux-security-module@vger.kernel.org jmorris@namei.org
netdev/build_clang success Errors and warnings before: 1389 this patch: 1389
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 1390 this patch: 1390
netdev/checkpatch warning CHECK: Alignment should match open parenthesis WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? WARNING: line length of 91 exceeds 80 columns WARNING: please write a help paragraph that fully describes the config symbol
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Michael Weiß Oct. 25, 2023, 9:42 a.m. UTC
devcgroup_inode_mknod and devcgroup_inode_permission hooks are
called at place where already the corresponding lsm hooks
security_inode_mknod and security_inode_permission are called
to govern device access. Though introduce a small LSM which
implements those two security hooks instead of the additional
explicit devcgroup calls. The explicit API will be removed when
corresponding subsystems will drop the direct call to devcgroup
hooks.

Signed-off-by: Michael Weiß <michael.weiss@aisec.fraunhofer.de>
---
 init/Kconfig                                 |  4 +
 security/Kconfig                             |  1 +
 security/Makefile                            |  2 +-
 security/device_cgroup/Kconfig               |  7 ++
 security/device_cgroup/Makefile              |  4 +
 security/{ => device_cgroup}/device_cgroup.c |  0
 security/device_cgroup/lsm.c                 | 82 ++++++++++++++++++++
 7 files changed, 99 insertions(+), 1 deletion(-)
 create mode 100644 security/device_cgroup/Kconfig
 create mode 100644 security/device_cgroup/Makefile
 rename security/{ => device_cgroup}/device_cgroup.c (100%)
 create mode 100644 security/device_cgroup/lsm.c
diff mbox series

Patch

diff --git a/init/Kconfig b/init/Kconfig
index 6d35728b94b2..5ed28dc821f3 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1111,6 +1111,8 @@  config PROC_PID_CPUSET
 
 config CGROUP_DEVICE
 	bool "Device controller"
+	select SECURITY
+	select SECURITY_DEVICE_CGROUP
 	help
 	  Provides a cgroup controller implementing whitelists for
 	  devices which a process in the cgroup can mknod or open.
@@ -1136,6 +1138,8 @@  config CGROUP_BPF
 	bool "Support for eBPF programs attached to cgroups"
 	depends on BPF_SYSCALL
 	select SOCK_CGROUP_DATA
+	select SECURITY
+	select SECURITY_DEVICE_CGROUP
 	help
 	  Allow attaching eBPF programs to a cgroup using the bpf(2)
 	  syscall command BPF_PROG_ATTACH.
diff --git a/security/Kconfig b/security/Kconfig
index 52c9af08ad35..0a0e60fc50e1 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -194,6 +194,7 @@  source "security/yama/Kconfig"
 source "security/safesetid/Kconfig"
 source "security/lockdown/Kconfig"
 source "security/landlock/Kconfig"
+source "security/device_cgroup/Kconfig"
 
 source "security/integrity/Kconfig"
 
diff --git a/security/Makefile b/security/Makefile
index 18121f8f85cd..7000cb8a69e8 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -21,7 +21,7 @@  obj-$(CONFIG_SECURITY_YAMA)		+= yama/
 obj-$(CONFIG_SECURITY_LOADPIN)		+= loadpin/
 obj-$(CONFIG_SECURITY_SAFESETID)       += safesetid/
 obj-$(CONFIG_SECURITY_LOCKDOWN_LSM)	+= lockdown/
-obj-$(CONFIG_CGROUPS)			+= device_cgroup.o
+obj-$(CONFIG_SECURITY_DEVICE_CGROUP)	+= device_cgroup/
 obj-$(CONFIG_BPF_LSM)			+= bpf/
 obj-$(CONFIG_SECURITY_LANDLOCK)		+= landlock/
 
diff --git a/security/device_cgroup/Kconfig b/security/device_cgroup/Kconfig
new file mode 100644
index 000000000000..93934bda3b8e
--- /dev/null
+++ b/security/device_cgroup/Kconfig
@@ -0,0 +1,7 @@ 
+# SPDX-License-Identifier: GPL-2.0-only
+config SECURITY_DEVICE_CGROUP
+	bool "Device Cgroup Support"
+	depends on SECURITY
+	help
+	  Provides the necessary security framework integration
+	  for cgroup device controller implementations.
diff --git a/security/device_cgroup/Makefile b/security/device_cgroup/Makefile
new file mode 100644
index 000000000000..c715b2b96388
--- /dev/null
+++ b/security/device_cgroup/Makefile
@@ -0,0 +1,4 @@ 
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_SECURITY_DEVICE_CGROUP) += devcgroup.o
+
+devcgroup-y := lsm.o device_cgroup.o
diff --git a/security/device_cgroup.c b/security/device_cgroup/device_cgroup.c
similarity index 100%
rename from security/device_cgroup.c
rename to security/device_cgroup/device_cgroup.c
diff --git a/security/device_cgroup/lsm.c b/security/device_cgroup/lsm.c
new file mode 100644
index 000000000000..ef30cff1f610
--- /dev/null
+++ b/security/device_cgroup/lsm.c
@@ -0,0 +1,82 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device cgroup security module
+ *
+ * This file contains device cgroup LSM hooks.
+ *
+ * Copyright (C) 2023 Fraunhofer AISEC. All rights reserved.
+ * Based on code copied from <file:include/linux/device_cgroups.h> (which has no copyright)
+ *
+ * Authors: Michael Weiß <michael.weiss@aisec.fraunhofer.de>
+ */
+
+#include <linux/bpf-cgroup.h>
+#include <linux/device_cgroup.h>
+#include <linux/lsm_hooks.h>
+
+static int devcg_inode_permission(struct inode *inode, int mask)
+{
+	short type, access = 0;
+
+	if (likely(!inode->i_rdev))
+		return 0;
+
+	if (S_ISBLK(inode->i_mode))
+		type = DEVCG_DEV_BLOCK;
+	else if (S_ISCHR(inode->i_mode))
+		type = DEVCG_DEV_CHAR;
+	else
+		return 0;
+
+	if (mask & MAY_WRITE)
+		access |= DEVCG_ACC_WRITE;
+	if (mask & MAY_READ)
+		access |= DEVCG_ACC_READ;
+
+	return devcgroup_check_permission(type, imajor(inode), iminor(inode),
+					  access);
+}
+
+static int __devcg_inode_mknod(int mode, dev_t dev, short access)
+{
+	short type;
+
+	if (!S_ISBLK(mode) && !S_ISCHR(mode))
+		return 0;
+
+	if (S_ISCHR(mode) && dev == WHITEOUT_DEV)
+		return 0;
+
+	if (S_ISBLK(mode))
+		type = DEVCG_DEV_BLOCK;
+	else
+		type = DEVCG_DEV_CHAR;
+
+	return devcgroup_check_permission(type, MAJOR(dev), MINOR(dev),
+					  access);
+}
+
+static int devcg_inode_mknod(struct inode *dir, struct dentry *dentry,
+				 umode_t mode, dev_t dev)
+{
+	return __devcg_inode_mknod(mode, dev, DEVCG_ACC_MKNOD);
+}
+
+static struct security_hook_list devcg_hooks[] __ro_after_init = {
+	LSM_HOOK_INIT(inode_permission, devcg_inode_permission),
+	LSM_HOOK_INIT(inode_mknod, devcg_inode_mknod),
+};
+
+static int __init devcgroup_init(void)
+{
+	security_add_hooks(devcg_hooks, ARRAY_SIZE(devcg_hooks),
+			   "devcgroup");
+	pr_info("device cgroup initialized\n");
+	return 0;
+}
+
+DEFINE_LSM(devcgroup) = {
+	.name = "devcgroup",
+	.order = LSM_ORDER_FIRST,
+	.init = devcgroup_init,
+};