mirror of
https://github.com/torvalds/linux.git
synced 2024-12-12 14:12:51 +00:00
2025cf9e19
Based on 1 normalized pattern(s): this program is free software you can redistribute it and or modify it under the terms and conditions of the gnu general public license version 2 as published by the free software foundation this program is distributed in the hope it will be useful but without any warranty without even the implied warranty of merchantability or fitness for a particular purpose see the gnu general public license for more details extracted by the scancode license scanner the SPDX license identifier GPL-2.0-only has been chosen to replace the boilerplate/reference in 263 file(s). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Allison Randal <allison@lohutok.net> Reviewed-by: Alexios Zavras <alexios.zavras@intel.com> Cc: linux-spdx@vger.kernel.org Link: https://lkml.kernel.org/r/20190529141901.208660670@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
81 lines
1.8 KiB
C
81 lines
1.8 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* vdso_restorer.c - tests vDSO-based signal restore
|
|
* Copyright (c) 2015 Andrew Lutomirski
|
|
*
|
|
* This makes sure that sa_restorer == NULL keeps working on 32-bit
|
|
* configurations. Modern glibc doesn't use it under any circumstances,
|
|
* so it's easy to overlook breakage.
|
|
*
|
|
* 64-bit userspace has never supported sa_restorer == NULL, so this is
|
|
* 32-bit only.
|
|
*/
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#include <err.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <signal.h>
|
|
#include <unistd.h>
|
|
#include <syscall.h>
|
|
#include <sys/syscall.h>
|
|
|
|
/* Open-code this -- the headers are too messy to easily use them. */
|
|
struct real_sigaction {
|
|
void *handler;
|
|
unsigned long flags;
|
|
void *restorer;
|
|
unsigned int mask[2];
|
|
};
|
|
|
|
static volatile sig_atomic_t handler_called;
|
|
|
|
static void handler_with_siginfo(int sig, siginfo_t *info, void *ctx_void)
|
|
{
|
|
handler_called = 1;
|
|
}
|
|
|
|
static void handler_without_siginfo(int sig)
|
|
{
|
|
handler_called = 1;
|
|
}
|
|
|
|
int main()
|
|
{
|
|
int nerrs = 0;
|
|
struct real_sigaction sa;
|
|
|
|
memset(&sa, 0, sizeof(sa));
|
|
sa.handler = handler_with_siginfo;
|
|
sa.flags = SA_SIGINFO;
|
|
sa.restorer = NULL; /* request kernel-provided restorer */
|
|
|
|
if (syscall(SYS_rt_sigaction, SIGUSR1, &sa, NULL, 8) != 0)
|
|
err(1, "raw rt_sigaction syscall");
|
|
|
|
raise(SIGUSR1);
|
|
|
|
if (handler_called) {
|
|
printf("[OK]\tSA_SIGINFO handler returned successfully\n");
|
|
} else {
|
|
printf("[FAIL]\tSA_SIGINFO handler was not called\n");
|
|
nerrs++;
|
|
}
|
|
|
|
sa.flags = 0;
|
|
sa.handler = handler_without_siginfo;
|
|
if (syscall(SYS_sigaction, SIGUSR1, &sa, 0) != 0)
|
|
err(1, "raw sigaction syscall");
|
|
handler_called = 0;
|
|
|
|
raise(SIGUSR1);
|
|
|
|
if (handler_called) {
|
|
printf("[OK]\t!SA_SIGINFO handler returned successfully\n");
|
|
} else {
|
|
printf("[FAIL]\t!SA_SIGINFO handler was not called\n");
|
|
nerrs++;
|
|
}
|
|
}
|