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

clone3_clear_sighand.c (2598B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2
      3#define _GNU_SOURCE
      4#include <errno.h>
      5#include <sched.h>
      6#include <signal.h>
      7#include <stdio.h>
      8#include <stdlib.h>
      9#include <string.h>
     10#include <unistd.h>
     11#include <linux/sched.h>
     12#include <linux/types.h>
     13#include <sys/syscall.h>
     14#include <sys/wait.h>
     15
     16#include "../kselftest.h"
     17#include "clone3_selftests.h"
     18
     19#ifndef CLONE_CLEAR_SIGHAND
     20#define CLONE_CLEAR_SIGHAND 0x100000000ULL
     21#endif
     22
     23static void nop_handler(int signo)
     24{
     25}
     26
     27static int wait_for_pid(pid_t pid)
     28{
     29	int status, ret;
     30
     31again:
     32	ret = waitpid(pid, &status, 0);
     33	if (ret == -1) {
     34		if (errno == EINTR)
     35			goto again;
     36
     37		return -1;
     38	}
     39
     40	if (!WIFEXITED(status))
     41		return -1;
     42
     43	return WEXITSTATUS(status);
     44}
     45
     46static void test_clone3_clear_sighand(void)
     47{
     48	int ret;
     49	pid_t pid;
     50	struct __clone_args args = {};
     51	struct sigaction act;
     52
     53	/*
     54	 * Check that CLONE_CLEAR_SIGHAND and CLONE_SIGHAND are mutually
     55	 * exclusive.
     56	 */
     57	args.flags |= CLONE_CLEAR_SIGHAND | CLONE_SIGHAND;
     58	args.exit_signal = SIGCHLD;
     59	pid = sys_clone3(&args, sizeof(args));
     60	if (pid > 0)
     61		ksft_exit_fail_msg(
     62			"clone3(CLONE_CLEAR_SIGHAND | CLONE_SIGHAND) succeeded\n");
     63
     64	act.sa_handler = nop_handler;
     65	ret = sigemptyset(&act.sa_mask);
     66	if (ret < 0)
     67		ksft_exit_fail_msg("%s - sigemptyset() failed\n",
     68				   strerror(errno));
     69
     70	act.sa_flags = 0;
     71
     72	/* Register signal handler for SIGUSR1 */
     73	ret = sigaction(SIGUSR1, &act, NULL);
     74	if (ret < 0)
     75		ksft_exit_fail_msg(
     76			"%s - sigaction(SIGUSR1, &act, NULL) failed\n",
     77			strerror(errno));
     78
     79	/* Register signal handler for SIGUSR2 */
     80	ret = sigaction(SIGUSR2, &act, NULL);
     81	if (ret < 0)
     82		ksft_exit_fail_msg(
     83			"%s - sigaction(SIGUSR2, &act, NULL) failed\n",
     84			strerror(errno));
     85
     86	/* Check that CLONE_CLEAR_SIGHAND works. */
     87	args.flags = CLONE_CLEAR_SIGHAND;
     88	pid = sys_clone3(&args, sizeof(args));
     89	if (pid < 0)
     90		ksft_exit_fail_msg("%s - clone3(CLONE_CLEAR_SIGHAND) failed\n",
     91				   strerror(errno));
     92
     93	if (pid == 0) {
     94		ret = sigaction(SIGUSR1, NULL, &act);
     95		if (ret < 0)
     96			exit(EXIT_FAILURE);
     97
     98		if (act.sa_handler != SIG_DFL)
     99			exit(EXIT_FAILURE);
    100
    101		ret = sigaction(SIGUSR2, NULL, &act);
    102		if (ret < 0)
    103			exit(EXIT_FAILURE);
    104
    105		if (act.sa_handler != SIG_DFL)
    106			exit(EXIT_FAILURE);
    107
    108		exit(EXIT_SUCCESS);
    109	}
    110
    111	ret = wait_for_pid(pid);
    112	if (ret)
    113		ksft_exit_fail_msg(
    114			"Failed to clear signal handler for child process\n");
    115
    116	ksft_test_result_pass("Cleared signal handlers for child process\n");
    117}
    118
    119int main(int argc, char **argv)
    120{
    121	ksft_print_header();
    122	ksft_set_plan(1);
    123	test_clone3_supported();
    124
    125	test_clone3_clear_sighand();
    126
    127	return ksft_exit_pass();
    128}