root/tools/testing/selftests/proc/setns-dcache.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_NEWNET) points to new /proc/net content even
  18  * if old one is in dcache.
  19  *
  20  * FIXME /proc/net/unix is under CONFIG_UNIX which can be disabled.
  21  */
  22 #undef NDEBUG
  23 #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 
  36 static pid_t pid = -1;
  37 
  38 static void f(void)
  39 {
  40         if (pid > 0) {
  41                 kill(pid, SIGTERM);
  42         }
  43 }
  44 
  45 int 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 }

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