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