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

owner.c (2022B)


      1// SPDX-License-Identifier: GPL-2.0
      2#define _GNU_SOURCE
      3#include <sched.h>
      4#include <unistd.h>
      5#include <stdio.h>
      6#include <stdlib.h>
      7#include <signal.h>
      8#include <errno.h>
      9#include <sys/types.h>
     10#include <sys/stat.h>
     11#include <fcntl.h>
     12#include <sys/ioctl.h>
     13#include <sys/prctl.h>
     14#include <sys/wait.h>
     15
     16#define NSIO    0xb7
     17#define NS_GET_USERNS   _IO(NSIO, 0x1)
     18
     19#define pr_err(fmt, ...) \
     20		({ \
     21			fprintf(stderr, "%s:%d:" fmt ": %m\n", \
     22				__func__, __LINE__, ##__VA_ARGS__); \
     23			1; \
     24		})
     25
     26int main(int argc, char *argvp[])
     27{
     28	int pfd[2], ns, uns, init_uns;
     29	struct stat st1, st2;
     30	char path[128];
     31	pid_t pid;
     32	char c;
     33
     34	if (pipe(pfd))
     35		return 1;
     36
     37	pid = fork();
     38	if (pid < 0)
     39		return pr_err("fork");
     40	if (pid == 0) {
     41		prctl(PR_SET_PDEATHSIG, SIGKILL);
     42		if (unshare(CLONE_NEWUTS | CLONE_NEWUSER))
     43			return pr_err("unshare");
     44		close(pfd[0]);
     45		close(pfd[1]);
     46		while (1)
     47			sleep(1);
     48		return 0;
     49	}
     50	close(pfd[1]);
     51	if (read(pfd[0], &c, 1) != 0)
     52		return pr_err("Unable to read from pipe");
     53	close(pfd[0]);
     54
     55	snprintf(path, sizeof(path), "/proc/%d/ns/uts", pid);
     56	ns = open(path, O_RDONLY);
     57	if (ns < 0)
     58		return pr_err("Unable to open %s", path);
     59
     60	uns = ioctl(ns, NS_GET_USERNS);
     61	if (uns < 0)
     62		return pr_err("Unable to get an owning user namespace");
     63
     64	if (fstat(uns, &st1))
     65		return pr_err("fstat");
     66
     67	snprintf(path, sizeof(path), "/proc/%d/ns/user", pid);
     68	if (stat(path, &st2))
     69		return pr_err("stat");
     70
     71	if (st1.st_ino != st2.st_ino)
     72		return pr_err("NS_GET_USERNS returned a wrong namespace");
     73
     74	init_uns = ioctl(uns, NS_GET_USERNS);
     75	if (uns < 0)
     76		return pr_err("Unable to get an owning user namespace");
     77
     78	if (ioctl(init_uns, NS_GET_USERNS) >= 0 || errno != EPERM)
     79		return pr_err("Don't get EPERM");
     80
     81	if (unshare(CLONE_NEWUSER))
     82		return pr_err("unshare");
     83
     84	if (ioctl(ns, NS_GET_USERNS) >= 0 || errno != EPERM)
     85		return pr_err("Don't get EPERM");
     86	if (ioctl(init_uns, NS_GET_USERNS) >= 0 || errno != EPERM)
     87		return pr_err("Don't get EPERM");
     88
     89	kill(pid, SIGKILL);
     90	wait(NULL);
     91	return 0;
     92}