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

exec.c (1877B)


      1// SPDX-License-Identifier: GPL-2.0
      2#define _GNU_SOURCE
      3#include <errno.h>
      4#include <fcntl.h>
      5#include <sched.h>
      6#include <stdio.h>
      7#include <stdbool.h>
      8#include <sys/stat.h>
      9#include <sys/syscall.h>
     10#include <sys/types.h>
     11#include <sys/wait.h>
     12#include <time.h>
     13#include <unistd.h>
     14#include <string.h>
     15
     16#include "log.h"
     17#include "timens.h"
     18
     19#define OFFSET (36000)
     20
     21int main(int argc, char *argv[])
     22{
     23	struct timespec now, tst;
     24	int status, i;
     25	pid_t pid;
     26
     27	if (argc > 1) {
     28		if (sscanf(argv[1], "%ld", &now.tv_sec) != 1)
     29			return pr_perror("sscanf");
     30
     31		for (i = 0; i < 2; i++) {
     32			_gettime(CLOCK_MONOTONIC, &tst, i);
     33			if (abs(tst.tv_sec - now.tv_sec) > 5)
     34				return pr_fail("%ld %ld\n", now.tv_sec, tst.tv_sec);
     35		}
     36		return 0;
     37	}
     38
     39	nscheck();
     40
     41	ksft_set_plan(1);
     42
     43	clock_gettime(CLOCK_MONOTONIC, &now);
     44
     45	if (unshare_timens())
     46		return 1;
     47
     48	if (_settime(CLOCK_MONOTONIC, OFFSET))
     49		return 1;
     50
     51	for (i = 0; i < 2; i++) {
     52		_gettime(CLOCK_MONOTONIC, &tst, i);
     53		if (abs(tst.tv_sec - now.tv_sec) > 5)
     54			return pr_fail("%ld %ld\n",
     55					now.tv_sec, tst.tv_sec);
     56	}
     57
     58	if (argc > 1)
     59		return 0;
     60
     61	pid = fork();
     62	if (pid < 0)
     63		return pr_perror("fork");
     64
     65	if (pid == 0) {
     66		char now_str[64];
     67		char *cargv[] = {"exec", now_str, NULL};
     68		char *cenv[] = {NULL};
     69
     70		/* Check that a child process is in the new timens. */
     71		for (i = 0; i < 2; i++) {
     72			_gettime(CLOCK_MONOTONIC, &tst, i);
     73			if (abs(tst.tv_sec - now.tv_sec - OFFSET) > 5)
     74				return pr_fail("%ld %ld\n",
     75						now.tv_sec + OFFSET, tst.tv_sec);
     76		}
     77
     78		/* Check for proper vvar offsets after execve. */
     79		snprintf(now_str, sizeof(now_str), "%ld", now.tv_sec + OFFSET);
     80		execve("/proc/self/exe", cargv, cenv);
     81		return pr_perror("execve");
     82	}
     83
     84	if (waitpid(pid, &status, 0) != pid)
     85		return pr_perror("waitpid");
     86
     87	if (status)
     88		ksft_exit_fail();
     89
     90	ksft_test_result_pass("exec\n");
     91	ksft_exit_pass();
     92	return 0;
     93}