Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/x86/vdso: Fix no-vDSO segfaults

test_vdso would try to call a NULL pointer if the vDSO was missing.

vdso_restorer_32 hit a genuine failure: trying to use the
kernel-provided signal restorer doesn't work if the vDSO is missing.
Skip the test if the vDSO is missing, since the test adds no particular
value in that case.

Reported-by: kbuild test robot <lkp@intel.com>
Signed-off-by: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/618ea7b8c55b10d08b1cb139e9a3a957934b8647.1584653439.git.luto@kernel.org

authored by

Andy Lutomirski and committed by
Borislav Petkov
07f24dc9 fb33c651

+20
+5
tools/testing/selftests/x86/test_vdso.c
··· 259 259 260 260 static void test_clock_gettime(void) 261 261 { 262 + if (!vdso_clock_gettime) { 263 + printf("[SKIP]\tNo vDSO, so skipping clock_gettime() tests\n"); 264 + return; 265 + } 266 + 262 267 for (int clock = 0; clock < sizeof(clocknames) / sizeof(clocknames[0]); 263 268 clock++) { 264 269 test_one_clock_gettime(clock, clocknames[clock]);
+15
tools/testing/selftests/x86/vdso_restorer.c
··· 15 15 16 16 #include <err.h> 17 17 #include <stdio.h> 18 + #include <dlfcn.h> 18 19 #include <string.h> 19 20 #include <signal.h> 20 21 #include <unistd.h> ··· 47 46 int nerrs = 0; 48 47 struct real_sigaction sa; 49 48 49 + void *vdso = dlopen("linux-vdso.so.1", 50 + RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD); 51 + if (!vdso) 52 + vdso = dlopen("linux-gate.so.1", 53 + RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD); 54 + if (!vdso) { 55 + printf("[SKIP]\tFailed to find vDSO. Tests are not expected to work.\n"); 56 + return 0; 57 + } 58 + 50 59 memset(&sa, 0, sizeof(sa)); 51 60 sa.handler = handler_with_siginfo; 52 61 sa.flags = SA_SIGINFO; 53 62 sa.restorer = NULL; /* request kernel-provided restorer */ 63 + 64 + printf("[RUN]\tRaise a signal, SA_SIGINFO, sa.restorer == NULL\n"); 54 65 55 66 if (syscall(SYS_rt_sigaction, SIGUSR1, &sa, NULL, 8) != 0) 56 67 err(1, "raw rt_sigaction syscall"); ··· 75 62 printf("[FAIL]\tSA_SIGINFO handler was not called\n"); 76 63 nerrs++; 77 64 } 65 + 66 + printf("[RUN]\tRaise a signal, !SA_SIGINFO, sa.restorer == NULL\n"); 78 67 79 68 sa.flags = 0; 80 69 sa.handler = handler_without_siginfo;