1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2017 Xiao yang <yangx.jy@cn.fujitsu.com>
4 */
5
6 #include <sys/types.h>
7 #include <sys/ipc.h>
8 #include <sys/msg.h>
9 #include <sys/shm.h>
10 #define TST_NO_DEFAULT_MAIN
11 #include "tst_test.h"
12 #include "tst_safe_sysv_ipc.h"
13 #include "lapi/sem.h"
14
15 /*
16 * The IPC_STAT, IPC_SET, IPC_RMID can return either 0 or -1.
17 */
msg_ret_check(int cmd,int ret)18 static int msg_ret_check(int cmd, int ret)
19 {
20 switch (cmd) {
21 case IPC_STAT:
22 case IPC_SET:
23 case IPC_RMID:
24 return ret != 0;
25 default:
26 return ret < 0;
27 }
28 }
29
30 /*
31 * The IPC_STAT, IPC_SET, IPC_RMID, SHM_LOCK, SHM_UNLOCK can return either 0 or -1.
32 */
shm_ret_check(int cmd,int ret)33 static int shm_ret_check(int cmd, int ret)
34 {
35 switch (cmd) {
36 case IPC_STAT:
37 case IPC_SET:
38 case IPC_RMID:
39 case SHM_LOCK:
40 case SHM_UNLOCK:
41 return ret != 0;
42 default:
43 return ret < 0;
44 }
45 }
46
47 /*
48 * The IPC_STAT, IPC_SET, IPC_RMID, SETALL, SETVAL can return either 0 or -1.
49 */
sem_ret_check(int cmd,int ret)50 static int sem_ret_check(int cmd, int ret)
51 {
52 switch (cmd) {
53 case IPC_STAT:
54 case IPC_SET:
55 case IPC_RMID:
56 case SETALL:
57 case SETVAL:
58 return ret != 0;
59 default:
60 return ret < 0;
61 }
62 }
63
safe_msgget(const char * file,const int lineno,key_t key,int msgflg)64 int safe_msgget(const char *file, const int lineno, key_t key, int msgflg)
65 {
66 int rval;
67
68 rval = msgget(key, msgflg);
69
70 if (rval == -1) {
71 tst_brk_(file, lineno, TBROK | TERRNO, "msgget(%i, %x) failed",
72 (int)key, msgflg);
73 } else if (rval < 0) {
74 tst_brk_(file, lineno, TBROK | TERRNO,
75 "Invalid msgget(%i, %x) return value %d", (int)key,
76 msgflg, rval);
77 }
78
79 return rval;
80 }
81
safe_msgsnd(const char * file,const int lineno,int msqid,const void * msgp,size_t msgsz,int msgflg)82 int safe_msgsnd(const char *file, const int lineno, int msqid, const void *msgp,
83 size_t msgsz, int msgflg)
84 {
85 int rval;
86
87 rval = msgsnd(msqid, msgp, msgsz, msgflg);
88
89 if (rval == -1) {
90 tst_brk_(file, lineno, TBROK | TERRNO,
91 "msgsnd(%i, %p, %zu, %x) failed", msqid, msgp, msgsz,
92 msgflg);
93 } else if (rval) {
94 tst_brk_(file, lineno, TBROK | TERRNO,
95 "Invalid msgsnd(%i, %p, %zu, %x) return value %d",
96 msqid, msgp, msgsz, msgflg, rval);
97 }
98
99 return rval;
100 }
101
safe_msgrcv(const char * file,const int lineno,int msqid,void * msgp,size_t msgsz,long msgtyp,int msgflg)102 ssize_t safe_msgrcv(const char *file, const int lineno, int msqid, void *msgp,
103 size_t msgsz, long msgtyp, int msgflg)
104 {
105 ssize_t rval;
106
107 rval = msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
108
109 if (rval == -1) {
110 tst_brk_(file, lineno, TBROK | TERRNO,
111 "msgrcv(%i, %p, %zu, %li, %x) failed",
112 msqid, msgp, msgsz, msgtyp, msgflg);
113 } else if (rval < 0) {
114 tst_brk_(file, lineno, TBROK | TERRNO,
115 "Invalid msgrcv(%i, %p, %zu, %li, %x) return value %ld",
116 msqid, msgp, msgsz, msgtyp, msgflg, rval);
117 }
118
119 return rval;
120 }
121
safe_msgctl(const char * file,const int lineno,int msqid,int cmd,struct msqid_ds * buf)122 int safe_msgctl(const char *file, const int lineno, int msqid, int cmd,
123 struct msqid_ds *buf)
124 {
125 int rval;
126
127 rval = msgctl(msqid, cmd, buf);
128
129 if (rval == -1) {
130 tst_brk_(file, lineno, TBROK | TERRNO,
131 "msgctl(%i, %i, %p) failed", msqid, cmd, buf);
132 } else if (msg_ret_check(cmd, rval)) {
133 tst_brk_(file, lineno, TBROK | TERRNO,
134 "Invalid msgctl(%i, %i, %p) return value %d", msqid,
135 cmd, buf, rval);
136 }
137
138 return rval;
139 }
140
safe_shmget(const char * file,const int lineno,key_t key,size_t size,int shmflg)141 int safe_shmget(const char *file, const int lineno, key_t key, size_t size,
142 int shmflg)
143 {
144 int rval;
145
146 rval = shmget(key, size, shmflg);
147
148 if (rval == -1) {
149 tst_brk_(file, lineno, TBROK | TERRNO,
150 "shmget(%i, %zu, %x) failed", (int)key, size, shmflg);
151 } else if (rval < 0) {
152 tst_brk_(file, lineno, TBROK | TERRNO,
153 "Invalid shmget(%i, %zu, %x) return value %d",
154 (int)key, size, shmflg, rval);
155 }
156
157 return rval;
158 }
159
safe_shmat(const char * file,const int lineno,int shmid,const void * shmaddr,int shmflg)160 void *safe_shmat(const char *file, const int lineno, int shmid,
161 const void *shmaddr, int shmflg)
162 {
163 void *rval;
164
165 rval = shmat(shmid, shmaddr, shmflg);
166
167 if (rval == (void *)-1) {
168 tst_brk_(file, lineno, TBROK | TERRNO,
169 "shmat(%i, %p, %x) failed", shmid, shmaddr, shmflg);
170 }
171
172 return rval;
173 }
174
safe_shmdt(const char * file,const int lineno,const void * shmaddr)175 int safe_shmdt(const char *file, const int lineno, const void *shmaddr)
176 {
177 int rval;
178
179 rval = shmdt(shmaddr);
180
181 if (rval == -1) {
182 tst_brk_(file, lineno, TBROK | TERRNO, "shmdt(%p) failed",
183 shmaddr);
184 } else if (rval) {
185 tst_brk_(file, lineno, TBROK | TERRNO,
186 "Invalid shmdt(%p) return value %d", shmaddr, rval);
187 }
188
189 return rval;
190 }
191
safe_shmctl(const char * file,const int lineno,int shmid,int cmd,struct shmid_ds * buf)192 int safe_shmctl(const char *file, const int lineno, int shmid, int cmd,
193 struct shmid_ds *buf)
194 {
195 int rval;
196
197 rval = shmctl(shmid, cmd, buf);
198
199 if (rval == -1) {
200 tst_brk_(file, lineno, TBROK | TERRNO,
201 "shmctl(%i, %i, %p) failed", shmid, cmd, buf);
202 } else if (shm_ret_check(cmd, rval)) {
203 tst_brk_(file, lineno, TBROK | TERRNO,
204 "Invalid shmctl(%i, %i, %p) return value %d", shmid,
205 cmd, buf, rval);
206 }
207
208 return rval;
209 }
210
safe_semget(const char * file,const int lineno,key_t key,int nsems,int semflg)211 int safe_semget(const char *file, const int lineno, key_t key, int nsems,
212 int semflg)
213 {
214 int rval;
215
216 rval = semget(key, nsems, semflg);
217
218 if (rval == -1) {
219 tst_brk_(file, lineno, TBROK | TERRNO,
220 "semget(%i, %i, %x) failed", (int)key, nsems, semflg);
221 } else if (rval < 0) {
222 tst_brk_(file, lineno, TBROK | TERRNO,
223 "Invalid semget(%i, %i, %x) return value %d",
224 (int)key, nsems, semflg, rval);
225 }
226
227 return rval;
228 }
229
safe_semctl(const char * file,const int lineno,int semid,int semnum,int cmd,...)230 int safe_semctl(const char *file, const int lineno, int semid, int semnum,
231 int cmd, ...)
232 {
233 int rval;
234 va_list va;
235 union semun un;
236
237 va_start(va, cmd);
238
239 un = va_arg(va, union semun);
240
241 va_end(va);
242
243 rval = semctl(semid, semnum, cmd, un);
244
245 if (rval == -1) {
246 tst_brk_(file, lineno, TBROK | TERRNO,
247 "semctl(%i, %i, %i,...) failed", semid, semnum, cmd);
248 } else if (sem_ret_check(cmd, rval)) {
249 tst_brk_(file, lineno, TBROK | TERRNO,
250 "Invalid semctl(%i, %i, %i,...) return value %d", semid,
251 semnum, cmd, rval);
252 }
253
254 return rval;
255 }
256
safe_semop(const char * file,const int lineno,int semid,struct sembuf * sops,size_t nsops)257 int safe_semop(const char *file, const int lineno, int semid, struct sembuf *sops,
258 size_t nsops)
259 {
260 int rval;
261
262 rval = semop(semid, sops, nsops);
263 if (rval == -1) {
264 tst_brk_(file, lineno, TBROK | TERRNO,
265 "semop(%d, %p, %zu) failed", semid, sops, nsops);
266 } else if (rval < 0) {
267 tst_brk_(file, lineno, TBROK | TERRNO,
268 "Invalid semop(%d, %p, %zu) return value %d",
269 semid, sops, nsops, rval);
270 }
271
272 return rval;
273 }
274