root/tools/testing/selftests/nsfs/owner.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. main

   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 
  26 int 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 }

/* [<][>][^][v][top][bottom][index][help] */