Wed Jan 29 16:03:44 2020 UTC ()
Chack thread->pt_magic with PT_MAGIC promptly

Rearrange some checks to avoid verifying pthread_t after using it.


(kamil)
diff -r1.160 -r1.161 src/lib/libpthread/pthread.c
diff -r1.2 -r1.3 src/lib/libpthread/pthread_getcpuclockid.c

cvs diff -r1.160 -r1.161 src/lib/libpthread/pthread.c (expand / switch to unified diff)

--- src/lib/libpthread/pthread.c 2020/01/29 15:31:14 1.160
+++ src/lib/libpthread/pthread.c 2020/01/29 16:03:44 1.161
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: pthread.c,v 1.160 2020/01/29 15:31:14 kamil Exp $ */ 1/* $NetBSD: pthread.c,v 1.161 2020/01/29 16:03:44 kamil Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008, 2020 4 * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008, 2020
5 * The NetBSD Foundation, Inc. 5 * The NetBSD Foundation, Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * This code is derived from software contributed to The NetBSD Foundation 8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Nathan J. Williams and Andrew Doran. 9 * by Nathan J. Williams and Andrew Doran.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -21,27 +21,27 @@ @@ -21,27 +21,27 @@
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__RCSID("$NetBSD: pthread.c,v 1.160 2020/01/29 15:31:14 kamil Exp $"); 34__RCSID("$NetBSD: pthread.c,v 1.161 2020/01/29 16:03:44 kamil Exp $");
35 35
36#define __EXPOSE_STACK 1 36#define __EXPOSE_STACK 1
37 37
38#include <sys/param.h> 38#include <sys/param.h>
39#include <sys/exec_elf.h> 39#include <sys/exec_elf.h>
40#include <sys/mman.h> 40#include <sys/mman.h>
41#include <sys/lwp.h> 41#include <sys/lwp.h>
42#include <sys/lwpctl.h> 42#include <sys/lwpctl.h>
43#include <sys/resource.h> 43#include <sys/resource.h>
44#include <sys/sysctl.h> 44#include <sys/sysctl.h>
45#include <sys/tls.h> 45#include <sys/tls.h>
46#include <uvm/uvm_param.h> 46#include <uvm/uvm_param.h>
47 47
@@ -587,40 +587,46 @@ pthread__create_tramp(void *cookie) @@ -587,40 +587,46 @@ pthread__create_tramp(void *cookie)
587 retval = (*self->pt_func)(self->pt_arg); 587 retval = (*self->pt_func)(self->pt_arg);
588 588
589 pthread_exit(retval); 589 pthread_exit(retval);
590 590
591 /*NOTREACHED*/ 591 /*NOTREACHED*/
592 pthread__abort(); 592 pthread__abort();
593} 593}
594 594
595int 595int
596pthread_suspend_np(pthread_t thread) 596pthread_suspend_np(pthread_t thread)
597{ 597{
598 pthread_t self; 598 pthread_t self;
599 599
 600 pthread__error(EINVAL, "Invalid thread",
 601 thread->pt_magic == PT_MAGIC);
 602
600 self = pthread__self(); 603 self = pthread__self();
601 if (self == thread) { 604 if (self == thread) {
602 return EDEADLK; 605 return EDEADLK;
603 } 606 }
604 if (pthread__find(thread) != 0) 607 if (pthread__find(thread) != 0)
605 return ESRCH; 608 return ESRCH;
606 if (_lwp_suspend(thread->pt_lid) == 0) 609 if (_lwp_suspend(thread->pt_lid) == 0)
607 return 0; 610 return 0;
608 return errno; 611 return errno;
609} 612}
610 613
611int 614int
612pthread_resume_np(pthread_t thread) 615pthread_resume_np(pthread_t thread)
613{ 616{
 617
 618 pthread__error(EINVAL, "Invalid thread",
 619 thread->pt_magic == PT_MAGIC);
614  620
615 if (pthread__find(thread) != 0) 621 if (pthread__find(thread) != 0)
616 return ESRCH; 622 return ESRCH;
617 if (_lwp_continue(thread->pt_lid) == 0) 623 if (_lwp_continue(thread->pt_lid) == 0)
618 return 0; 624 return 0;
619 return errno; 625 return errno;
620} 626}
621 627
622/* 628/*
623 * In case the thread is exiting at an inopportune time leaving waiters not 629 * In case the thread is exiting at an inopportune time leaving waiters not
624 * awoken (because cancelled, for instance) make sure we have no waiters 630 * awoken (because cancelled, for instance) make sure we have no waiters
625 * left. 631 * left.
626 */ 632 */
@@ -692,34 +698,34 @@ pthread_exit(void *retval) @@ -692,34 +698,34 @@ pthread_exit(void *retval)
692 698
693out: 699out:
694 /*NOTREACHED*/ 700 /*NOTREACHED*/
695 pthread__abort(); 701 pthread__abort();
696 exit(1); 702 exit(1);
697} 703}
698 704
699 705
700int 706int
701pthread_join(pthread_t thread, void **valptr) 707pthread_join(pthread_t thread, void **valptr)
702{ 708{
703 pthread_t self; 709 pthread_t self;
704 710
 711 pthread__error(EINVAL, "Invalid thread",
 712 thread->pt_magic == PT_MAGIC);
 713
705 self = pthread__self(); 714 self = pthread__self();
706 715
707 if (pthread__find(thread) != 0) 716 if (pthread__find(thread) != 0)
708 return ESRCH; 717 return ESRCH;
709 718
710 if (thread->pt_magic != PT_MAGIC) 
711 return EINVAL; 
712 
713 if (thread == self) 719 if (thread == self)
714 return EDEADLK; 720 return EDEADLK;
715 721
716 /* XXX temporary - kernel should handle. */ 722 /* XXX temporary - kernel should handle. */
717 if ((thread->pt_flags & PT_FLAG_DETACHED) != 0) 723 if ((thread->pt_flags & PT_FLAG_DETACHED) != 0)
718 return EINVAL; 724 return EINVAL;
719 725
720 /* IEEE Std 1003.1 says pthread_join() never returns EINTR. */ 726 /* IEEE Std 1003.1 says pthread_join() never returns EINTR. */
721 for (;;) { 727 for (;;) {
722 pthread__testcancel(self); 728 pthread__testcancel(self);
723 if (_lwp_wait(thread->pt_lid, NULL) == 0) 729 if (_lwp_wait(thread->pt_lid, NULL) == 0)
724 break; 730 break;
725 if (errno != EINTR) 731 if (errno != EINTR)
@@ -754,97 +760,104 @@ pthread__reap(pthread_t thread) @@ -754,97 +760,104 @@ pthread__reap(pthread_t thread)
754 pthread_mutex_unlock(&thread->pt_lock); 760 pthread_mutex_unlock(&thread->pt_lock);
755 761
756 pthread_mutex_lock(&pthread__deadqueue_lock); 762 pthread_mutex_lock(&pthread__deadqueue_lock);
757 PTQ_INSERT_HEAD(&pthread__deadqueue, thread, pt_deadq); 763 PTQ_INSERT_HEAD(&pthread__deadqueue, thread, pt_deadq);
758 pthread_mutex_unlock(&pthread__deadqueue_lock); 764 pthread_mutex_unlock(&pthread__deadqueue_lock);
759 765
760 if (name != NULL) 766 if (name != NULL)
761 free(name); 767 free(name);
762} 768}
763 769
764int 770int
765pthread_equal(pthread_t t1, pthread_t t2) 771pthread_equal(pthread_t t1, pthread_t t2)
766{ 772{
 773
767 if (__predict_false(__uselibcstub)) 774 if (__predict_false(__uselibcstub))
768 return __libc_thr_equal_stub(t1, t2); 775 return __libc_thr_equal_stub(t1, t2);
769 776
 777 pthread__error(EINVAL, "Invalid thread",
 778 t1->pt_magic == PT_MAGIC);
 779
 780 pthread__error(EINVAL, "Invalid thread",
 781 t2->pt_magic == PT_MAGIC);
 782
770 /* Nothing special here. */ 783 /* Nothing special here. */
771 return (t1 == t2); 784 return (t1 == t2);
772} 785}
773 786
774 787
775int 788int
776pthread_detach(pthread_t thread) 789pthread_detach(pthread_t thread)
777{ 790{
778 int error; 791 int error;
779 792
 793 pthread__error(EINVAL, "Invalid thread",
 794 thread->pt_magic == PT_MAGIC);
 795
780 if (pthread__find(thread) != 0) 796 if (pthread__find(thread) != 0)
781 return ESRCH; 797 return ESRCH;
782 798
783 if (thread->pt_magic != PT_MAGIC) 
784 return EINVAL; 
785 
786 pthread_mutex_lock(&thread->pt_lock); 799 pthread_mutex_lock(&thread->pt_lock);
787 if ((thread->pt_flags & PT_FLAG_DETACHED) != 0) { 800 if ((thread->pt_flags & PT_FLAG_DETACHED) != 0) {
788 error = EINVAL; 801 error = EINVAL;
789 } else { 802 } else {
790 error = _lwp_detach(thread->pt_lid); 803 error = _lwp_detach(thread->pt_lid);
791 if (error == 0) 804 if (error == 0)
792 thread->pt_flags |= PT_FLAG_DETACHED; 805 thread->pt_flags |= PT_FLAG_DETACHED;
793 else 806 else
794 error = errno; 807 error = errno;
795 } 808 }
796 if (thread->pt_state == PT_STATE_ZOMBIE) { 809 if (thread->pt_state == PT_STATE_ZOMBIE) {
797 /* pthread__reap() will drop the lock. */ 810 /* pthread__reap() will drop the lock. */
798 pthread__reap(thread); 811 pthread__reap(thread);
799 } else 812 } else
800 pthread_mutex_unlock(&thread->pt_lock); 813 pthread_mutex_unlock(&thread->pt_lock);
801 return error; 814 return error;
802} 815}
803 816
804 817
805int 818int
806pthread_getname_np(pthread_t thread, char *name, size_t len) 819pthread_getname_np(pthread_t thread, char *name, size_t len)
807{ 820{
808 821
 822 pthread__error(EINVAL, "Invalid thread",
 823 thread->pt_magic == PT_MAGIC);
 824
809 if (pthread__find(thread) != 0) 825 if (pthread__find(thread) != 0)
810 return ESRCH; 826 return ESRCH;
811 827
812 if (thread->pt_magic != PT_MAGIC) 
813 return EINVAL; 
814 
815 pthread_mutex_lock(&thread->pt_lock); 828 pthread_mutex_lock(&thread->pt_lock);
816 if (thread->pt_name == NULL) 829 if (thread->pt_name == NULL)
817 name[0] = '\0'; 830 name[0] = '\0';
818 else 831 else
819 strlcpy(name, thread->pt_name, len); 832 strlcpy(name, thread->pt_name, len);
820 pthread_mutex_unlock(&thread->pt_lock); 833 pthread_mutex_unlock(&thread->pt_lock);
821 834
822 return 0; 835 return 0;
823} 836}
824 837
825 838
826int 839int
827pthread_setname_np(pthread_t thread, const char *name, void *arg) 840pthread_setname_np(pthread_t thread, const char *name, void *arg)
828{ 841{
829 char *oldname, *cp, newname[PTHREAD_MAX_NAMELEN_NP]; 842 char *oldname, *cp, newname[PTHREAD_MAX_NAMELEN_NP];
830 int namelen; 843 int namelen;
831 844
 845 pthread__error(EINVAL, "Invalid thread",
 846 thread->pt_magic == PT_MAGIC);
 847
832 if (pthread__find(thread) != 0) 848 if (pthread__find(thread) != 0)
833 return ESRCH; 849 return ESRCH;
834 850
835 if (thread->pt_magic != PT_MAGIC) 
836 return EINVAL; 
837 
838 namelen = snprintf(newname, sizeof(newname), name, arg); 851 namelen = snprintf(newname, sizeof(newname), name, arg);
839 if (namelen >= PTHREAD_MAX_NAMELEN_NP) 852 if (namelen >= PTHREAD_MAX_NAMELEN_NP)
840 return EINVAL; 853 return EINVAL;
841 854
842 cp = strdup(newname); 855 cp = strdup(newname);
843 if (cp == NULL) 856 if (cp == NULL)
844 return ENOMEM; 857 return ENOMEM;
845 858
846 pthread_mutex_lock(&thread->pt_lock); 859 pthread_mutex_lock(&thread->pt_lock);
847 oldname = thread->pt_name; 860 oldname = thread->pt_name;
848 thread->pt_name = cp; 861 thread->pt_name = cp;
849 (void)_lwp_setname(thread->pt_lid, cp); 862 (void)_lwp_setname(thread->pt_lid, cp);
850 pthread_mutex_unlock(&thread->pt_lock); 863 pthread_mutex_unlock(&thread->pt_lock);
@@ -860,26 +873,29 @@ pthread_t @@ -860,26 +873,29 @@ pthread_t
860pthread_self(void) 873pthread_self(void)
861{ 874{
862 if (__predict_false(__uselibcstub)) 875 if (__predict_false(__uselibcstub))
863 return (pthread_t)__libc_thr_self_stub(); 876 return (pthread_t)__libc_thr_self_stub();
864 877
865 return pthread__self(); 878 return pthread__self();
866} 879}
867 880
868 881
869int 882int
870pthread_cancel(pthread_t thread) 883pthread_cancel(pthread_t thread)
871{ 884{
872 885
 886 pthread__error(EINVAL, "Invalid thread",
 887 thread->pt_magic == PT_MAGIC);
 888
873 if (pthread__find(thread) != 0) 889 if (pthread__find(thread) != 0)
874 return ESRCH; 890 return ESRCH;
875 pthread_mutex_lock(&thread->pt_lock); 891 pthread_mutex_lock(&thread->pt_lock);
876 thread->pt_flags |= PT_FLAG_CS_PENDING; 892 thread->pt_flags |= PT_FLAG_CS_PENDING;
877 if ((thread->pt_flags & PT_FLAG_CS_DISABLED) == 0) { 893 if ((thread->pt_flags & PT_FLAG_CS_DISABLED) == 0) {
878 thread->pt_cancel = 1; 894 thread->pt_cancel = 1;
879 pthread_mutex_unlock(&thread->pt_lock); 895 pthread_mutex_unlock(&thread->pt_lock);
880 _lwp_wakeup(thread->pt_lid); 896 _lwp_wakeup(thread->pt_lid);
881 } else 897 } else
882 pthread_mutex_unlock(&thread->pt_lock); 898 pthread_mutex_unlock(&thread->pt_lock);
883 899
884 return 0; 900 return 0;
885} 901}

cvs diff -r1.2 -r1.3 src/lib/libpthread/pthread_getcpuclockid.c (expand / switch to unified diff)

--- src/lib/libpthread/pthread_getcpuclockid.c 2017/03/04 11:16:33 1.2
+++ src/lib/libpthread/pthread_getcpuclockid.c 2020/01/29 16:03:44 1.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: pthread_getcpuclockid.c,v 1.2 2017/03/04 11:16:33 njoly Exp $ */ 1/* $NetBSD: pthread_getcpuclockid.c,v 1.3 2020/01/29 16:03:44 kamil Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2016 The NetBSD Foundation, Inc. 4 * Copyright (c) 2016 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christos Zoulas. 8 * by Christos Zoulas.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -20,35 +20,38 @@ @@ -20,35 +20,38 @@
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 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 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 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 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32#if defined(LIBC_SCCS) && !defined(lint) 32#if defined(LIBC_SCCS) && !defined(lint)
33__RCSID("$NetBSD: pthread_getcpuclockid.c,v 1.2 2017/03/04 11:16:33 njoly Exp $"); 33__RCSID("$NetBSD: pthread_getcpuclockid.c,v 1.3 2020/01/29 16:03:44 kamil Exp $");
34#endif /* LIBC_SCCS and not lint */ 34#endif /* LIBC_SCCS and not lint */
35 35
36#include <sys/types.h> 36#include <sys/types.h>
37#include <errno.h> 37#include <errno.h>
38#include <pthread.h> 38#include <pthread.h>
39#include <time.h> 39#include <time.h>
40 40
41#include "pthread_int.h" 41#include "pthread_int.h"
42 42
43int 43int
44pthread_getcpuclockid(pthread_t thread, clockid_t *clock_id) 44pthread_getcpuclockid(pthread_t thread, clockid_t *clock_id)
45{ 45{
46 int error = 0, saved_errno; 46 int error = 0, saved_errno;
47 47
 48 pthread__error(EINVAL, "Invalid thread",
 49 thread->pt_magic == PT_MAGIC);
 50
48 saved_errno = errno; 51 saved_errno = errno;
49 if (clock_getcpuclockid2(P_LWPID, (id_t)thread->pt_lid, clock_id) == -1) 52 if (clock_getcpuclockid2(P_LWPID, (id_t)thread->pt_lid, clock_id) == -1)
50 error = errno; 53 error = errno;
51 errno = saved_errno; 54 errno = saved_errno;
52 55
53 return error; 56 return error;
54} 57}