root/tools/testing/selftests/proc/setns-sysvipc.c

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

DEFINITIONS

This source file includes following definitions.
  1. f
  2. main

   1 /*
   2  * Copyright © 2019 Alexey Dobriyan <adobriyan@gmail.com>
   3  *
   4  * Permission to use, copy, modify, and distribute this software for any
   5  * purpose with or without fee is hereby granted, provided that the above
   6  * copyright notice and this permission notice appear in all copies.
   7  *
   8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14  * 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 even
  18  * if old one is in dcache.
  19  */
  20 #undef NDEBUG
  21 #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 
  35 static pid_t pid = -1;
  36 
  37 static void f(void)
  38 {
  39         if (pid > 0) {
  40                 kill(pid, SIGTERM);
  41         }
  42 }
  43 
  44 int 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 }

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