Path: blob/master/tools/testing/selftests/filesystems/nsfs/pidns.c
26302 views
// SPDX-License-Identifier: GPL-2.01#define _GNU_SOURCE2#include <sched.h>3#include <unistd.h>4#include <stdio.h>5#include <stdlib.h>6#include <signal.h>7#include <errno.h>8#include <sys/types.h>9#include <sys/stat.h>10#include <fcntl.h>11#include <sys/ioctl.h>12#include <sys/prctl.h>13#include <sys/wait.h>1415#define pr_err(fmt, ...) \16({ \17fprintf(stderr, "%s:%d:" fmt ": %m\n", \18__func__, __LINE__, ##__VA_ARGS__); \191; \20})2122#define NSIO 0xb723#define NS_GET_USERNS _IO(NSIO, 0x1)24#define NS_GET_PARENT _IO(NSIO, 0x2)2526#define __stack_aligned__ __attribute__((aligned(16)))27struct cr_clone_arg {28char stack[128] __stack_aligned__;29char stack_ptr[];30};3132static int child(void *args)33{34prctl(PR_SET_PDEATHSIG, SIGKILL);35while (1)36sleep(1);37exit(0);38}3940int main(int argc, char *argv[])41{42char *ns_strs[] = {"pid", "user"};43char path[] = "/proc/0123456789/ns/pid";44struct cr_clone_arg ca;45struct stat st1, st2;46int ns, pns, i;47pid_t pid;4849pid = clone(child, ca.stack_ptr, CLONE_NEWUSER | CLONE_NEWPID | SIGCHLD, NULL);50if (pid < 0)51return pr_err("clone");5253for (i = 0; i < 2; i++) {54snprintf(path, sizeof(path), "/proc/%d/ns/%s", pid, ns_strs[i]);55ns = open(path, O_RDONLY);56if (ns < 0)57return pr_err("Unable to open %s", path);5859pns = ioctl(ns, NS_GET_PARENT);60if (pns < 0)61return pr_err("Unable to get a parent pidns");6263snprintf(path, sizeof(path), "/proc/self/ns/%s", ns_strs[i]);64if (stat(path, &st2))65return pr_err("Unable to stat %s", path);66if (fstat(pns, &st1))67return pr_err("Unable to stat the parent pidns");68if (st1.st_ino != st2.st_ino)69return pr_err("NS_GET_PARENT returned a wrong namespace");7071if (ioctl(pns, NS_GET_PARENT) >= 0 || errno != EPERM)72return pr_err("Don't get EPERM");73}7475kill(pid, SIGKILL);76wait(NULL);77return 0;78}798081