• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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