1 /* $NetBSD: pthread_cancelstub.c,v 1.40 2021/10/01 20:13:38 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 2002, 2007 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Nathan J. Williams and Andrew Doran. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* Disable namespace mangling, Fortification is useless here anyway. */ 33 #undef _FORTIFY_SOURCE 34 35 #include <sys/cdefs.h> 36 __RCSID("$NetBSD: pthread_cancelstub.c,v 1.40 2021/10/01 20:13:38 christos Exp $"); 37 38 #ifndef lint 39 40 41 /* 42 * This is necessary because the names are always weak (they are not 43 * POSIX functions). 44 */ 45 #define fsync_range _fsync_range 46 #define pollts _pollts 47 48 /* 49 * XXX this is necessary to get the prototypes for the __sigsuspend14 50 * XXX and __msync13 internal names, instead of the application-visible 51 * XXX sigsuspend and msync names. It's kind of gross, but we're pretty 52 * XXX intimate with libc already. 53 */ 54 #define __LIBC12_SOURCE__ 55 56 #include <sys/msg.h> 57 #include <sys/types.h> 58 #include <sys/uio.h> 59 #include <sys/wait.h> 60 #include <aio.h> 61 #include <errno.h> 62 #include <fcntl.h> 63 #include <mqueue.h> 64 #include <poll.h> 65 #include <stdarg.h> 66 #include <unistd.h> 67 68 #include <signal.h> 69 #include <sys/mman.h> 70 #include <sys/select.h> 71 #include <sys/socket.h> 72 #include <sys/event.h> 73 74 #include <compat/sys/mman.h> 75 #include <compat/sys/poll.h> 76 #include <compat/sys/select.h> 77 #include <compat/sys/event.h> 78 #include <compat/sys/wait.h> 79 #include <compat/include/mqueue.h> 80 #include <compat/include/signal.h> 81 82 #include "pthread.h" 83 #include "pthread_int.h" 84 #include "reentrant.h" 85 86 int pthread__cancel_stub_binder; 87 88 int _sys_accept(int, struct sockaddr *, socklen_t *); 89 int _sys___aio_suspend50(const struct aiocb * const [], int, 90 const struct timespec *); 91 int __aio_suspend50(const struct aiocb * const [], int, 92 const struct timespec *); 93 int _sys_clock_nanosleep(clockid_t clock_id, int flags, 94 const struct timespec *rqtp, struct timespec *rmtp); 95 int _sys_close(int); 96 int _sys_connect(int, const struct sockaddr *, socklen_t); 97 int _sys_fcntl(int, int, ...); 98 int _sys_fdatasync(int); 99 int _sys_fsync(int); 100 int _sys_fsync_range(int, int, off_t, off_t); 101 int _sys___kevent50(int, const struct kevent *, size_t, struct kevent *, 102 size_t, const struct timespec *); 103 int _sys_mq_send(mqd_t, const char *, size_t, unsigned); 104 ssize_t _sys_mq_receive(mqd_t, char *, size_t, unsigned *); 105 int _sys___mq_timedsend50(mqd_t, const char *, size_t, unsigned, 106 const struct timespec *); 107 ssize_t _sys___mq_timedreceive50(mqd_t, char *, size_t, unsigned *, 108 const struct timespec *); 109 ssize_t _sys_msgrcv(int, void *, size_t, long, int); 110 int _sys_msgsnd(int, const void *, size_t, int); 111 int _sys___msync13(void *, size_t, int); 112 int _sys___nanosleep50(const struct timespec *, struct timespec *); 113 int __nanosleep50(const struct timespec *, struct timespec *); 114 int _sys_open(const char *, int, ...); 115 int _sys_openat(int, const char *, int, ...); 116 int _sys_poll(struct pollfd *, nfds_t, int); 117 int _sys___pollts50(struct pollfd *, nfds_t, const struct timespec *, 118 const sigset_t *); 119 ssize_t _sys_pread(int, void *, size_t, off_t); 120 int _sys___pselect50(int, fd_set *, fd_set *, fd_set *, 121 const struct timespec *, const sigset_t *); 122 ssize_t _sys_pwrite(int, const void *, size_t, off_t); 123 ssize_t _sys_read(int, void *, size_t); 124 ssize_t _sys_readv(int, const struct iovec *, int); 125 ssize_t _sys_recvfrom(int, void * restrict, size_t, int, 126 struct sockaddr * restrict, socklen_t * restrict); 127 ssize_t _sys_recvmsg(int, struct msghdr *, int); 128 int _sys_recvmmsg(int, struct mmsghdr *, unsigned int, unsigned int, 129 struct timespec *); 130 ssize_t _sys_sendto(int, const void *, size_t, int, const struct sockaddr *, 131 socklen_t); 132 ssize_t _sys_sendmsg(int, const struct msghdr *, int); 133 int _sys_sendmmsg(int, struct mmsghdr *, unsigned int, unsigned int); 134 int _sys___select50(int, fd_set *, fd_set *, fd_set *, struct timeval *); 135 int _sys___wait450(pid_t, int *, int, struct rusage *); 136 ssize_t _sys_write(int, const void *, size_t); 137 ssize_t _sys_writev(int, const struct iovec *, int); 138 int _sys___sigsuspend14(const sigset_t *); 139 int ____sigtimedwait50(const sigset_t * __restrict, siginfo_t * __restrict, 140 struct timespec * __restrict); 141 int __sigsuspend14(const sigset_t *); 142 143 #define TESTCANCEL(id) do { \ 144 if (__predict_true(!__uselibcstub) && \ 145 __predict_false((id)->pt_cancel)) \ 146 pthread__cancelled(); \ 147 } while (/*CONSTCOND*/0) 148 149 150 int 151 accept(int s, struct sockaddr *addr, socklen_t *addrlen) 152 { 153 int retval; 154 pthread_t self; 155 156 self = pthread__self(); 157 TESTCANCEL(self); 158 retval = _sys_accept(s, addr, addrlen); 159 TESTCANCEL(self); 160 161 return retval; 162 } 163 164 int 165 __aio_suspend50(const struct aiocb * const list[], int nent, 166 const struct timespec *timeout) 167 { 168 int retval; 169 pthread_t self; 170 171 self = pthread__self(); 172 TESTCANCEL(self); 173 retval = _sys___aio_suspend50(list, nent, timeout); 174 TESTCANCEL(self); 175 176 return retval; 177 } 178 179 int 180 __kevent50(int fd, const struct kevent *ev, size_t nev, struct kevent *rev, 181 size_t nrev, const struct timespec *ts) 182 { 183 int retval; 184 pthread_t self; 185 186 self = pthread__self(); 187 TESTCANCEL(self); 188 retval = _sys___kevent50(fd, ev, nev, rev, nrev, ts); 189 TESTCANCEL(self); 190 191 return retval; 192 } 193 194 int 195 clock_nanosleep(clockid_t clock_id, int flags, 196 const struct timespec *rqtp, struct timespec *rmtp) 197 { 198 int retval; 199 pthread_t self; 200 201 self = pthread__self(); 202 TESTCANCEL(self); 203 retval = _sys_clock_nanosleep(clock_id, flags, rqtp, rmtp); 204 TESTCANCEL(self); 205 206 return retval; 207 } 208 209 int 210 close(int d) 211 { 212 int retval; 213 pthread_t self; 214 215 self = pthread__self(); 216 TESTCANCEL(self); 217 retval = _sys_close(d); 218 TESTCANCEL(self); 219 220 return retval; 221 } 222 223 int 224 connect(int s, const struct sockaddr *addr, socklen_t namelen) 225 { 226 int retval; 227 pthread_t self; 228 229 self = pthread__self(); 230 TESTCANCEL(self); 231 retval = _sys_connect(s, addr, namelen); 232 TESTCANCEL(self); 233 234 return retval; 235 } 236 237 int 238 fcntl(int fd, int cmd, ...) 239 { 240 int retval; 241 pthread_t self; 242 va_list ap; 243 244 self = pthread__self(); 245 TESTCANCEL(self); 246 va_start(ap, cmd); 247 retval = _sys_fcntl(fd, cmd, va_arg(ap, void *)); 248 va_end(ap); 249 TESTCANCEL(self); 250 251 return retval; 252 } 253 254 int 255 fdatasync(int d) 256 { 257 int retval; 258 pthread_t self; 259 260 self = pthread__self(); 261 TESTCANCEL(self); 262 retval = _sys_fdatasync(d); 263 TESTCANCEL(self); 264 265 return retval; 266 } 267 268 int 269 fsync(int d) 270 { 271 int retval; 272 pthread_t self; 273 274 self = pthread__self(); 275 TESTCANCEL(self); 276 retval = _sys_fsync(d); 277 TESTCANCEL(self); 278 279 return retval; 280 } 281 282 int 283 fsync_range(int d, int f, off_t s, off_t e) 284 { 285 int retval; 286 pthread_t self; 287 288 self = pthread__self(); 289 TESTCANCEL(self); 290 retval = _sys_fsync_range(d, f, s, e); 291 TESTCANCEL(self); 292 293 return retval; 294 } 295 296 int 297 mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio) 298 { 299 int retval; 300 pthread_t self; 301 302 self = pthread__self(); 303 TESTCANCEL(self); 304 retval = _sys_mq_send(mqdes, msg_ptr, msg_len, msg_prio); 305 TESTCANCEL(self); 306 307 return retval; 308 } 309 310 ssize_t 311 mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio) 312 { 313 ssize_t retval; 314 pthread_t self; 315 316 self = pthread__self(); 317 TESTCANCEL(self); 318 retval = _sys_mq_receive(mqdes, msg_ptr, msg_len, msg_prio); 319 TESTCANCEL(self); 320 321 return retval; 322 } 323 324 int 325 __mq_timedsend50(mqd_t mqdes, const char *msg_ptr, size_t msg_len, 326 unsigned msg_prio, const struct timespec *abst) 327 { 328 int retval; 329 pthread_t self; 330 331 self = pthread__self(); 332 TESTCANCEL(self); 333 retval = _sys___mq_timedsend50(mqdes, msg_ptr, msg_len, msg_prio, abst); 334 TESTCANCEL(self); 335 336 return retval; 337 } 338 339 ssize_t 340 __mq_timedreceive50(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio, 341 const struct timespec *abst) 342 { 343 ssize_t retval; 344 pthread_t self; 345 346 self = pthread__self(); 347 TESTCANCEL(self); 348 retval = _sys___mq_timedreceive50(mqdes, msg_ptr, msg_len, msg_prio, abst); 349 TESTCANCEL(self); 350 351 return retval; 352 } 353 354 ssize_t 355 msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg) 356 { 357 ssize_t retval; 358 pthread_t self; 359 360 self = pthread__self(); 361 TESTCANCEL(self); 362 retval = _sys_msgrcv(msgid, msgp, msgsz, msgtyp, msgflg); 363 TESTCANCEL(self); 364 365 return retval; 366 } 367 368 int 369 msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg) 370 { 371 int retval; 372 pthread_t self; 373 374 self = pthread__self(); 375 TESTCANCEL(self); 376 retval = _sys_msgsnd(msgid, msgp, msgsz, msgflg); 377 TESTCANCEL(self); 378 379 return retval; 380 } 381 382 int 383 __msync13(void *addr, size_t len, int flags) 384 { 385 int retval; 386 pthread_t self; 387 388 self = pthread__self(); 389 TESTCANCEL(self); 390 retval = _sys___msync13(addr, len, flags); 391 TESTCANCEL(self); 392 393 return retval; 394 } 395 396 int 397 open(const char *path, int flags, ...) 398 { 399 int retval; 400 pthread_t self; 401 va_list ap; 402 403 self = pthread__self(); 404 TESTCANCEL(self); 405 va_start(ap, flags); 406 retval = _sys_open(path, flags, va_arg(ap, mode_t)); 407 va_end(ap); 408 TESTCANCEL(self); 409 410 return retval; 411 } 412 413 int 414 openat(int fd, const char *path, int flags, ...) 415 { 416 int retval; 417 pthread_t self; 418 va_list ap; 419 420 self = pthread__self(); 421 TESTCANCEL(self); 422 va_start(ap, flags); 423 retval = _sys_openat(fd, path, flags, va_arg(ap, mode_t)); 424 va_end(ap); 425 TESTCANCEL(self); 426 427 return retval; 428 } 429 430 int 431 __nanosleep50(const struct timespec *rqtp, struct timespec *rmtp) 432 { 433 int retval; 434 pthread_t self; 435 436 self = pthread__self(); 437 TESTCANCEL(self); 438 /* 439 * For now, just nanosleep. In the future, maybe pass a ucontext_t 440 * to _lwp_nanosleep() and allow it to recycle our kernel stack. 441 */ 442 retval = _sys___nanosleep50(rqtp, rmtp); 443 TESTCANCEL(self); 444 445 return retval; 446 } 447 448 int 449 poll(struct pollfd *fds, nfds_t nfds, int timeout) 450 { 451 int retval; 452 pthread_t self; 453 454 self = pthread__self(); 455 TESTCANCEL(self); 456 retval = _sys_poll(fds, nfds, timeout); 457 TESTCANCEL(self); 458 459 return retval; 460 } 461 462 int 463 __pollts50(struct pollfd *fds, nfds_t nfds, const struct timespec *ts, 464 const sigset_t *sigmask) 465 { 466 int retval; 467 pthread_t self; 468 469 self = pthread__self(); 470 TESTCANCEL(self); 471 retval = _sys___pollts50(fds, nfds, ts, sigmask); 472 TESTCANCEL(self); 473 474 return retval; 475 } 476 477 ssize_t 478 pread(int d, void *buf, size_t nbytes, off_t offset) 479 { 480 ssize_t retval; 481 pthread_t self; 482 483 self = pthread__self(); 484 TESTCANCEL(self); 485 retval = _sys_pread(d, buf, nbytes, offset); 486 TESTCANCEL(self); 487 488 return retval; 489 } 490 491 int 492 __pselect50(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 493 const struct timespec *timeout, const sigset_t *sigmask) 494 { 495 int retval; 496 pthread_t self; 497 498 self = pthread__self(); 499 TESTCANCEL(self); 500 retval = _sys___pselect50(nfds, readfds, writefds, exceptfds, timeout, 501 sigmask); 502 TESTCANCEL(self); 503 504 return retval; 505 } 506 507 ssize_t 508 pwrite(int d, const void *buf, size_t nbytes, off_t offset) 509 { 510 ssize_t retval; 511 pthread_t self; 512 513 self = pthread__self(); 514 TESTCANCEL(self); 515 retval = _sys_pwrite(d, buf, nbytes, offset); 516 TESTCANCEL(self); 517 518 return retval; 519 } 520 521 ssize_t 522 read(int d, void *buf, size_t nbytes) 523 { 524 ssize_t retval; 525 pthread_t self; 526 527 self = pthread__self(); 528 TESTCANCEL(self); 529 retval = _sys_read(d, buf, nbytes); 530 TESTCANCEL(self); 531 532 return retval; 533 } 534 535 ssize_t 536 readv(int d, const struct iovec *iov, int iovcnt) 537 { 538 ssize_t retval; 539 pthread_t self; 540 541 self = pthread__self(); 542 TESTCANCEL(self); 543 retval = _sys_readv(d, iov, iovcnt); 544 TESTCANCEL(self); 545 546 return retval; 547 } 548 549 ssize_t 550 recvfrom(int s, void * restrict buf, size_t len, int flags, 551 struct sockaddr * restrict from, socklen_t * restrict fromlen) 552 { 553 ssize_t retval; 554 pthread_t self; 555 556 self = pthread__self(); 557 TESTCANCEL(self); 558 retval = _sys_recvfrom(s, buf, len, flags, from, fromlen); 559 TESTCANCEL(self); 560 561 return retval; 562 } 563 564 ssize_t 565 recvmsg(int s, struct msghdr *msg, int flags) 566 { 567 ssize_t retval; 568 pthread_t self; 569 570 self = pthread__self(); 571 TESTCANCEL(self); 572 retval = _sys_recvmsg(s, msg, flags); 573 TESTCANCEL(self); 574 575 return retval; 576 } 577 578 int 579 recvmmsg(int s, struct mmsghdr *mmsg, unsigned int vlen, 580 unsigned int flags, struct timespec *timeout) 581 { 582 ssize_t retval; 583 pthread_t self; 584 585 self = pthread__self(); 586 TESTCANCEL(self); 587 retval = _sys_recvmmsg(s, mmsg, vlen, flags, timeout); 588 TESTCANCEL(self); 589 590 return retval; 591 } 592 593 int 594 __select50(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 595 struct timeval *timeout) 596 { 597 int retval; 598 pthread_t self; 599 600 self = pthread__self(); 601 TESTCANCEL(self); 602 retval = _sys___select50(nfds, readfds, writefds, exceptfds, timeout); 603 TESTCANCEL(self); 604 605 return retval; 606 } 607 608 ssize_t 609 sendto(int s, const void *msg, size_t len, int flags, 610 const struct sockaddr *to, socklen_t tolen) 611 { 612 int retval; 613 pthread_t self; 614 615 self = pthread__self(); 616 TESTCANCEL(self); 617 retval = _sys_sendto(s, msg, len, flags, to, tolen); 618 TESTCANCEL(self); 619 620 return retval; 621 } 622 623 ssize_t 624 sendmsg(int s, const struct msghdr *msg, int flags) 625 { 626 int retval; 627 pthread_t self; 628 629 self = pthread__self(); 630 TESTCANCEL(self); 631 retval = _sys_sendmsg(s, msg, flags); 632 TESTCANCEL(self); 633 634 return retval; 635 } 636 637 int 638 sendmmsg(int s, struct mmsghdr *mmsg, unsigned int vlen, 639 unsigned int flags) 640 { 641 int retval; 642 pthread_t self; 643 644 self = pthread__self(); 645 TESTCANCEL(self); 646 retval = _sys_sendmmsg(s, mmsg, vlen, flags); 647 TESTCANCEL(self); 648 649 return retval; 650 } 651 652 653 pid_t 654 __wait450(pid_t wpid, int *status, int options, struct rusage *rusage) 655 { 656 pid_t retval; 657 pthread_t self; 658 659 self = pthread__self(); 660 TESTCANCEL(self); 661 retval = _sys___wait450(wpid, status, options, rusage); 662 TESTCANCEL(self); 663 664 return retval; 665 } 666 667 ssize_t 668 write(int d, const void *buf, size_t nbytes) 669 { 670 ssize_t retval; 671 pthread_t self; 672 673 self = pthread__self(); 674 TESTCANCEL(self); 675 retval = _sys_write(d, buf, nbytes); 676 TESTCANCEL(self); 677 678 return retval; 679 } 680 681 ssize_t 682 writev(int d, const struct iovec *iov, int iovcnt) 683 { 684 ssize_t retval; 685 pthread_t self; 686 687 self = pthread__self(); 688 TESTCANCEL(self); 689 retval = _sys_writev(d, iov, iovcnt); 690 TESTCANCEL(self); 691 692 return retval; 693 } 694 695 int 696 __sigsuspend14(const sigset_t *sigmask) 697 { 698 pthread_t self; 699 int retval; 700 701 self = pthread__self(); 702 TESTCANCEL(self); 703 retval = _sys___sigsuspend14(sigmask); 704 TESTCANCEL(self); 705 706 return retval; 707 } 708 709 int 710 __sigtimedwait50(const sigset_t * __restrict set, siginfo_t * __restrict info, 711 const struct timespec * __restrict timeout) 712 { 713 pthread_t self; 714 int retval; 715 struct timespec tout, *tp; 716 717 if (timeout) { 718 tout = *timeout; 719 tp = &tout; 720 } else 721 tp = NULL; 722 723 self = pthread__self(); 724 TESTCANCEL(self); 725 retval = ____sigtimedwait50(set, info, tp); 726 TESTCANCEL(self); 727 728 return retval; 729 } 730 731 int 732 sigwait(const sigset_t * __restrict set, int * __restrict sig) 733 { 734 pthread_t self; 735 int saved_errno; 736 int new_errno; 737 int retval; 738 739 self = pthread__self(); 740 saved_errno = errno; 741 TESTCANCEL(self); 742 retval = ____sigtimedwait50(set, NULL, NULL); 743 TESTCANCEL(self); 744 new_errno = errno; 745 errno = saved_errno; 746 if (retval < 0) { 747 return new_errno; 748 } 749 *sig = retval; 750 return 0; 751 } 752 753 __strong_alias(_close, close) 754 __strong_alias(_clock_nanosleep, clock_nanosleep) 755 __strong_alias(_fcntl, fcntl) 756 __strong_alias(_fdatasync, fdatasync) 757 __strong_alias(_fsync, fsync) 758 __weak_alias(fsync_range, _fsync_range) 759 __strong_alias(_mq_send, mq_send) 760 __strong_alias(_mq_receive, mq_receive) 761 __strong_alias(_msgrcv, msgrcv) 762 __strong_alias(_msgsnd, msgsnd) 763 __strong_alias(___msync13, __msync13) 764 __strong_alias(___nanosleep50, __nanosleep50) 765 __strong_alias(_open, open) 766 __strong_alias(_openat, openat) 767 __strong_alias(_poll, poll) 768 __strong_alias(_pread, pread) 769 __strong_alias(_pwrite, pwrite) 770 __strong_alias(_read, read) 771 __strong_alias(_readv, readv) 772 __strong_alias(_recvfrom, recvfrom) 773 __strong_alias(_recvmsg, recvmsg) 774 __strong_alias(_recvmmsg, recvmmsg) 775 __strong_alias(_sendmsg, sendmsg) 776 __strong_alias(_sendmmsg, sendmmsg) 777 __strong_alias(_sendto, sendto) 778 __strong_alias(_sigwait, sigwait) 779 __strong_alias(_write, write) 780 __strong_alias(_writev, writev) 781 782 #endif /* !lint */ 783