From: Greg Kroah-Hartman Date: Tue, 24 Mar 2026 12:12:34 +0000 (+0100) Subject: 6.12-stable patches X-Git-Tag: v6.1.167~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2358eb7e9960dbcd792641103470f42d2a059c02;p=thirdparty%2Fkernel%2Fstable-queue.git 6.12-stable patches added patches: xen-privcmd-add-boot-control-for-restricted-usage-in-domu.patch xen-privcmd-restrict-usage-in-unprivileged-domu.patch --- diff --git a/queue-6.12/series b/queue-6.12/series index 148f03b783..f7793b81e5 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -458,3 +458,5 @@ lib-bootconfig-check-xbc_init_node-return-in-overrid.patch tools-bootconfig-fix-fd-leak-in-load_xbc_file-on-fst.patch hwmon-max6639-fix-pulses-per-revolution-implementati.patch perf-x86-intel-add-missing-branch-counters-constraint-apply.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.12/xen-privcmd-add-boot-control-for-restricted-usage-in-domu.patch b/queue-6.12/xen-privcmd-add-boot-control-for-restricted-usage-in-domu.patch new file mode 100644 index 0000000000..b5d6b12b6d --- /dev/null +++ b/queue-6.12/xen-privcmd-add-boot-control-for-restricted-usage-in-domu.patch @@ -0,0 +1,90 @@ +From 1a801ce7c1d550ac59822ae2b6ace4540e165c36 Mon Sep 17 00:00:00 2001 +From: Juergen Gross +Date: Tue, 14 Oct 2025 13:28:15 +0200 +Subject: xen/privcmd: add boot control for restricted usage in domU + +From: Juergen Gross + +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + #include ++#include + #include + #include + +@@ -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; + }; +@@ -1727,6 +1733,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 +@@ -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, +--- a/security/security.c ++++ b/security/security.c +@@ -79,6 +79,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.12/xen-privcmd-restrict-usage-in-unprivileged-domu.patch b/queue-6.12/xen-privcmd-restrict-usage-in-unprivileged-domu.patch new file mode 100644 index 0000000000..db487d95ae --- /dev/null +++ b/queue-6.12/xen-privcmd-restrict-usage-in-unprivileged-domu.patch @@ -0,0 +1,157 @@ +From a4403864fddca76d6d0fb982818d3407ce13cb8e Mon Sep 17 00:00:00 2001 +From: Juergen Gross +Date: Thu, 9 Oct 2025 16:54:58 +0200 +Subject: xen/privcmd: restrict usage in unprivileged domU + +From: Juergen Gross + +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 +Fixes: 1c5de1939c20 ("xen: add privcmd driver") +Signed-off-by: Juergen Gross +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + #include ++#include + #include + #include + #include +@@ -30,7 +31,9 @@ + #include + #include + #include ++#include + #include ++#include + + #include + #include +@@ -46,6 +49,7 @@ + #include + #include + #include ++#include + #ifdef CONFIG_XEN_ACPI + #include + #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, +@@ -1582,13 +1591,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; +@@ -1681,6 +1693,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; +@@ -1688,6 +1739,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");