]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xen/privcmd: add boot control for restricted usage in domU
authorJuergen Gross <jgross@suse.com>
Tue, 14 Oct 2025 11:28:15 +0000 (13:28 +0200)
committerJuergen Gross <jgross@suse.com>
Fri, 20 Mar 2026 11:06:01 +0000 (12:06 +0100)
When running in an unprivileged domU under Xen, the privcmd driver
is restricted to allow only hypercalls against a target domain, for
which the current domU is acting as a device model.

Add a boot parameter "unrestricted" to allow all hypercalls (the
hypervisor will still refuse destructive hypercalls affecting other
guests).

Make this new parameter effective only in case the domU wasn't started
using secure boot, as otherwise hypercalls targeting the domU itself
might result in violating the secure boot functionality.

This is achieved by adding another lockdown reason, which can be
tested to not being set when applying the "unrestricted" option.

This is part of XSA-482

Signed-off-by: Juergen Gross <jgross@suse.com>
---
V2:
- new patch

drivers/xen/privcmd.c
include/linux/security.h
security/security.c

index a83bad69f4f2184b722e278dc81f8a4aa662d5de..bbf9ee21306cdeb63bb0a4c43f045659edaff0ea 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/miscdevice.h>
 #include <linux/moduleparam.h>
 #include <linux/notifier.h>
+#include <linux/security.h>
 #include <linux/virtio_mmio.h>
 #include <linux/wait.h>
 
@@ -72,6 +73,11 @@ module_param_named(dm_op_buf_max_size, privcmd_dm_op_buf_max_size, uint,
 MODULE_PARM_DESC(dm_op_buf_max_size,
                 "Maximum size of a dm_op hypercall buffer");
 
+static bool unrestricted;
+module_param(unrestricted, bool, 0);
+MODULE_PARM_DESC(unrestricted,
+       "Don't restrict hypercalls to target domain if running in a domU");
+
 struct privcmd_data {
        domid_t domid;
 };
@@ -1708,6 +1714,13 @@ static struct notifier_block xenstore_notifier = {
 
 static void __init restrict_driver(void)
 {
+       if (unrestricted) {
+               if (security_locked_down(LOCKDOWN_XEN_USER_ACTIONS))
+                       pr_warn("Kernel is locked down, parameter \"unrestricted\" ignored\n");
+               else
+                       return;
+       }
+
        restrict_wait = true;
 
        register_xenstore_notifier(&xenstore_notifier);
index 83a646d72f6f8facea550c63693a397cca4cd0ef..ee88dd2d2d1f715e9c1ff65220e83eacb5d9f167 100644 (file)
@@ -145,6 +145,7 @@ enum lockdown_reason {
        LOCKDOWN_BPF_WRITE_USER,
        LOCKDOWN_DBG_WRITE_KERNEL,
        LOCKDOWN_RTAS_ERROR_INJECTION,
+       LOCKDOWN_XEN_USER_ACTIONS,
        LOCKDOWN_INTEGRITY_MAX,
        LOCKDOWN_KCORE,
        LOCKDOWN_KPROBES,
index 67af9228c4e9413d62aff17884657427adfaa4b0..a26c1474e2e499b81c3a3285f52f3c14c8bae4ec 100644 (file)
@@ -61,6 +61,7 @@ const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX + 1] = {
        [LOCKDOWN_BPF_WRITE_USER] = "use of bpf to write user RAM",
        [LOCKDOWN_DBG_WRITE_KERNEL] = "use of kgdb/kdb to write kernel RAM",
        [LOCKDOWN_RTAS_ERROR_INJECTION] = "RTAS error injection",
+       [LOCKDOWN_XEN_USER_ACTIONS] = "Xen guest user action",
        [LOCKDOWN_INTEGRITY_MAX] = "integrity",
        [LOCKDOWN_KCORE] = "/proc/kcore access",
        [LOCKDOWN_KPROBES] = "use of kprobes",