From 3a1ae904dba54474a56815ba7fbf3238fcfe5a46 Mon Sep 17 00:00:00 2001
From: Ondrej Mosnacek <omosnace@redhat.com>
Date: Mon, 30 Jan 2023 14:46:50 +0100
Subject: [PATCH 2/5] Add initial policy for the /usr/sbin/request-key helper

The kernel is hard-coded to call /sbin/request-key to handle requests
for instantiating keys that are not found in the existing keyrings.

Thus, we need to add a domain for this helper and set up a transition
into that domain from kernel_t.

request-key dispatches the key requests to further helper programs based
on the configuration in /etc/request-key.d/*.conf and
/etc/request-key.conf. Currently, the only known used dispatcher is
/usr/sbin/nfsidmap, which is set up by the nfs-utils package to handle
requests for the 'id_resolver' key type. This patch adds the minimal
policy for this helper that is needed for an NFS mount to succeed.

Policy for other request-key helper programs may need to be added in the
future. An optional mechanism to allow any possible configuration (e.g.
by setting up a transition over any file to unconfined_service_t) may be
also desired. For now let's at least make the one known use case work.

Fixes: 1e8688ea6943 ("Don't make kernel_t an unconfined domain")
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
---
 policy/modules.conf                |  7 +++++
 policy/modules/contrib/keyutils.fc |  1 +
 policy/modules/contrib/keyutils.if | 43 ++++++++++++++++++++++++++++++
 policy/modules/contrib/keyutils.te | 11 ++++++++
 policy/modules/contrib/rpc.fc      |  1 +
 policy/modules/contrib/rpc.te      | 32 ++++++++++++++++++++++
 policy/modules/kernel/kernel.if    | 19 +++++++++++++
 policy/modules/kernel/kernel.te    |  4 +++
 8 files changed, 118 insertions(+)
 create mode 100644 policy/modules/contrib/keyutils.fc
 create mode 100644 policy/modules/contrib/keyutils.if
 create mode 100644 policy/modules/contrib/keyutils.te

diff --git a/policy/modules.conf b/policy/modules.conf
index 5e0678668..6f63c8cb6 100644
--- a/policy/modules.conf
+++ b/policy/modules.conf
@@ -3078,3 +3078,10 @@ rhcd = module
 # wireguard
 #
 wireguard = module
+
+# Layer: contrib
+# Module: keyutils
+#
+#  keyutils - Linux Key Management Utilities
+#
+keyutils = module
diff --git a/policy/modules/contrib/keyutils.fc b/policy/modules/contrib/keyutils.fc
new file mode 100644
index 000000000..78c5f159f
--- /dev/null
+++ b/policy/modules/contrib/keyutils.fc
@@ -0,0 +1 @@
+/usr/sbin/request-key	--	gen_context(system_u:object_r:keyutils_request_exec_t,s0)
diff --git a/policy/modules/contrib/keyutils.if b/policy/modules/contrib/keyutils.if
new file mode 100644
index 000000000..06daab988
--- /dev/null
+++ b/policy/modules/contrib/keyutils.if
@@ -0,0 +1,43 @@
+## <summary>Linux Key Management Utilities</summary>
+
+#######################################
+## <summary>
+##	Execute request-key in the keyutils request domain.
+## </summary>
+## <param name="domain">
+##	<summary>
+##	Domain allowed access.
+##	</summary>
+## </param>
+#
+interface(`keyutils_request_domtrans',`
+	gen_require(`
+		type keyutils_request_t, keyutils_request_exec_t;
+	')
+
+	domtrans_pattern($1, keyutils_request_exec_t, keyutils_request_t)
+')
+
+########################################
+## <summary>
+##	Allows to perform key instantiation callout
+##	by transitioning to the specified domain.
+## </summary>
+## <param name="domain">
+##	<summary>
+##	The process type entered by request-key.
+##	</summary>
+## </param>
+## <param name="entrypoint">
+##	<summary>
+##	The executable type for the entrypoint.
+##	</summary>
+## </param>
+#
+interface(`keyutils_request_domtrans_to',`
+	gen_require(`
+		type keyutils_request_t;
+	')
+
+	domtrans_pattern(keyutils_request_t, $2, $1)
+')
diff --git a/policy/modules/contrib/keyutils.te b/policy/modules/contrib/keyutils.te
new file mode 100644
index 000000000..2ea1d5e38
--- /dev/null
+++ b/policy/modules/contrib/keyutils.te
@@ -0,0 +1,11 @@
+policy_module(keyutils, 1.0)
+
+type keyutils_request_exec_t;
+files_type(keyutils_request_exec_t)
+
+type keyutils_request_t;
+domain_type(keyutils_request_t)
+domain_entry_file(keyutils_request_t, keyutils_request_exec_t)
+
+kernel_view_key(keyutils_request_t)
+kernel_read_key(keyutils_request_t)
diff --git a/policy/modules/contrib/rpc.fc b/policy/modules/contrib/rpc.fc
index 3825ef707..06a6c009c 100644
--- a/policy/modules/contrib/rpc.fc
+++ b/policy/modules/contrib/rpc.fc
@@ -32,6 +32,7 @@
 /usr/sbin/rpc\.svcgssd	--	gen_context(system_u:object_r:gssd_exec_t,s0)
 /usr/sbin/sm-notify	--	gen_context(system_u:object_r:rpcd_exec_t,s0)
 /usr/sbin/nfsdcld	--	gen_context(system_u:object_r:rpcd_exec_t,s0)
+/usr/sbin/nfsidmap	--	gen_context(system_u:object_r:nfsidmap_exec_t,s0)
 
 #
 # /var
diff --git a/policy/modules/contrib/rpc.te b/policy/modules/contrib/rpc.te
index f94cfa5d2..c83492a56 100644
--- a/policy/modules/contrib/rpc.te
+++ b/policy/modules/contrib/rpc.te
@@ -434,3 +434,35 @@ optional_policy(`
 optional_policy(`
 	xserver_rw_xdm_tmp_files(gssd_t)
 ')
+
+########################################
+#
+# nfsidmap policy
+#
+
+type nfsidmap_exec_t;
+files_type(nfsidmap_exec_t)
+
+type nfsidmap_t;
+domain_type(nfsidmap_t)
+domain_entry_file(nfsidmap_t, nfsidmap_exec_t)
+
+allow nfsidmap_t self:key write;
+allow nfsidmap_t self:netlink_route_socket r_netlink_socket_perms;
+
+kernel_setattr_key(nfsidmap_t)
+
+sysnet_read_config(nfsidmap_t)
+
+optional_policy(`
+	auth_read_passwd_file(nfsidmap_t)
+')
+
+optional_policy(`
+	logging_send_syslog_msg(nfsidmap_t)
+')
+
+optional_policy(`
+	# /etc/request-key.d/id_resolver.conf
+	keyutils_request_domtrans_to(nfsidmap_t, nfsidmap_exec_t)
+')
diff --git a/policy/modules/kernel/kernel.if b/policy/modules/kernel/kernel.if
index 166586f66..adb71ed3a 100644
--- a/policy/modules/kernel/kernel.if
+++ b/policy/modules/kernel/kernel.if
@@ -579,6 +579,25 @@ interface(`kernel_dontaudit_view_key',`
 
 	dontaudit $1 kernel_t:key view;
 ')
+
+########################################
+## <summary>
+##	Allow to set attributes on the kernel key ring.
+## </summary>
+## <param name="domain">
+##	<summary>
+##	Domain allowed access.
+##	</summary>
+## </param>
+#
+interface(`kernel_setattr_key',`
+	gen_require(`
+		type kernel_t;
+	')
+
+	allow $1 kernel_t:key setattr;
+')
+
 ########################################
 ## <summary>
 ##	Allows caller to read the ring buffer.
diff --git a/policy/modules/kernel/kernel.te b/policy/modules/kernel/kernel.te
index f7ac8cd1f..0a27fa7ae 100644
--- a/policy/modules/kernel/kernel.te
+++ b/policy/modules/kernel/kernel.te
@@ -410,6 +410,10 @@ optional_policy(`
 	kerberos_filetrans_home_content(kernel_t)
 ')
 
+optional_policy(`
+	keyutils_request_domtrans(kernel_t)
+')
+
 optional_policy(`
 	init_dbus_chat(kernel_t)
 	init_sigchld(kernel_t)
-- 
2.33.0

