]> git.ipfire.org Git - thirdparty/kernel/stable.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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 25 Mar 2026 10:08:57 +0000 (11:08 +0100)
commit 1613462be621ad5103ec338a7b0ca0746ec4e5f1 upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/xen/privcmd.c
include/linux/security.h
security/security.c

index 4bcf44b19bac07e05fb2209cf2c521691daf133a..b366192c77cf19a22ffc57748a3c3cfe708040fb 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;
 };
@@ -1727,6 +1733,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 2ec8f3014757cd78ef0d961e77f42db409db3b1c..2c6db949ad1a16c6eb8d973ba965349ec87ef06e 100644 (file)
@@ -140,6 +140,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 c5981e558bc2643b485778edf5c5c20f725ccb00..6e4deac6ec0737fef28c65cff0fe679fef749e05 100644 (file)
@@ -79,6 +79,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",