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