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