cregit-Linux how code gets into the kernel

Release 4.10 tools/testing/selftests/x86/vdso_restorer.c

/*
 * vdso_restorer.c - tests vDSO-based signal restore
 * Copyright (c) 2015 Andrew Lutomirski
 *
 * 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.
 *
 * 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; }

Contributors

PersonTokensPropCommitsCommitProp
andy lutomirskiandy lutomirski21100.00%1100.00%
Total21100.00%1100.00%


static void handler_without_siginfo(int sig) { handler_called = 1; }

Contributors

PersonTokensPropCommitsCommitProp
andy lutomirskiandy lutomirski13100.00%1100.00%
Total13100.00%1100.00%


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++; } }

Contributors

PersonTokensPropCommitsCommitProp
andy lutomirskiandy lutomirski164100.00%1100.00%
Total164100.00%1100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
andy lutomirskiandy lutomirski253100.00%1100.00%
Total253100.00%1100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.