]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 24 Mar 2026 12:12:42 +0000 (13:12 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 24 Mar 2026 12:12:42 +0000 (13:12 +0100)
added patches:
xen-privcmd-add-boot-control-for-restricted-usage-in-domu.patch
xen-privcmd-restrict-usage-in-unprivileged-domu.patch

queue-6.18/series
queue-6.18/xen-privcmd-add-boot-control-for-restricted-usage-in-domu.patch [new file with mode: 0644]
queue-6.18/xen-privcmd-restrict-usage-in-unprivileged-domu.patch [new file with mode: 0644]

index e83abe7afa55daef2912ebe03e3d0c2aec885741..f459fc287b5f4695343951575c95487a212c0b48 100644 (file)
@@ -210,3 +210,5 @@ lib-bootconfig-check-xbc_init_node-return-in-overrid.patch
 tools-bootconfig-fix-fd-leak-in-load_xbc_file-on-fst.patch
 arm64-realm-fix-pte_ns_shared-for-52bit-pa-support.patch
 hwmon-max6639-fix-pulses-per-revolution-implementati.patch
+xen-privcmd-restrict-usage-in-unprivileged-domu.patch
+xen-privcmd-add-boot-control-for-restricted-usage-in-domu.patch
diff --git a/queue-6.18/xen-privcmd-add-boot-control-for-restricted-usage-in-domu.patch b/queue-6.18/xen-privcmd-add-boot-control-for-restricted-usage-in-domu.patch
new file mode 100644 (file)
index 0000000..ccc6c7f
--- /dev/null
@@ -0,0 +1,90 @@
+From aa3c2e217b1471cdc51fe98e883fab20277b0af6 Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Tue, 14 Oct 2025 13:28:15 +0200
+Subject: xen/privcmd: add boot control for restricted usage in domU
+
+From: Juergen Gross <jgross@suse.com>
+
+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    |   13 +++++++++++++
+ include/linux/security.h |    1 +
+ security/security.c      |    1 +
+ 3 files changed, 15 insertions(+)
+
+--- a/drivers/xen/privcmd.c
++++ b/drivers/xen/privcmd.c
+@@ -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, p
+ 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;
+ };
+@@ -1707,6 +1713,13 @@ static struct notifier_block xenstore_no
+ 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);
+--- a/include/linux/security.h
++++ b/include/linux/security.h
+@@ -144,6 +144,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,
+--- a/security/security.c
++++ b/security/security.c
+@@ -78,6 +78,7 @@ const char *const lockdown_reasons[LOCKD
+       [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",
diff --git a/queue-6.18/xen-privcmd-restrict-usage-in-unprivileged-domu.patch b/queue-6.18/xen-privcmd-restrict-usage-in-unprivileged-domu.patch
new file mode 100644 (file)
index 0000000..590d430
--- /dev/null
@@ -0,0 +1,157 @@
+From 13fa03edd54653ae09f1440b59bd8f6f1e5a6ada Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Thu, 9 Oct 2025 16:54:58 +0200
+Subject: xen/privcmd: restrict usage in unprivileged domU
+
+From: Juergen Gross <jgross@suse.com>
+
+commit 453b8fb68f3641fea970db88b7d9a153ed2a37e8 upstream.
+
+The Xen privcmd driver allows to issue arbitrary hypercalls from
+user space processes. This is normally no problem, as access is
+usually limited to root and the hypervisor will deny any hypercalls
+affecting other domains.
+
+In case the guest is booted using secure boot, however, the privcmd
+driver would be enabling a root user process to modify e.g. kernel
+memory contents, thus breaking the secure boot feature.
+
+The only known case where an unprivileged domU is really needing to
+use the privcmd driver is the case when it is acting as the device
+model for another guest. In this case all hypercalls issued via the
+privcmd driver will target that other guest.
+
+Fortunately the privcmd driver can already be locked down to allow
+only hypercalls targeting a specific domain, but this mode can be
+activated from user land only today.
+
+The target domain can be obtained from Xenstore, so when not running
+in dom0 restrict the privcmd driver to that target domain from the
+beginning, resolving the potential problem of breaking secure boot.
+
+This is XSA-482
+
+Reported-by: Teddy Astie <teddy.astie@vates.tech>
+Fixes: 1c5de1939c20 ("xen: add privcmd driver")
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/xen/privcmd.c |   60 +++++++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 57 insertions(+), 3 deletions(-)
+
+--- a/drivers/xen/privcmd.c
++++ b/drivers/xen/privcmd.c
+@@ -12,6 +12,7 @@
+ #include <linux/eventfd.h>
+ #include <linux/file.h>
+ #include <linux/kernel.h>
++#include <linux/kstrtox.h>
+ #include <linux/module.h>
+ #include <linux/mutex.h>
+ #include <linux/poll.h>
+@@ -30,7 +31,9 @@
+ #include <linux/seq_file.h>
+ #include <linux/miscdevice.h>
+ #include <linux/moduleparam.h>
++#include <linux/notifier.h>
+ #include <linux/virtio_mmio.h>
++#include <linux/wait.h>
+ #include <asm/xen/hypervisor.h>
+ #include <asm/xen/hypercall.h>
+@@ -46,6 +49,7 @@
+ #include <xen/page.h>
+ #include <xen/xen-ops.h>
+ #include <xen/balloon.h>
++#include <xen/xenbus.h>
+ #ifdef CONFIG_XEN_ACPI
+ #include <xen/acpi.h>
+ #endif
+@@ -72,6 +76,11 @@ struct privcmd_data {
+       domid_t domid;
+ };
++/* DOMID_INVALID implies no restriction */
++static domid_t target_domain = DOMID_INVALID;
++static bool restrict_wait;
++static DECLARE_WAIT_QUEUE_HEAD(restrict_wait_wq);
++
+ static int privcmd_vma_range_is_mapped(
+                struct vm_area_struct *vma,
+                unsigned long addr,
+@@ -1562,13 +1571,16 @@ static long privcmd_ioctl(struct file *f
+ static int privcmd_open(struct inode *ino, struct file *file)
+ {
+-      struct privcmd_data *data = kzalloc(sizeof(*data), GFP_KERNEL);
++      struct privcmd_data *data;
++
++      if (wait_event_interruptible(restrict_wait_wq, !restrict_wait) < 0)
++              return -EINTR;
++      data = kzalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+-      /* DOMID_INVALID implies no restriction */
+-      data->domid = DOMID_INVALID;
++      data->domid = target_domain;
+       file->private_data = data;
+       return 0;
+@@ -1661,6 +1673,45 @@ static struct miscdevice privcmd_dev = {
+       .fops = &xen_privcmd_fops,
+ };
++static int init_restrict(struct notifier_block *notifier,
++                       unsigned long event,
++                       void *data)
++{
++      char *target;
++      unsigned int domid;
++
++      /* Default to an guaranteed unused domain-id. */
++      target_domain = DOMID_IDLE;
++
++      target = xenbus_read(XBT_NIL, "target", "", NULL);
++      if (IS_ERR(target) || kstrtouint(target, 10, &domid)) {
++              pr_err("No target domain found, blocking all hypercalls\n");
++              goto out;
++      }
++
++      target_domain = domid;
++
++ out:
++      if (!IS_ERR(target))
++              kfree(target);
++
++      restrict_wait = false;
++      wake_up_all(&restrict_wait_wq);
++
++      return NOTIFY_DONE;
++}
++
++static struct notifier_block xenstore_notifier = {
++      .notifier_call = init_restrict,
++};
++
++static void __init restrict_driver(void)
++{
++      restrict_wait = true;
++
++      register_xenstore_notifier(&xenstore_notifier);
++}
++
+ static int __init privcmd_init(void)
+ {
+       int err;
+@@ -1668,6 +1719,9 @@ static int __init privcmd_init(void)
+       if (!xen_domain())
+               return -ENODEV;
++      if (!xen_initial_domain())
++              restrict_driver();
++
+       err = misc_register(&privcmd_dev);
+       if (err != 0) {
+               pr_err("Could not register Xen privcmd device\n");