brintos

brintos / linux-shallow public Read only

0
0
Text · 2.9 KiB · 903890c Raw
134 lines · c
1/*2 * Copyright © 2019 Alexey Dobriyan <adobriyan@gmail.com>3 *4 * Permission to use, copy, modify, and distribute this software for any5 * purpose with or without fee is hereby granted, provided that the above6 * copyright notice and this permission notice appear in all copies.7 *8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.15 */16/*17 * Test that setns(CLONE_NEWIPC) points to new /proc/sysvipc content even18 * if old one is in dcache.19 */20#undef NDEBUG21#include <assert.h>22#include <errno.h>23#include <stdio.h>24#include <sched.h>25#include <signal.h>26#include <stdlib.h>27#include <string.h>28#include <unistd.h>29#include <sys/types.h>30#include <sys/stat.h>31#include <fcntl.h>32#include <sys/ipc.h>33#include <sys/shm.h>34 35static pid_t pid = -1;36 37static void f(void)38{39	if (pid > 0) {40		kill(pid, SIGTERM);41	}42}43 44int main(void)45{46	int fd[2];47	char _ = 0;48	int nsfd;49 50	atexit(f);51 52	/* Check for priviledges and syscall availability straight away. */53	if (unshare(CLONE_NEWIPC) == -1) {54		if (errno == ENOSYS || errno == EPERM) {55			return 4;56		}57		return 1;58	}59	/* Distinguisher between two otherwise empty IPC namespaces. */60	if (shmget(IPC_PRIVATE, 1, IPC_CREAT) == -1) {61		return 1;62	}63 64	if (pipe(fd) == -1) {65		return 1;66	}67 68	pid = fork();69	if (pid == -1) {70		return 1;71	}72 73	if (pid == 0) {74		if (unshare(CLONE_NEWIPC) == -1) {75			return 1;76		}77 78		if (write(fd[1], &_, 1) != 1) {79			return 1;80		}81 82		pause();83 84		return 0;85	}86 87	if (read(fd[0], &_, 1) != 1) {88		return 1;89	}90 91	{92		char buf[64];93		snprintf(buf, sizeof(buf), "/proc/%u/ns/ipc", pid);94		nsfd = open(buf, O_RDONLY);95		if (nsfd == -1) {96			return 1;97		}98	}99 100	/* Reliably pin dentry into dcache. */101	(void)open("/proc/sysvipc/shm", O_RDONLY);102 103	if (setns(nsfd, CLONE_NEWIPC) == -1) {104		return 1;105	}106 107	kill(pid, SIGTERM);108	pid = 0;109 110	{111		char buf[4096];112		ssize_t rv;113		int fd;114 115		fd = open("/proc/sysvipc/shm", O_RDONLY);116		if (fd == -1) {117			return 1;118		}119 120#define S32 "       key      shmid perms       size  cpid  lpid nattch   uid   gid  cuid  cgid      atime      dtime      ctime        rss       swap\n"121#define S64 "       key      shmid perms                  size  cpid  lpid nattch   uid   gid  cuid  cgid      atime      dtime      ctime                   rss                  swap\n"122		rv = read(fd, buf, sizeof(buf));123		if (rv == strlen(S32)) {124			assert(memcmp(buf, S32, strlen(S32)) == 0);125		} else if (rv == strlen(S64)) {126			assert(memcmp(buf, S64, strlen(S64)) == 0);127		} else {128			assert(0);129		}130	}131 132	return 0;133}134