If either via kernel command line 'vdso32=' or via 'sysctl abi.vsyscall32'
vdso32_enabled gets set to a value below 0 or above 1, load_vdso32() won't
map the vDSO but ARCH_DLINFO_IA32 would still pass an AT_SYSINFO_EHDR
auxiliary vector, however with a NULL pointer. That'll make any program
trying to make use of it fail with a segmentation fault. At least musl
makes use of it if the kernel provides it.

Ensure vdso32_enabled gets set to valid values only to fix this corner
case.

Fixes: b0b49f2673f0 ("x86, vdso: Remove compat vdso support")
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: Ingo Molnar <mi...@redhat.com>
Cc: "H. Peter Anvin" <h...@zytor.com>
Cc: Roland McGrath <rol...@redhat.com>
Signed-off-by: Mathias Krause <mini...@googlemail.com>
---
 arch/x86/entry/vdso/vdso32-setup.c |   11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/x86/entry/vdso/vdso32-setup.c 
b/arch/x86/entry/vdso/vdso32-setup.c
index 7853b53959cd..ca312c174d6f 100644
--- a/arch/x86/entry/vdso/vdso32-setup.c
+++ b/arch/x86/entry/vdso/vdso32-setup.c
@@ -30,8 +30,10 @@ static int __init vdso32_setup(char *s)
 {
        vdso32_enabled = simple_strtoul(s, NULL, 0);
 
-       if (vdso32_enabled > 1)
+       if (vdso32_enabled > 1) {
                pr_warn("vdso32 values other than 0 and 1 are no longer 
allowed; vdso disabled\n");
+               vdso32_enabled = 0;
+       }
 
        return 1;
 }
@@ -62,13 +64,18 @@ int __init sysenter_setup(void)
 /* Register vsyscall32 into the ABI table */
 #include <linux/sysctl.h>
 
+static const int zero;
+static const int one = 1;
+
 static struct ctl_table abi_table2[] = {
        {
                .procname       = "vsyscall32",
                .data           = &vdso32_enabled,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = proc_dointvec
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = (int *)&zero,
+               .extra2         = (int *)&one,
        },
        {}
 };
-- 
1.7.10.4

Reply via email to