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