xref: /netbsd-src/external/gpl3/gdb/dist/gdb/nat/linux-namespaces.c (revision d909946ca08dceb44d7d0f22ec9488679695d976)
1 /* Linux namespaces(7) support.
2 
3    Copyright (C) 2015 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include "common-defs.h"
21 #include "nat/linux-namespaces.h"
22 #include "filestuff.h"
23 #include <fcntl.h>
24 #include <sys/syscall.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <sys/socket.h>
28 #include "gdb_wait.h"
29 #include <signal.h>
30 #include <sched.h>
31 
32 /* See nat/linux-namespaces.h.  */
33 int debug_linux_namespaces;
34 
35 /* Handle systems without setns.  */
36 
37 static inline int
38 do_setns (int fd, int nstype)
39 {
40 #ifdef HAVE_SETNS
41   return setns (fd, nstype);
42 #elif defined __NR_setns
43   return syscall (__NR_setns, fd, nstype);
44 #else
45   errno = ENOSYS;
46   return -1;
47 #endif
48 }
49 
50 /* Handle systems without MSG_CMSG_CLOEXEC.  */
51 
52 #ifndef MSG_CMSG_CLOEXEC
53 #define MSG_CMSG_CLOEXEC 0
54 #endif
55 
56 /* A Linux namespace.  */
57 
58 struct linux_ns
59 {
60   /* Filename of this namespace's entries in /proc/PID/ns.  */
61   const char *filename;
62 
63   /* Nonzero if this object has been initialized.  */
64   int initialized;
65 
66   /* Nonzero if this namespace is supported on this system.  */
67   int supported;
68 
69   /* ID of the namespace the calling process is in, used to
70      see if other processes share the namespace.  The code in
71      this file assumes that the calling process never changes
72      namespace.  */
73   ino_t id;
74 };
75 
76 /* Return the absolute filename of process PID's /proc/PID/ns
77    entry for namespace NS.  The returned value persists until
78    this function is next called.  */
79 
80 static const char *
81 linux_ns_filename (struct linux_ns *ns, int pid)
82 {
83   static char filename[PATH_MAX];
84 
85   gdb_assert (pid > 0);
86   xsnprintf (filename, sizeof (filename), "/proc/%d/ns/%s", pid,
87 	     ns->filename);
88 
89   return filename;
90 }
91 
92 /* Return a representation of the caller's TYPE namespace, or
93    NULL if TYPE namespaces are not supported on this system.  */
94 
95 static struct linux_ns *
96 linux_ns_get_namespace (enum linux_ns_type type)
97 {
98   static struct linux_ns namespaces[NUM_LINUX_NS_TYPES] =
99     {
100       { "ipc" },
101       { "mnt" },
102       { "net" },
103       { "pid" },
104       { "user" },
105       { "uts" },
106     };
107   struct linux_ns *ns;
108 
109   gdb_assert (type >= 0 && type < NUM_LINUX_NS_TYPES);
110   ns = &namespaces[type];
111 
112   if (!ns->initialized)
113     {
114       struct stat sb;
115 
116       if (stat (linux_ns_filename (ns, getpid ()), &sb) == 0)
117 	{
118 	  ns->id = sb.st_ino;
119 
120 	  ns->supported = 1;
121 	}
122 
123       ns->initialized = 1;
124     }
125 
126   return ns->supported ? ns : NULL;
127 }
128 
129 /* See nat/linux-namespaces.h.  */
130 
131 int
132 linux_ns_same (pid_t pid, enum linux_ns_type type)
133 {
134   struct linux_ns *ns = linux_ns_get_namespace (type);
135   const char *filename;
136   struct stat sb;
137 
138   /* If the kernel does not support TYPE namespaces then there's
139      effectively only one TYPE namespace that all processes on
140      the system share.  */
141   if (ns == NULL)
142     return 1;
143 
144   /* Stat PID's TYPE namespace entry to get the namespace ID.  This
145      might fail if the process died, or if we don't have the right
146      permissions (though we should be attached by this time so this
147      seems unlikely).  In any event, we can't make any decisions and
148      must throw.  */
149   filename = linux_ns_filename (ns, pid);
150   if (stat (filename, &sb) != 0)
151     perror_with_name (filename);
152 
153   return sb.st_ino == ns->id;
154 }
155 
156 /* We need to use setns(2) to handle filesystem access in mount
157    namespaces other than our own, but this isn't permitted for
158    multithreaded processes.  GDB is multithreaded when compiled
159    with Guile support, and may become multithreaded if compiled
160    with Python support.  We deal with this by spawning a single-
161    threaded helper process to access mount namespaces other than
162    our own.
163 
164    The helper process is started the first time a call to setns
165    is required.  The main process (GDB or gdbserver) communicates
166    with the helper via sockets, passing file descriptors where
167    necessary using SCM_RIGHTS.  Once started the helper process
168    runs until the main process terminates; when this happens the
169    helper will receive socket errors, notice that its parent died,
170    and exit accordingly (see mnsh_maybe_mourn_peer).
171 
172    The protocol is that the main process sends a request in a
173    single message, and the helper replies to every message it
174    receives with a single-message response.  If the helper
175    receives a message it does not understand it will reply with
176    a MNSH_MSG_ERROR message.  The main process checks all
177    responses it receives with gdb_assert, so if the main process
178    receives something unexpected (which includes MNSH_MSG_ERROR)
179    the main process will call internal_error.
180 
181    For avoidance of doubt, if the helper process receives a
182    message it doesn't handle it will reply with MNSH_MSG_ERROR.
183    If the main process receives MNSH_MSG_ERROR at any time then
184    it will call internal_error.  If internal_error causes the
185    main process to exit, the helper will notice this and also
186    exit.  The helper will not exit until the main process
187    terminates, so if the user continues through internal_error
188    the helper will still be there awaiting requests from the
189    main process.
190 
191    Messages in both directions have the following payload:
192 
193    - TYPE (enum mnsh_msg_type, always sent) - the message type.
194    - INT1 and
195    - INT2 (int, always sent, though not always used) - two
196            values whose meaning is message-type-dependent.
197 	   See enum mnsh_msg_type documentation below.
198    - FD (int, optional, sent using SCM_RIGHTS) - an open file
199          descriptor.
200    - BUF (unstructured data, optional) - some data with message-
201           type-dependent meaning.
202 
203    Note that the helper process is the child of a call to fork,
204    so all code in the helper must be async-signal-safe.  */
205 
206 /* Mount namespace helper message types.  */
207 
208 enum mnsh_msg_type
209   {
210     /* A communication error occurred.  Receipt of this message
211        by either end will cause an assertion failure in the main
212        process.  */
213     MNSH_MSG_ERROR,
214 
215     /* Requests, sent from the main process to the helper.  */
216 
217     /* A request that the helper call setns.  Arguments should
218        be passed in FD and INT1.  Helper should respond with a
219        MNSH_RET_INT.  */
220     MNSH_REQ_SETNS,
221 
222     /* A request that the helper call open.  Arguments should
223        be passed in BUF, INT1 and INT2.  The filename (in BUF)
224        should include a terminating NUL character.  The helper
225        should respond with a MNSH_RET_FD.  */
226     MNSH_REQ_OPEN,
227 
228     /* A request that the helper call unlink.  The single
229        argument (the filename) should be passed in BUF, and
230        should include a terminating NUL character.  The helper
231        should respond with a MNSH_RET_INT.  */
232     MNSH_REQ_UNLINK,
233 
234     /* A request that the helper call readlink.  The single
235        argument (the filename) should be passed in BUF, and
236        should include a terminating NUL character.  The helper
237        should respond with a MNSH_RET_INTSTR.  */
238     MNSH_REQ_READLINK,
239 
240     /* Responses, sent to the main process from the helper.  */
241 
242     /* Return an integer in INT1 and errno in INT2.  */
243     MNSH_RET_INT,
244 
245     /* Return a file descriptor in FD if one was opened or an
246        integer in INT1 otherwise.  Return errno in INT2.  */
247     MNSH_RET_FD,
248 
249     /* Return an integer in INT1, errno in INT2, and optionally
250        some data in BUF.  */
251     MNSH_RET_INTSTR,
252   };
253 
254 /* Print a string representation of a message using debug_printf.
255    This function is not async-signal-safe so should never be
256    called from the helper.  */
257 
258 static void
259 mnsh_debug_print_message (enum mnsh_msg_type type,
260 			  int fd, int int1, int int2,
261 			  const void *buf, int bufsiz)
262 {
263   gdb_byte *c = (gdb_byte *) buf;
264   gdb_byte *cl = c + bufsiz;
265 
266   switch (type)
267     {
268     case MNSH_MSG_ERROR:
269       debug_printf ("ERROR");
270       break;
271 
272     case MNSH_REQ_SETNS:
273       debug_printf ("SETNS");
274       break;
275 
276     case MNSH_REQ_OPEN:
277       debug_printf ("OPEN");
278       break;
279 
280     case MNSH_REQ_UNLINK:
281       debug_printf ("UNLINK");
282       break;
283 
284     case MNSH_REQ_READLINK:
285       debug_printf ("READLINK");
286       break;
287 
288     case MNSH_RET_INT:
289       debug_printf ("INT");
290       break;
291 
292     case MNSH_RET_FD:
293       debug_printf ("FD");
294       break;
295 
296     case MNSH_RET_INTSTR:
297       debug_printf ("INTSTR");
298       break;
299 
300     default:
301       debug_printf ("unknown-packet-%d", type);
302     }
303 
304   debug_printf (" %d %d %d \"", fd, int1, int2);
305 
306   for (; c < cl; c++)
307     debug_printf (*c >= ' ' && *c <= '~' ? "%c" : "\\%o", *c);
308 
309   debug_printf ("\"");
310 }
311 
312 /* Forward declaration.  */
313 
314 static void mnsh_maybe_mourn_peer (void);
315 
316 /* Send a message.  The argument SOCK is the file descriptor of the
317    sending socket, the other arguments are the payload to send.
318    Return the number of bytes sent on success.  Return -1 on failure
319    and set errno appropriately.  This function is called by both the
320    main process and the helper so must be async-signal-safe.  */
321 
322 static ssize_t
323 mnsh_send_message (int sock, enum mnsh_msg_type type,
324 		   int fd, int int1, int int2,
325 		   const void *buf, int bufsiz)
326 {
327   struct msghdr msg;
328   struct iovec iov[4];
329   char fdbuf[CMSG_SPACE (sizeof (fd))];
330   ssize_t size;
331 
332   /* Build the basic TYPE, INT1, INT2 message.  */
333   memset (&msg, 0, sizeof (msg));
334   msg.msg_iov = iov;
335 
336   iov[0].iov_base = &type;
337   iov[0].iov_len = sizeof (type);
338   iov[1].iov_base = &int1;
339   iov[1].iov_len = sizeof (int1);
340   iov[2].iov_base = &int2;
341   iov[2].iov_len = sizeof (int2);
342 
343   msg.msg_iovlen = 3;
344 
345   /* Append BUF if supplied.  */
346   if (buf != NULL && bufsiz > 0)
347     {
348       iov[3].iov_base = alloca (bufsiz);
349       memcpy (iov[3].iov_base, buf, bufsiz);
350       iov[3].iov_len = bufsiz;
351 
352       msg.msg_iovlen ++;
353     }
354 
355   /* Attach FD if supplied.  */
356   if (fd >= 0)
357     {
358       struct cmsghdr *cmsg;
359 
360       msg.msg_control = fdbuf;
361       msg.msg_controllen = sizeof (fdbuf);
362 
363       cmsg = CMSG_FIRSTHDR (&msg);
364       cmsg->cmsg_level = SOL_SOCKET;
365       cmsg->cmsg_type = SCM_RIGHTS;
366       cmsg->cmsg_len = CMSG_LEN (sizeof (int));
367 
368       memcpy (CMSG_DATA (cmsg), &fd, sizeof (int));
369 
370       msg.msg_controllen = cmsg->cmsg_len;
371     }
372 
373   /* Send the message.  */
374   size = sendmsg (sock, &msg, 0);
375 
376   if (size < 0)
377     mnsh_maybe_mourn_peer ();
378 
379   if (debug_linux_namespaces)
380     {
381       debug_printf ("mnsh: send: ");
382       mnsh_debug_print_message (type, fd, int1, int2, buf, bufsiz);
383       debug_printf (" -> %s\n", pulongest (size));
384     }
385 
386   return size;
387 }
388 
389 /* Receive a message.  The argument SOCK is the file descriptor of
390    the receiving socket, the other arguments point to storage for
391    the received payload.  Returns the number of bytes stored into
392    BUF on success, which may be zero in the event no BUF was sent.
393    Return -1 on failure and set errno appropriately.  This function
394    is called from both the main process and the helper and must be
395    async-signal-safe.  */
396 
397 static ssize_t
398 mnsh_recv_message (int sock, enum mnsh_msg_type *type,
399 		   int *fd, int *int1, int *int2,
400 		   void *buf, int bufsiz)
401 {
402   struct msghdr msg;
403   struct iovec iov[4];
404   char fdbuf[CMSG_SPACE (sizeof (*fd))];
405   struct cmsghdr *cmsg;
406   ssize_t size, fixed_size;
407   int i;
408 
409   /* Build the message to receive data into.  */
410   memset (&msg, 0, sizeof (msg));
411   msg.msg_iov = iov;
412 
413   iov[0].iov_base = type;
414   iov[0].iov_len = sizeof (*type);
415   iov[1].iov_base = int1;
416   iov[1].iov_len = sizeof (*int1);
417   iov[2].iov_base = int2;
418   iov[2].iov_len = sizeof (*int2);
419   iov[3].iov_base = buf;
420   iov[3].iov_len = bufsiz;
421 
422   msg.msg_iovlen = 4;
423 
424   for (fixed_size = i = 0; i < msg.msg_iovlen - 1; i++)
425     fixed_size += iov[i].iov_len;
426 
427   msg.msg_control = fdbuf;
428   msg.msg_controllen = sizeof (fdbuf);
429 
430   /* Receive the message.  */
431   size = recvmsg (sock, &msg, MSG_CMSG_CLOEXEC);
432   if (size < 0)
433     {
434       if (debug_linux_namespaces)
435 	debug_printf ("namespace-helper: recv failed (%s)\n",
436 		      pulongest (size));
437 
438       mnsh_maybe_mourn_peer ();
439 
440       return size;
441     }
442 
443   /* Check for truncation.  */
444   if (size < fixed_size || (msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC)))
445     {
446       if (debug_linux_namespaces)
447 	debug_printf ("namespace-helper: recv truncated (%s 0x%x)\n",
448 		      pulongest (size), msg.msg_flags);
449 
450       mnsh_maybe_mourn_peer ();
451 
452       errno = EBADMSG;
453       return -1;
454     }
455 
456   /* Unpack the file descriptor if supplied.  */
457   cmsg = CMSG_FIRSTHDR (&msg);
458   if (cmsg != NULL
459       && cmsg->cmsg_len == CMSG_LEN (sizeof (int))
460       && cmsg->cmsg_level == SOL_SOCKET
461       && cmsg->cmsg_type == SCM_RIGHTS)
462     memcpy (fd, CMSG_DATA (cmsg), sizeof (int));
463   else
464     *fd = -1;
465 
466   if (debug_linux_namespaces)
467     {
468       debug_printf ("mnsh: recv: ");
469       mnsh_debug_print_message (*type, *fd, *int1, *int2, buf,
470 				size - fixed_size);
471       debug_printf ("\n");
472     }
473 
474   /* Return the number of bytes of data in BUF.  */
475   return size - fixed_size;
476 }
477 
478 /* Shortcuts for returning results from the helper.  */
479 
480 #define mnsh_return_int(sock, result, error) \
481   mnsh_send_message (sock, MNSH_RET_INT, -1, result, error, NULL, 0)
482 
483 #define mnsh_return_fd(sock, fd, error) \
484   mnsh_send_message (sock, MNSH_RET_FD, \
485 		     (fd) < 0 ? -1 : (fd), \
486 		     (fd) < 0 ? (fd) : 0, \
487 		     error, NULL, 0)
488 
489 #define mnsh_return_intstr(sock, result, buf, bufsiz, error) \
490   mnsh_send_message (sock, MNSH_RET_INTSTR, -1, result, error, \
491 		     buf, bufsiz)
492 
493 /* Handle a MNSH_REQ_SETNS message.  Must be async-signal-safe.  */
494 
495 static ssize_t
496 mnsh_handle_setns (int sock, int fd, int nstype)
497 {
498   int result = do_setns (fd, nstype);
499 
500   return mnsh_return_int (sock, result, errno);
501 }
502 
503 /* Handle a MNSH_REQ_OPEN message.  Must be async-signal-safe.  */
504 
505 static ssize_t
506 mnsh_handle_open (int sock, const char *filename,
507 		  int flags, mode_t mode)
508 {
509   int fd = gdb_open_cloexec (filename, flags, mode);
510   ssize_t result = mnsh_return_fd (sock, fd, errno);
511 
512   if (fd >= 0)
513     close (fd);
514 
515   return result;
516 }
517 
518 /* Handle a MNSH_REQ_UNLINK message.  Must be async-signal-safe.  */
519 
520 static ssize_t
521 mnsh_handle_unlink (int sock, const char *filename)
522 {
523   int result = unlink (filename);
524 
525   return mnsh_return_int (sock, result, errno);
526 }
527 
528 /* Handle a MNSH_REQ_READLINK message.  Must be async-signal-safe.  */
529 
530 static ssize_t
531 mnsh_handle_readlink (int sock, const char *filename)
532 {
533   char buf[PATH_MAX];
534   int len = readlink (filename, buf, sizeof (buf));
535 
536   return mnsh_return_intstr (sock, len,
537 			     buf, len < 0 ? 0 : len,
538 			     errno);
539 }
540 
541 /* The helper process.  Never returns.  Must be async-signal-safe.  */
542 
543 static void mnsh_main (int sock) ATTRIBUTE_NORETURN;
544 
545 static void
546 mnsh_main (int sock)
547 {
548   while (1)
549     {
550       enum mnsh_msg_type type;
551       int fd, int1, int2;
552       char buf[PATH_MAX];
553       ssize_t size, response = -1;
554 
555       size = mnsh_recv_message (sock, &type,
556 				&fd, &int1, &int2,
557 				buf, sizeof (buf));
558 
559       if (size >= 0 && size < sizeof (buf))
560 	{
561 	  switch (type)
562 	    {
563 	    case MNSH_REQ_SETNS:
564 	      if (fd > 0)
565 		response = mnsh_handle_setns (sock, fd, int1);
566 	      break;
567 
568 	    case MNSH_REQ_OPEN:
569 	      if (size > 0 && buf[size - 1] == '\0')
570 		response = mnsh_handle_open (sock, buf, int1, int2);
571 	      break;
572 
573 	    case MNSH_REQ_UNLINK:
574 	      if (size > 0 && buf[size - 1] == '\0')
575 		response = mnsh_handle_unlink (sock, buf);
576 	      break;
577 
578 	    case MNSH_REQ_READLINK:
579 	      if (size > 0 && buf[size - 1] == '\0')
580 		response = mnsh_handle_readlink (sock, buf);
581 	      break;
582 
583 	    default:
584 	      break; /* Handled below.  */
585 	    }
586 	}
587 
588       /* Close any file descriptors we were passed.  */
589       if (fd >= 0)
590 	close (fd);
591 
592       /* Can't handle this message, bounce it back.  */
593       if (response < 0)
594 	{
595 	  if (size < 0)
596 	    size = 0;
597 
598 	  mnsh_send_message (sock, MNSH_MSG_ERROR,
599 			     -1, int1, int2, buf, size);
600 	}
601     }
602 }
603 
604 /* The mount namespace helper process.  */
605 
606 struct linux_mnsh
607 {
608   /* PID of helper.  */
609   pid_t pid;
610 
611   /* Socket for communication.  */
612   int sock;
613 
614   /* ID of the mount namespace the helper is currently in.  */
615   ino_t nsid;
616 };
617 
618 /* In the helper process this is set to the PID of the process that
619    created the helper (i.e. GDB or gdbserver).  In the main process
620    this is set to zero.  Used by mnsh_maybe_mourn_peer.  */
621 static int mnsh_creator_pid = 0;
622 
623 /* Return an object representing the mount namespace helper process.
624    If no mount namespace helper process has been started then start
625    one.  Return NULL if no mount namespace helper process could be
626    started.  */
627 
628 static struct linux_mnsh *
629 linux_mntns_get_helper (void)
630 {
631   static struct linux_mnsh *helper = NULL;
632 
633   if (helper == NULL)
634     {
635       static struct linux_mnsh h;
636       struct linux_ns *ns;
637       pid_t helper_creator = getpid ();
638       int sv[2];
639 
640       ns = linux_ns_get_namespace (LINUX_NS_MNT);
641       if (ns == NULL)
642 	return NULL;
643 
644       if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, sv) < 0)
645 	return NULL;
646 
647       h.pid = fork ();
648       if (h.pid < 0)
649 	{
650 	  int saved_errno = errno;
651 
652 	  close (sv[0]);
653 	  close (sv[1]);
654 
655 	  errno = saved_errno;
656 	  return NULL;
657 	}
658 
659       if (h.pid == 0)
660 	{
661 	  /* Child process.  */
662 	  close (sv[0]);
663 
664 	  mnsh_creator_pid = helper_creator;
665 
666 	  /* Debug printing isn't async-signal-safe.  */
667 	  debug_linux_namespaces = 0;
668 
669 	  mnsh_main (sv[1]);
670 	}
671 
672       /* Parent process.  */
673       close (sv[1]);
674 
675       helper = &h;
676       helper->sock = sv[0];
677       helper->nsid = ns->id;
678 
679       if (debug_linux_namespaces)
680 	debug_printf ("Started mount namespace helper process %d\n",
681 		      helper->pid);
682     }
683 
684   return helper;
685 }
686 
687 /* Check whether the other process died and act accordingly.  Called
688    whenever a socket error occurs, from both the main process and the
689    helper.  Must be async-signal-safe when called from the helper.  */
690 
691 static void
692 mnsh_maybe_mourn_peer (void)
693 {
694   if (mnsh_creator_pid != 0)
695     {
696       /* We're in the helper.  Check if our current parent is the
697 	 process that started us.  If it isn't, then our original
698 	 parent died and we've been reparented.  Exit immediately
699 	 if that's the case.  */
700       if (getppid () != mnsh_creator_pid)
701 	_exit (0);
702     }
703   else
704     {
705       /* We're in the main process.  */
706 
707       struct linux_mnsh *helper = linux_mntns_get_helper ();
708       int status;
709       pid_t pid;
710 
711       if (helper->pid < 0)
712 	{
713 	  /* We already mourned it.  */
714 	  return;
715 	}
716 
717       pid = waitpid (helper->pid, &status, WNOHANG);
718       if (pid == 0)
719 	{
720 	  /* The helper is still alive.  */
721 	  return;
722 	}
723       else if (pid == -1)
724 	{
725 	  if (errno == ECHILD)
726 	    warning (_("mount namespace helper vanished?"));
727 	  else
728 	    internal_warning (__FILE__, __LINE__,
729 			      _("unhandled error %d"), errno);
730 	}
731       else if (pid == helper->pid)
732 	{
733 	  if (WIFEXITED (status))
734 	    warning (_("mount namespace helper exited with status %d"),
735 		     WEXITSTATUS (status));
736 	  else if (WIFSIGNALED (status))
737 	    warning (_("mount namespace helper killed by signal %d"),
738 		     WTERMSIG (status));
739 	  else
740 	    internal_warning (__FILE__, __LINE__,
741 			      _("unhandled status %d"), status);
742 	}
743       else
744 	internal_warning (__FILE__, __LINE__,
745 			  _("unknown pid %d"), pid);
746 
747       /* Something unrecoverable happened.  */
748       helper->pid = -1;
749     }
750 }
751 
752 /* Shortcuts for sending messages to the helper.  */
753 
754 #define mnsh_send_setns(helper, fd, nstype) \
755   mnsh_send_message (helper->sock, MNSH_REQ_SETNS, fd, nstype, 0, \
756 		     NULL, 0)
757 
758 #define mnsh_send_open(helper, filename, flags, mode) \
759   mnsh_send_message (helper->sock, MNSH_REQ_OPEN, -1, flags, mode, \
760     		     filename, strlen (filename) + 1)
761 
762 #define mnsh_send_unlink(helper, filename) \
763   mnsh_send_message (helper->sock, MNSH_REQ_UNLINK, -1, 0, 0, \
764     		     filename, strlen (filename) + 1)
765 
766 #define mnsh_send_readlink(helper, filename) \
767   mnsh_send_message (helper->sock, MNSH_REQ_READLINK, -1, 0, 0, \
768     		     filename, strlen (filename) + 1)
769 
770 /* Receive a message from the helper.  Issue an assertion failure if
771    the message isn't a correctly-formatted MNSH_RET_INT.  Set RESULT
772    and ERROR and return 0 on success.  Set errno and return -1 on
773    failure.  */
774 
775 static int
776 mnsh_recv_int (struct linux_mnsh *helper, int *result, int *error)
777 {
778   enum mnsh_msg_type type;
779   char buf[PATH_MAX];
780   ssize_t size;
781   int fd;
782 
783   size = mnsh_recv_message (helper->sock, &type, &fd,
784 			    result, error,
785 			    buf, sizeof (buf));
786   if (size < 0)
787     return -1;
788 
789   gdb_assert (type == MNSH_RET_INT);
790   gdb_assert (fd == -1);
791   gdb_assert (size == 0);
792 
793   return 0;
794 }
795 
796 /* Receive a message from the helper.  Issue an assertion failure if
797    the message isn't a correctly-formatted MNSH_RET_FD.  Set FD and
798    ERROR and return 0 on success.  Set errno and return -1 on
799    failure.  */
800 
801 static int
802 mnsh_recv_fd (struct linux_mnsh *helper, int *fd, int *error)
803 {
804   enum mnsh_msg_type type;
805   char buf[PATH_MAX];
806   ssize_t size;
807   int result;
808 
809   size = mnsh_recv_message (helper->sock, &type, fd,
810 			    &result, error,
811 			    buf, sizeof (buf));
812   if (size < 0)
813     return -1;
814 
815   gdb_assert (type == MNSH_RET_FD);
816   gdb_assert (size == 0);
817 
818   if (*fd < 0)
819     {
820       gdb_assert (result < 0);
821       *fd = result;
822     }
823 
824   return 0;
825 }
826 
827 /* Receive a message from the helper.  Issue an assertion failure if
828    the message isn't a correctly-formatted MNSH_RET_INTSTR.  Set
829    RESULT and ERROR and optionally store data in BUF, then return
830    the number of bytes stored in BUF on success (this may be zero).
831    Set errno and return -1 on error.  */
832 
833 static ssize_t
834 mnsh_recv_intstr (struct linux_mnsh *helper,
835 		  int *result, int *error,
836 		  void *buf, int bufsiz)
837 {
838   enum mnsh_msg_type type;
839   ssize_t size;
840   int fd;
841 
842   size = mnsh_recv_message (helper->sock, &type, &fd,
843 			    result, error,
844 			    buf, bufsiz);
845 
846   if (size < 0)
847     return -1;
848 
849   gdb_assert (type == MNSH_RET_INTSTR);
850   gdb_assert (fd == -1);
851 
852   return size;
853 }
854 
855 /* Return values for linux_mntns_access_fs.  */
856 
857 enum mnsh_fs_code
858   {
859     /* Something went wrong, errno is set.  */
860     MNSH_FS_ERROR = -1,
861 
862     /* The main process is in the correct mount namespace.
863        The caller should access the filesystem directly.  */
864     MNSH_FS_DIRECT,
865 
866     /* The helper is in the correct mount namespace.
867        The caller should access the filesystem via the helper.  */
868     MNSH_FS_HELPER
869   };
870 
871 /* Return a value indicating how the caller should access the
872    mount namespace of process PID.  */
873 
874 static enum mnsh_fs_code
875 linux_mntns_access_fs (pid_t pid)
876 {
877   struct cleanup *old_chain;
878   struct linux_ns *ns;
879   struct stat sb;
880   struct linux_mnsh *helper;
881   ssize_t size;
882   int fd, saved_errno;
883 
884   if (pid == getpid ())
885     return MNSH_FS_DIRECT;
886 
887   ns = linux_ns_get_namespace (LINUX_NS_MNT);
888   if (ns == NULL)
889     return MNSH_FS_DIRECT;
890 
891   old_chain = make_cleanup (null_cleanup, NULL);
892 
893   fd = gdb_open_cloexec (linux_ns_filename (ns, pid), O_RDONLY, 0);
894   if (fd < 0)
895     goto error;
896 
897   make_cleanup_close (fd);
898 
899   if (fstat (fd, &sb) != 0)
900     goto error;
901 
902   if (sb.st_ino == ns->id)
903     {
904       do_cleanups (old_chain);
905 
906       return MNSH_FS_DIRECT;
907     }
908 
909   helper = linux_mntns_get_helper ();
910   if (helper == NULL)
911     goto error;
912 
913   if (sb.st_ino != helper->nsid)
914     {
915       int result, error;
916 
917       size = mnsh_send_setns (helper, fd, 0);
918       if (size < 0)
919 	goto error;
920 
921       if (mnsh_recv_int (helper, &result, &error) != 0)
922 	goto error;
923 
924       if (result != 0)
925 	{
926 	  /* ENOSYS indicates that an entire function is unsupported
927 	     (it's not appropriate for our versions of open/unlink/
928 	     readlink to sometimes return with ENOSYS depending on how
929 	     they're called) so we convert ENOSYS to ENOTSUP if setns
930 	     fails.  */
931 	  if (error == ENOSYS)
932 	    error = ENOTSUP;
933 
934 	  errno = error;
935 	  goto error;
936 	}
937 
938       helper->nsid = sb.st_ino;
939     }
940 
941   do_cleanups (old_chain);
942 
943   return MNSH_FS_HELPER;
944 
945 error:
946   saved_errno = errno;
947 
948   do_cleanups (old_chain);
949 
950   errno = saved_errno;
951   return MNSH_FS_ERROR;
952 }
953 
954 /* See nat/linux-namespaces.h.  */
955 
956 int
957 linux_mntns_open_cloexec (pid_t pid, const char *filename,
958 			  int flags, mode_t mode)
959 {
960   enum mnsh_fs_code access = linux_mntns_access_fs (pid);
961   struct linux_mnsh *helper;
962   int fd, error;
963   ssize_t size;
964 
965   if (access == MNSH_FS_ERROR)
966     return -1;
967 
968   if (access == MNSH_FS_DIRECT)
969     return gdb_open_cloexec (filename, flags, mode);
970 
971   gdb_assert (access == MNSH_FS_HELPER);
972 
973   helper = linux_mntns_get_helper ();
974 
975   size = mnsh_send_open (helper, filename, flags, mode);
976   if (size < 0)
977     return -1;
978 
979   if (mnsh_recv_fd (helper, &fd, &error) != 0)
980     return -1;
981 
982   if (fd < 0)
983     errno = error;
984 
985   return fd;
986 }
987 
988 /* See nat/linux-namespaces.h.  */
989 
990 int
991 linux_mntns_unlink (pid_t pid, const char *filename)
992 {
993   enum mnsh_fs_code access = linux_mntns_access_fs (pid);
994   struct linux_mnsh *helper;
995   int ret, error;
996   ssize_t size;
997 
998   if (access == MNSH_FS_ERROR)
999     return -1;
1000 
1001   if (access == MNSH_FS_DIRECT)
1002     return unlink (filename);
1003 
1004   gdb_assert (access == MNSH_FS_HELPER);
1005 
1006   helper = linux_mntns_get_helper ();
1007 
1008   size = mnsh_send_unlink (helper, filename);
1009   if (size < 0)
1010     return -1;
1011 
1012   if (mnsh_recv_int (helper, &ret, &error) != 0)
1013     return -1;
1014 
1015   if (ret != 0)
1016     errno = error;
1017 
1018   return ret;
1019 }
1020 
1021 /* See nat/linux-namespaces.h.  */
1022 
1023 ssize_t
1024 linux_mntns_readlink (pid_t pid, const char *filename,
1025 		      char *buf, size_t bufsiz)
1026 {
1027   enum mnsh_fs_code access = linux_mntns_access_fs (pid);
1028   struct linux_mnsh *helper;
1029   int ret, error;
1030   ssize_t size;
1031 
1032   if (access == MNSH_FS_ERROR)
1033     return -1;
1034 
1035   if (access == MNSH_FS_DIRECT)
1036     return readlink (filename, buf, bufsiz);
1037 
1038   gdb_assert (access == MNSH_FS_HELPER);
1039 
1040   helper = linux_mntns_get_helper ();
1041 
1042   size = mnsh_send_readlink (helper, filename);
1043   if (size < 0)
1044     return -1;
1045 
1046   size = mnsh_recv_intstr (helper, &ret, &error, buf, bufsiz);
1047 
1048   if (size < 0)
1049     {
1050       ret = -1;
1051       errno = error;
1052     }
1053   else
1054     gdb_assert (size == ret);
1055 
1056   return ret;
1057 }
1058