cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

vdso_restorer.c (2262B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * vdso_restorer.c - tests vDSO-based signal restore
      4 * Copyright (c) 2015 Andrew Lutomirski
      5 *
      6 * This makes sure that sa_restorer == NULL keeps working on 32-bit
      7 * configurations.  Modern glibc doesn't use it under any circumstances,
      8 * so it's easy to overlook breakage.
      9 *
     10 * 64-bit userspace has never supported sa_restorer == NULL, so this is
     11 * 32-bit only.
     12 */
     13
     14#define _GNU_SOURCE
     15
     16#include <err.h>
     17#include <stdio.h>
     18#include <dlfcn.h>
     19#include <string.h>
     20#include <signal.h>
     21#include <unistd.h>
     22#include <syscall.h>
     23#include <sys/syscall.h>
     24
     25/* Open-code this -- the headers are too messy to easily use them. */
     26struct real_sigaction {
     27	void *handler;
     28	unsigned long flags;
     29	void *restorer;
     30	unsigned int mask[2];
     31};
     32
     33static volatile sig_atomic_t handler_called;
     34
     35static void handler_with_siginfo(int sig, siginfo_t *info, void *ctx_void)
     36{
     37	handler_called = 1;
     38}
     39
     40static void handler_without_siginfo(int sig)
     41{
     42	handler_called = 1;
     43}
     44
     45int main()
     46{
     47	int nerrs = 0;
     48	struct real_sigaction sa;
     49
     50	void *vdso = dlopen("linux-vdso.so.1",
     51			    RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
     52	if (!vdso)
     53		vdso = dlopen("linux-gate.so.1",
     54			      RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
     55	if (!vdso) {
     56		printf("[SKIP]\tFailed to find vDSO.  Tests are not expected to work.\n");
     57		return 0;
     58	}
     59
     60	memset(&sa, 0, sizeof(sa));
     61	sa.handler = handler_with_siginfo;
     62	sa.flags = SA_SIGINFO;
     63	sa.restorer = NULL;	/* request kernel-provided restorer */
     64
     65	printf("[RUN]\tRaise a signal, SA_SIGINFO, sa.restorer == NULL\n");
     66
     67	if (syscall(SYS_rt_sigaction, SIGUSR1, &sa, NULL, 8) != 0)
     68		err(1, "raw rt_sigaction syscall");
     69
     70	raise(SIGUSR1);
     71
     72	if (handler_called) {
     73		printf("[OK]\tSA_SIGINFO handler returned successfully\n");
     74	} else {
     75		printf("[FAIL]\tSA_SIGINFO handler was not called\n");
     76		nerrs++;
     77	}
     78
     79	printf("[RUN]\tRaise a signal, !SA_SIGINFO, sa.restorer == NULL\n");
     80
     81	sa.flags = 0;
     82	sa.handler = handler_without_siginfo;
     83	if (syscall(SYS_sigaction, SIGUSR1, &sa, 0) != 0)
     84		err(1, "raw sigaction syscall");
     85	handler_called = 0;
     86
     87	raise(SIGUSR1);
     88
     89	if (handler_called) {
     90		printf("[OK]\t!SA_SIGINFO handler returned successfully\n");
     91	} else {
     92		printf("[FAIL]\t!SA_SIGINFO handler was not called\n");
     93		nerrs++;
     94	}
     95}