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