1 /* 2 * Copyright (c) 2014 The FreeBSD Foundation. 3 * Copyright (C) 2005 David Xu <davidxu@freebsd.org>. 4 * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>. 5 * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. 6 * All rights reserved. 7 * 8 * Portions of this software were developed by Konstantin Belousov 9 * under sponsorship from the FreeBSD Foundation. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice(s), this list of conditions and the following disclaimer as 16 * the first lines of this file unmodified other than the possible 17 * addition of one or more copyright notices. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice(s), this list of conditions and the following disclaimer in 20 * the documentation and/or other materials provided with the 21 * distribution. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY 24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE 27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 32 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 33 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 /* 37 * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> 38 * All rights reserved. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that the following conditions 42 * are met: 43 * 1. Redistributions of source code must retain the above copyright 44 * notice, this list of conditions and the following disclaimer. 45 * 2. Redistributions in binary form must reproduce the above copyright 46 * notice, this list of conditions and the following disclaimer in the 47 * documentation and/or other materials provided with the distribution. 48 * 3. Neither the name of the author nor the names of any co-contributors 49 * may be used to endorse or promote products derived from this software 50 * without specific prior written permission. 51 * 52 * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND 53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * SUCH DAMAGE. 63 * 64 */ 65 66 #include <sys/cdefs.h> 67 __FBSDID("$FreeBSD$"); 68 69 #include "namespace.h" 70 #include <sys/types.h> 71 #include <sys/mman.h> 72 #include <sys/param.h> 73 #include <sys/select.h> 74 #include <sys/signalvar.h> 75 #include <sys/socket.h> 76 #include <sys/stat.h> 77 #include <sys/time.h> 78 #include <sys/uio.h> 79 #include <sys/wait.h> 80 #include <aio.h> 81 #include <dirent.h> 82 #include <errno.h> 83 #include <fcntl.h> 84 #include <poll.h> 85 #include <signal.h> 86 #include <stdarg.h> 87 #include <stdio.h> 88 #include <stdlib.h> 89 #include <string.h> 90 #include <termios.h> 91 #include <unistd.h> 92 #include <pthread.h> 93 #include "un-namespace.h" 94 95 #include "libc_private.h" 96 #include "thr_private.h" 97 98 #ifdef SYSCALL_COMPAT 99 extern int __fcntl_compat(int, int, ...); 100 #endif 101 102 /* 103 * Cancellation behavior: 104 * If thread is canceled, no socket is created. 105 */ 106 static int 107 __thr_accept(int s, struct sockaddr *addr, socklen_t *addrlen) 108 { 109 struct pthread *curthread; 110 int ret; 111 112 curthread = _get_curthread(); 113 _thr_cancel_enter(curthread); 114 ret = __sys_accept(s, addr, addrlen); 115 _thr_cancel_leave(curthread, ret == -1); 116 117 return (ret); 118 } 119 120 /* 121 * Cancellation behavior: 122 * If thread is canceled, no socket is created. 123 */ 124 static int 125 __thr_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) 126 { 127 struct pthread *curthread; 128 int ret; 129 130 curthread = _get_curthread(); 131 _thr_cancel_enter(curthread); 132 ret = __sys_accept4(s, addr, addrlen, flags); 133 _thr_cancel_leave(curthread, ret == -1); 134 135 return (ret); 136 } 137 138 static int 139 __thr_aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct 140 timespec *timeout) 141 { 142 struct pthread *curthread; 143 int ret; 144 145 curthread = _get_curthread(); 146 _thr_cancel_enter(curthread); 147 ret = __sys_aio_suspend(iocbs, niocb, timeout); 148 _thr_cancel_leave(curthread, 1); 149 150 return (ret); 151 } 152 153 /* 154 * Cancellation behavior: 155 * According to manual of close(), the file descriptor is always deleted. 156 * Here, thread is only canceled after the system call, so the file 157 * descriptor is always deleted despite whether the thread is canceled 158 * or not. 159 */ 160 static int 161 __thr_close(int fd) 162 { 163 struct pthread *curthread; 164 int ret; 165 166 curthread = _get_curthread(); 167 _thr_cancel_enter2(curthread, 0); 168 ret = __sys_close(fd); 169 _thr_cancel_leave(curthread, 1); 170 171 return (ret); 172 } 173 174 /* 175 * Cancellation behavior: 176 * If the thread is canceled, connection is not made. 177 */ 178 static int 179 __thr_connect(int fd, const struct sockaddr *name, socklen_t namelen) 180 { 181 struct pthread *curthread; 182 int ret; 183 184 curthread = _get_curthread(); 185 _thr_cancel_enter(curthread); 186 ret = __sys_connect(fd, name, namelen); 187 _thr_cancel_leave(curthread, ret == -1); 188 189 return (ret); 190 } 191 192 193 /* 194 * Cancellation behavior: 195 * If thread is canceled, file is not created. 196 */ 197 static int 198 __thr_creat(const char *path, mode_t mode) 199 { 200 struct pthread *curthread; 201 int ret; 202 203 curthread = _get_curthread(); 204 _thr_cancel_enter(curthread); 205 ret = __libc_creat(path, mode); 206 _thr_cancel_leave(curthread, ret == -1); 207 208 return (ret); 209 } 210 211 /* 212 * Cancellation behavior: 213 * According to specification, only F_SETLKW is a cancellation point. 214 * Thread is only canceled at start, or canceled if the system call 215 * is failure, this means the function does not generate side effect 216 * if it is canceled. 217 */ 218 static int 219 __thr_fcntl(int fd, int cmd, ...) 220 { 221 struct pthread *curthread; 222 int ret; 223 va_list ap; 224 225 curthread = _get_curthread(); 226 va_start(ap, cmd); 227 if (cmd == F_OSETLKW || cmd == F_SETLKW) { 228 _thr_cancel_enter(curthread); 229 #ifdef SYSCALL_COMPAT 230 ret = __fcntl_compat(fd, cmd, va_arg(ap, void *)); 231 #else 232 ret = __sys_fcntl(fd, cmd, va_arg(ap, void *)); 233 #endif 234 _thr_cancel_leave(curthread, ret == -1); 235 } else { 236 #ifdef SYSCALL_COMPAT 237 ret = __fcntl_compat(fd, cmd, va_arg(ap, void *)); 238 #else 239 ret = __sys_fcntl(fd, cmd, va_arg(ap, void *)); 240 #endif 241 } 242 va_end(ap); 243 244 return (ret); 245 } 246 247 /* 248 * Cancellation behavior: 249 * Thread may be canceled after system call. 250 */ 251 static int 252 __thr_fsync(int fd) 253 { 254 struct pthread *curthread; 255 int ret; 256 257 curthread = _get_curthread(); 258 _thr_cancel_enter2(curthread, 0); 259 ret = __sys_fsync(fd); 260 _thr_cancel_leave(curthread, 1); 261 262 return (ret); 263 } 264 265 /* 266 * Cancellation behavior: 267 * Thread may be canceled after system call. 268 */ 269 static int 270 __thr_msync(void *addr, size_t len, int flags) 271 { 272 struct pthread *curthread; 273 int ret; 274 275 curthread = _get_curthread(); 276 _thr_cancel_enter2(curthread, 0); 277 ret = __sys_msync(addr, len, flags); 278 _thr_cancel_leave(curthread, 1); 279 280 return (ret); 281 } 282 283 static int 284 __thr_nanosleep(const struct timespec *time_to_sleep, 285 struct timespec *time_remaining) 286 { 287 struct pthread *curthread; 288 int ret; 289 290 curthread = _get_curthread(); 291 _thr_cancel_enter(curthread); 292 ret = __sys_nanosleep(time_to_sleep, time_remaining); 293 _thr_cancel_leave(curthread, 1); 294 295 return (ret); 296 } 297 298 /* 299 * Cancellation behavior: 300 * If the thread is canceled, file is not opened. 301 */ 302 static int 303 __thr_open(const char *path, int flags,...) 304 { 305 struct pthread *curthread; 306 int mode, ret; 307 va_list ap; 308 309 /* Check if the file is being created: */ 310 if ((flags & O_CREAT) != 0) { 311 /* Get the creation mode: */ 312 va_start(ap, flags); 313 mode = va_arg(ap, int); 314 va_end(ap); 315 } else { 316 mode = 0; 317 } 318 319 curthread = _get_curthread(); 320 _thr_cancel_enter(curthread); 321 ret = __sys_open(path, flags, mode); 322 _thr_cancel_leave(curthread, ret == -1); 323 324 return (ret); 325 } 326 327 /* 328 * Cancellation behavior: 329 * If the thread is canceled, file is not opened. 330 */ 331 static int 332 __thr_openat(int fd, const char *path, int flags, ...) 333 { 334 struct pthread *curthread; 335 int mode, ret; 336 va_list ap; 337 338 339 /* Check if the file is being created: */ 340 if ((flags & O_CREAT) != 0) { 341 /* Get the creation mode: */ 342 va_start(ap, flags); 343 mode = va_arg(ap, int); 344 va_end(ap); 345 } else { 346 mode = 0; 347 } 348 349 curthread = _get_curthread(); 350 _thr_cancel_enter(curthread); 351 ret = __sys_openat(fd, path, flags, mode); 352 _thr_cancel_leave(curthread, ret == -1); 353 354 return (ret); 355 } 356 357 /* 358 * Cancellation behavior: 359 * Thread may be canceled at start, but if the system call returns something, 360 * the thread is not canceled. 361 */ 362 static int 363 __thr_poll(struct pollfd *fds, unsigned int nfds, int timeout) 364 { 365 struct pthread *curthread; 366 int ret; 367 368 curthread = _get_curthread(); 369 _thr_cancel_enter(curthread); 370 ret = __sys_poll(fds, nfds, timeout); 371 _thr_cancel_leave(curthread, ret == -1); 372 373 return (ret); 374 } 375 376 /* 377 * Cancellation behavior: 378 * Thread may be canceled at start, but if the system call returns something, 379 * the thread is not canceled. 380 */ 381 static int 382 __thr_pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, 383 const struct timespec *timo, const sigset_t *mask) 384 { 385 struct pthread *curthread; 386 int ret; 387 388 curthread = _get_curthread(); 389 _thr_cancel_enter(curthread); 390 ret = __sys_pselect(count, rfds, wfds, efds, timo, mask); 391 _thr_cancel_leave(curthread, ret == -1); 392 393 return (ret); 394 } 395 396 /* 397 * Cancellation behavior: 398 * Thread may be canceled at start, but if the system call got some data, 399 * the thread is not canceled. 400 */ 401 static ssize_t 402 __thr_read(int fd, void *buf, size_t nbytes) 403 { 404 struct pthread *curthread; 405 ssize_t ret; 406 407 curthread = _get_curthread(); 408 _thr_cancel_enter(curthread); 409 ret = __sys_read(fd, buf, nbytes); 410 _thr_cancel_leave(curthread, ret == -1); 411 412 return (ret); 413 } 414 415 /* 416 * Cancellation behavior: 417 * Thread may be canceled at start, but if the system call got some data, 418 * the thread is not canceled. 419 */ 420 static ssize_t 421 __thr_readv(int fd, const struct iovec *iov, int iovcnt) 422 { 423 struct pthread *curthread; 424 ssize_t ret; 425 426 curthread = _get_curthread(); 427 _thr_cancel_enter(curthread); 428 ret = __sys_readv(fd, iov, iovcnt); 429 _thr_cancel_leave(curthread, ret == -1); 430 return (ret); 431 } 432 433 /* 434 * Cancellation behavior: 435 * Thread may be canceled at start, but if the system call got some data, 436 * the thread is not canceled. 437 */ 438 static ssize_t 439 __thr_recvfrom(int s, void *b, size_t l, int f, struct sockaddr *from, 440 socklen_t *fl) 441 { 442 struct pthread *curthread; 443 ssize_t ret; 444 445 curthread = _get_curthread(); 446 _thr_cancel_enter(curthread); 447 ret = __sys_recvfrom(s, b, l, f, from, fl); 448 _thr_cancel_leave(curthread, ret == -1); 449 return (ret); 450 } 451 452 /* 453 * Cancellation behavior: 454 * Thread may be canceled at start, but if the system call got some data, 455 * the thread is not canceled. 456 */ 457 static ssize_t 458 __thr_recvmsg(int s, struct msghdr *m, int f) 459 { 460 struct pthread *curthread; 461 ssize_t ret; 462 463 curthread = _get_curthread(); 464 _thr_cancel_enter(curthread); 465 ret = __sys_recvmsg(s, m, f); 466 _thr_cancel_leave(curthread, ret == -1); 467 return (ret); 468 } 469 470 /* 471 * Cancellation behavior: 472 * Thread may be canceled at start, but if the system call returns something, 473 * the thread is not canceled. 474 */ 475 static int 476 __thr_select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 477 struct timeval *timeout) 478 { 479 struct pthread *curthread; 480 int ret; 481 482 curthread = _get_curthread(); 483 _thr_cancel_enter(curthread); 484 ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout); 485 _thr_cancel_leave(curthread, ret == -1); 486 return (ret); 487 } 488 489 /* 490 * Cancellation behavior: 491 * Thread may be canceled at start, but if the system call sent 492 * data, the thread is not canceled. 493 */ 494 static ssize_t 495 __thr_sendmsg(int s, const struct msghdr *m, int f) 496 { 497 struct pthread *curthread; 498 ssize_t ret; 499 500 curthread = _get_curthread(); 501 _thr_cancel_enter(curthread); 502 ret = __sys_sendmsg(s, m, f); 503 _thr_cancel_leave(curthread, ret <= 0); 504 return (ret); 505 } 506 507 /* 508 * Cancellation behavior: 509 * Thread may be canceled at start, but if the system call sent some 510 * data, the thread is not canceled. 511 */ 512 static ssize_t 513 __thr_sendto(int s, const void *m, size_t l, int f, const struct sockaddr *t, 514 socklen_t tl) 515 { 516 struct pthread *curthread; 517 ssize_t ret; 518 519 curthread = _get_curthread(); 520 _thr_cancel_enter(curthread); 521 ret = __sys_sendto(s, m, l, f, t, tl); 522 _thr_cancel_leave(curthread, ret <= 0); 523 return (ret); 524 } 525 526 static unsigned int 527 __thr_sleep(unsigned int seconds) 528 { 529 struct pthread *curthread; 530 unsigned int ret; 531 532 curthread = _get_curthread(); 533 _thr_cancel_enter(curthread); 534 ret = __libc_sleep(seconds); 535 _thr_cancel_leave(curthread, 1); 536 return (ret); 537 } 538 539 static int 540 __thr_system(const char *string) 541 { 542 struct pthread *curthread; 543 int ret; 544 545 curthread = _get_curthread(); 546 _thr_cancel_enter(curthread); 547 ret = __libc_system(string); 548 _thr_cancel_leave(curthread, 1); 549 return (ret); 550 } 551 552 /* 553 * Cancellation behavior: 554 * If thread is canceled, the system call is not completed, 555 * this means not all bytes were drained. 556 */ 557 static int 558 __thr_tcdrain(int fd) 559 { 560 struct pthread *curthread; 561 int ret; 562 563 curthread = _get_curthread(); 564 _thr_cancel_enter(curthread); 565 ret = __libc_tcdrain(fd); 566 _thr_cancel_leave(curthread, ret == -1); 567 return (ret); 568 } 569 570 static int 571 __thr_usleep(useconds_t useconds) 572 { 573 struct pthread *curthread; 574 int ret; 575 576 curthread = _get_curthread(); 577 _thr_cancel_enter(curthread); 578 ret = __libc_usleep(useconds); 579 _thr_cancel_leave(curthread, 1); 580 return (ret); 581 } 582 583 /* 584 * Cancellation behavior: 585 * Thread may be canceled at start, but if the system call returns 586 * a child pid, the thread is not canceled. 587 */ 588 static pid_t 589 __thr_wait(int *istat) 590 { 591 struct pthread *curthread; 592 pid_t ret; 593 594 curthread = _get_curthread(); 595 _thr_cancel_enter(curthread); 596 ret = __libc_wait(istat); 597 _thr_cancel_leave(curthread, ret <= 0); 598 return (ret); 599 } 600 601 /* 602 * Cancellation behavior: 603 * Thread may be canceled at start, but if the system call returns 604 * a child pid, the thread is not canceled. 605 */ 606 static pid_t 607 __thr_wait3(int *status, int options, struct rusage *rusage) 608 { 609 struct pthread *curthread; 610 pid_t ret; 611 612 curthread = _get_curthread(); 613 _thr_cancel_enter(curthread); 614 ret = __libc_wait3(status, options, rusage); 615 _thr_cancel_leave(curthread, ret <= 0); 616 return (ret); 617 } 618 619 /* 620 * Cancellation behavior: 621 * Thread may be canceled at start, but if the system call returns 622 * a child pid, the thread is not canceled. 623 */ 624 static pid_t 625 __thr_wait4(pid_t pid, int *status, int options, struct rusage *rusage) 626 { 627 struct pthread *curthread; 628 pid_t ret; 629 630 curthread = _get_curthread(); 631 _thr_cancel_enter(curthread); 632 ret = __sys_wait4(pid, status, options, rusage); 633 _thr_cancel_leave(curthread, ret <= 0); 634 return (ret); 635 } 636 637 /* 638 * Cancellation behavior: 639 * Thread may be canceled at start, but if the system call returns 640 * a child pid, the thread is not canceled. 641 */ 642 static pid_t 643 __thr_waitpid(pid_t wpid, int *status, int options) 644 { 645 struct pthread *curthread; 646 pid_t ret; 647 648 curthread = _get_curthread(); 649 _thr_cancel_enter(curthread); 650 ret = __libc_waitpid(wpid, status, options); 651 _thr_cancel_leave(curthread, ret <= 0); 652 return (ret); 653 } 654 655 /* 656 * Cancellation behavior: 657 * Thread may be canceled at start, but if the thread wrote some data, 658 * it is not canceled. 659 */ 660 static ssize_t 661 __thr_write(int fd, const void *buf, size_t nbytes) 662 { 663 struct pthread *curthread; 664 ssize_t ret; 665 666 curthread = _get_curthread(); 667 _thr_cancel_enter(curthread); 668 ret = __sys_write(fd, buf, nbytes); 669 _thr_cancel_leave(curthread, (ret <= 0)); 670 return (ret); 671 } 672 673 /* 674 * Cancellation behavior: 675 * Thread may be canceled at start, but if the thread wrote some data, 676 * it is not canceled. 677 */ 678 static ssize_t 679 __thr_writev(int fd, const struct iovec *iov, int iovcnt) 680 { 681 struct pthread *curthread; 682 ssize_t ret; 683 684 curthread = _get_curthread(); 685 _thr_cancel_enter(curthread); 686 ret = __sys_writev(fd, iov, iovcnt); 687 _thr_cancel_leave(curthread, (ret <= 0)); 688 return (ret); 689 } 690 691 void 692 __thr_interpose_libc(void) 693 { 694 695 __set_error_selector(__error_threaded); 696 #define SLOT(name) \ 697 *(__libc_interposing_slot(INTERPOS_##name)) = \ 698 (interpos_func_t)__thr_##name; 699 SLOT(accept); 700 SLOT(accept4); 701 SLOT(aio_suspend); 702 SLOT(close); 703 SLOT(connect); 704 SLOT(creat); 705 SLOT(fcntl); 706 SLOT(fsync); 707 SLOT(fork); 708 SLOT(msync); 709 SLOT(nanosleep); 710 SLOT(open); 711 SLOT(openat); 712 SLOT(poll); 713 SLOT(pselect); 714 SLOT(raise); 715 SLOT(read); 716 SLOT(readv); 717 SLOT(recvfrom); 718 SLOT(recvmsg); 719 SLOT(select); 720 SLOT(sendmsg); 721 SLOT(sendto); 722 SLOT(setcontext); 723 SLOT(sigaction); 724 SLOT(sigprocmask); 725 SLOT(sigsuspend); 726 SLOT(sigwait); 727 SLOT(sigtimedwait); 728 SLOT(sigwaitinfo); 729 SLOT(swapcontext); 730 SLOT(system); 731 SLOT(sleep); 732 SLOT(tcdrain); 733 SLOT(usleep); 734 SLOT(pause); 735 SLOT(wait); 736 SLOT(wait3); 737 SLOT(wait4); 738 SLOT(waitpid); 739 SLOT(write); 740 SLOT(writev); 741 #undef SLOT 742 *(__libc_interposing_slot( 743 INTERPOS__pthread_mutex_init_calloc_cb)) = 744 (interpos_func_t)_pthread_mutex_init_calloc_cb; 745 } 746