brintos

brintos / linux-shallow public Read only

0
0
Text · 2.6 KiB · 60ab197 Raw
130 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_NEWNET) points to new /proc/net content even18 * if old one is in dcache.19 *20 * FIXME /proc/net/unix is under CONFIG_UNIX which can be disabled.21 */22#undef NDEBUG23#include <assert.h>24#include <errno.h>25#include <sched.h>26#include <signal.h>27#include <stdio.h>28#include <stdlib.h>29#include <string.h>30#include <unistd.h>31#include <sys/types.h>32#include <sys/stat.h>33#include <fcntl.h>34#include <sys/socket.h>35 36static pid_t pid = -1;37 38static void f(void)39{40	if (pid > 0) {41		kill(pid, SIGTERM);42	}43}44 45int main(void)46{47	int fd[2];48	char _ = 0;49	int nsfd;50 51	atexit(f);52 53	/* Check for priviledges and syscall availability straight away. */54	if (unshare(CLONE_NEWNET) == -1) {55		if (errno == ENOSYS || errno == EPERM) {56			return 4;57		}58		return 1;59	}60	/* Distinguisher between two otherwise empty net namespaces. */61	if (socket(AF_UNIX, SOCK_STREAM, 0) == -1) {62		return 1;63	}64 65	if (pipe(fd) == -1) {66		return 1;67	}68 69	pid = fork();70	if (pid == -1) {71		return 1;72	}73 74	if (pid == 0) {75		if (unshare(CLONE_NEWNET) == -1) {76			return 1;77		}78 79		if (write(fd[1], &_, 1) != 1) {80			return 1;81		}82 83		pause();84 85		return 0;86	}87 88	if (read(fd[0], &_, 1) != 1) {89		return 1;90	}91 92	{93		char buf[64];94		snprintf(buf, sizeof(buf), "/proc/%u/ns/net", pid);95		nsfd = open(buf, O_RDONLY);96		if (nsfd == -1) {97			return 1;98		}99	}100 101	/* Reliably pin dentry into dcache. */102	(void)open("/proc/net/unix", O_RDONLY);103 104	if (setns(nsfd, CLONE_NEWNET) == -1) {105		return 1;106	}107 108	kill(pid, SIGTERM);109	pid = 0;110 111	{112		char buf[4096];113		ssize_t rv;114		int fd;115 116		fd = open("/proc/net/unix", O_RDONLY);117		if (fd == -1) {118			return 1;119		}120 121#define S "Num       RefCount Protocol Flags    Type St Inode Path\n"122		rv = read(fd, buf, sizeof(buf));123 124		assert(rv == strlen(S));125		assert(memcmp(buf, S, strlen(S)) == 0);126	}127 128	return 0;129}130