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

tm-signal-stack.c (1774B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright 2015, Michael Neuling, IBM Corp.
      4 *
      5 * Test the kernel's signal delievery code to ensure that we don't
      6 * trelaim twice in the kernel signal delivery code.  This can happen
      7 * if we trigger a signal when in a transaction and the stack pointer
      8 * is bogus.
      9 *
     10 * This test case registers a SEGV handler, sets the stack pointer
     11 * (r1) to NULL, starts a transaction and then generates a SEGV.  The
     12 * SEGV should be handled but we exit here as the stack pointer is
     13 * invalid and hance we can't sigreturn.  We only need to check that
     14 * this flow doesn't crash the kernel.
     15 */
     16
     17#include <unistd.h>
     18#include <sys/types.h>
     19#include <sys/wait.h>
     20#include <stdlib.h>
     21#include <stdio.h>
     22#include <signal.h>
     23
     24#include "utils.h"
     25#include "tm.h"
     26
     27void signal_segv(int signum)
     28{
     29	/* This should never actually run since stack is foobar */
     30	exit(1);
     31}
     32
     33int tm_signal_stack()
     34{
     35	int pid;
     36
     37	SKIP_IF(!have_htm());
     38	SKIP_IF(htm_is_synthetic());
     39
     40	pid = fork();
     41	if (pid < 0)
     42		exit(1);
     43
     44	if (pid) { /* Parent */
     45		/*
     46		 * It's likely the whole machine will crash here so if
     47		 * the child ever exits, we are good.
     48		 */
     49		wait(NULL);
     50		return 0;
     51	}
     52
     53	/*
     54	 * The flow here is:
     55	 * 1) register a signal handler (so signal delievery occurs)
     56	 * 2) make stack pointer (r1) = NULL
     57	 * 3) start transaction
     58	 * 4) cause segv
     59	 */
     60	if (signal(SIGSEGV, signal_segv) == SIG_ERR)
     61		exit(1);
     62	asm volatile("li 1, 0 ;"		/* stack ptr == NULL */
     63		     "1:"
     64		     "tbegin.;"
     65		     "beq 1b ;"			/* retry forever */
     66		     "tsuspend.;"
     67		     "ld 2, 0(1) ;"		/* trigger segv" */
     68		     : : : "memory");
     69
     70	/* This should never get here due to above segv */
     71	return 1;
     72}
     73
     74int main(void)
     75{
     76	return test_harness(tm_signal_stack, "tm_signal_stack");
     77}