• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <pthread.h>
17 #include <semaphore.h>
18 #include <stdio.h>
19 #include <errno.h>
20 #include <string.h>
21 #include "test.h"
22 #include <signal.h>
23 #include <sys/wait.h>
24 #include <sigchain.h>
25 #include "fortify_test.h"
26 #include "functionalext.h"
27 
28 #define T(f) if ((r=(f))) t_error(#f " failed: %s\n", strerror(r))
29 #define E(f) if (f) t_error(#f " failed: %s\n", strerror(errno))
30 
pthread_mutex_lock_after_destroyed(void * arg)31 static void *pthread_mutex_lock_after_destroyed(void *arg)
32 {
33     void **a = arg;
34 
35     *(int*)a[1] = pthread_mutex_lock(a[0]);
36     return 0;
37 }
38 
test_pthread_mutex_lock_after_destroyed(int mtype)39 static int test_pthread_mutex_lock_after_destroyed(int mtype)
40 {
41     pthread_t t;
42     pthread_mutex_t m;
43     pthread_mutexattr_t ma;
44     int i;
45     int r;
46     void *p;
47     void *a[] = {&m, &i};
48     T(pthread_mutexattr_init(&ma));
49     T(pthread_mutexattr_settype(&ma, mtype));
50     T(pthread_mutex_init(a[0], &ma));
51     T(pthread_mutexattr_destroy(&ma));
52     T(pthread_create(&t, 0, pthread_mutex_lock_after_destroyed, a));
53     T(pthread_mutex_destroy(a[0]));
54     T(pthread_join(t, &p));
55     return i;
56 }
57 
pthread_mutex_unlock_after_destroyed(void * arg)58 static void *pthread_mutex_unlock_after_destroyed(void *arg)
59 {
60     void **a = arg;
61 
62     *(int*)a[1] = pthread_mutex_unlock(a[0]);
63     return 0;
64 }
65 
test_pthread_mutex_unlock_after_destroyed(int mtype)66 static int test_pthread_mutex_unlock_after_destroyed(int mtype)
67 {
68     pthread_t t;
69     pthread_mutex_t m;
70     pthread_mutexattr_t ma;
71     int i;
72     int r;
73     void *p;
74     void *a[] = {&m, &i};
75     T(pthread_mutexattr_init(&ma));
76     T(pthread_mutexattr_settype(&ma, mtype));
77     T(pthread_mutex_init(a[0], &ma));
78     T(pthread_mutexattr_destroy(&ma));
79     T(pthread_create(&t, 0, pthread_mutex_unlock_after_destroyed, a));
80     T(pthread_mutex_destroy(a[0]));
81     T(pthread_join(t, &p));
82     return i;
83 }
84 
pthread_mutex_timedlock_after_destroyed(void * arg)85 static void *pthread_mutex_timedlock_after_destroyed(void *arg)
86 {
87     void **a = arg;
88     struct timespec ts;
89     clock_gettime(CLOCK_REALTIME, &ts);
90     ts.tv_sec += 1;
91     *(int*)a[1] = pthread_mutex_timedlock(a[0], &ts);
92     return 0;
93 }
94 
test_pthread_mutex_timedlock_after_destroyed(int mtype)95 static int test_pthread_mutex_timedlock_after_destroyed(int mtype)
96 {
97     pthread_t t;
98     pthread_mutex_t m;
99     pthread_mutexattr_t ma;
100     int i;
101     int r;
102     void *p;
103     void *a[] = {&m, &i};
104     T(pthread_mutexattr_init(&ma));
105     T(pthread_mutexattr_settype(&ma, mtype));
106     T(pthread_mutex_init(a[0], &ma));
107     T(pthread_mutexattr_destroy(&ma));
108     T(pthread_create(&t, 0, pthread_mutex_timedlock_after_destroyed, a));
109     T(pthread_mutex_destroy(a[0]));
110     T(pthread_join(t, &p));
111     return i;
112 }
113 
pthread_mutex_trylock_after_destroyed(void * arg)114 static void *pthread_mutex_trylock_after_destroyed(void *arg)
115 {
116     void **a = arg;
117 
118     *(int*)a[1] = pthread_mutex_trylock(a[0]);
119     return 0;
120 }
121 
test_pthread_mutex_trylock_after_destroyed(int mtype)122 static int test_pthread_mutex_trylock_after_destroyed(int mtype)
123 {
124     pthread_t t;
125     pthread_mutex_t m;
126     pthread_mutexattr_t ma;
127     int i;
128     int r;
129     void *p;
130     void *a[] = {&m, &i};
131     T(pthread_mutexattr_init(&ma));
132     T(pthread_mutexattr_settype(&ma, mtype));
133     T(pthread_mutex_init(a[0], &ma));
134     T(pthread_mutexattr_destroy(&ma));
135     T(pthread_create(&t, 0, pthread_mutex_trylock_after_destroyed, a));
136     T(pthread_mutex_destroy(a[0]));
137     T(pthread_join(t, &p));
138     return i;
139 }
140 
main(int argc,char * argv[])141 int main(int argc, char *argv[])
142 {
143     int i;
144 
145     i = test_pthread_mutex_lock_after_destroyed(PTHREAD_MUTEX_NORMAL);
146     if (i != 0) {
147         t_error("PTHREAD_MUTEX_NORMAL lock failed after destroyed, got %s\n", strerror(i));
148     }
149     i = test_pthread_mutex_lock_after_destroyed(PTHREAD_MUTEX_ERRORCHECK);
150     if (i != 0) {
151         t_error("PTHREAD_MUTEX_ERRORCHECK lock failed after destroyed, got %s\n", strerror(i));
152     }
153     i = test_pthread_mutex_lock_after_destroyed(PTHREAD_MUTEX_RECURSIVE);
154     if (i != 0) {
155         t_error("PTHREAD_MUTEX_RECURSIVE lock failed after destroyed, got %s\n", strerror(i));
156     }
157     i = test_pthread_mutex_unlock_after_destroyed(PTHREAD_MUTEX_ERRORCHECK);
158     if (i == 0) {
159         t_error("PTHREAD_MUTEX_ERRORCHECK unlock failed after destroyed, got %s\n", strerror(i));
160     }
161     i = test_pthread_mutex_unlock_after_destroyed(PTHREAD_MUTEX_RECURSIVE);
162     if (i == 0) {
163         t_error("PTHREAD_MUTEX_RECURSIVE unlock failed after destroyed, got %s\n", strerror(i));
164     }
165     i = test_pthread_mutex_timedlock_after_destroyed(PTHREAD_MUTEX_NORMAL);
166     if (i != 0) {
167         t_error("PTHREAD_MUTEX_NORMAL timedlock failed after destroyed, got %s\n", strerror(i));
168     }
169     i = test_pthread_mutex_timedlock_after_destroyed(PTHREAD_MUTEX_ERRORCHECK);
170     if (i != 0) {
171         t_error("PTHREAD_MUTEX_ERRORCHECK timedlock failed after destroyed, got %s\n", strerror(i));
172     }
173     i = test_pthread_mutex_timedlock_after_destroyed(PTHREAD_MUTEX_RECURSIVE);
174     if (i != 0) {
175         t_error("PTHREAD_MUTEX_RECURSIVE timedlock failed after destroyed, got %s\n", strerror(i));
176     }
177     i = test_pthread_mutex_trylock_after_destroyed(PTHREAD_MUTEX_ERRORCHECK);
178     if (i != 0) {
179         t_error("PTHREAD_MUTEX_NORMAL trylock failed after destroyed, got %s\n", strerror(i));
180     }
181     i = test_pthread_mutex_trylock_after_destroyed(PTHREAD_MUTEX_ERRORCHECK);
182     if (i != 0) {
183         t_error("PTHREAD_MUTEX_ERRORCHECK trylock failed after destroyed, got %s\n", strerror(i));
184     }
185     i = test_pthread_mutex_trylock_after_destroyed(PTHREAD_MUTEX_RECURSIVE);
186     if (i != 0) {
187         t_error("PTHREAD_MUTEX_RECURSIVE trylock failed after destroyed, got %s\n", strerror(i));
188     }
189     return t_status;
190 }