ibcs2_ipc.c revision 330897
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 1995 Scott Bartram
5 * Copyright (c) 1995 Steven Wallace
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. The name of the author may not be used to endorse or promote products
14 *    derived from this software without specific prior written permission
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: stable/11/sys/i386/ibcs2/ibcs2_ipc.c 330897 2018-03-14 03:19:51Z eadler $");
30
31#include <sys/param.h>
32#include <sys/systm.h>
33#include <sys/limits.h>
34#include <sys/msg.h>
35#include <sys/sem.h>
36#include <sys/shm.h>
37#include <sys/syscallsubr.h>
38#include <sys/sysproto.h>
39
40#include <i386/ibcs2/ibcs2_types.h>
41#include <i386/ibcs2/ibcs2_signal.h>
42#include <i386/ibcs2/ibcs2_proto.h>
43#include <i386/ibcs2/ibcs2_util.h>
44#include <i386/ibcs2/ibcs2_ipc.h>
45
46#define IBCS2_IPC_RMID	0
47#define IBCS2_IPC_SET	1
48#define IBCS2_IPC_STAT	2
49#define IBCS2_SETVAL	8
50
51
52
53static void cvt_msqid2imsqid(struct msqid_ds *, struct ibcs2_msqid_ds *);
54static void cvt_imsqid2msqid(struct ibcs2_msqid_ds *, struct msqid_ds *);
55#ifdef unused
56static void cvt_sem2isem(struct sem *, struct ibcs2_sem *);
57static void cvt_isem2sem(struct ibcs2_sem *, struct sem *);
58#endif
59static void cvt_semid2isemid(struct semid_ds *, struct ibcs2_semid_ds *);
60static void cvt_isemid2semid(struct ibcs2_semid_ds *, struct semid_ds *);
61static void cvt_shmid2ishmid(struct shmid_ds *, struct ibcs2_shmid_ds *);
62static void cvt_ishmid2shmid(struct ibcs2_shmid_ds *, struct shmid_ds *);
63static void cvt_perm2iperm(struct ipc_perm *, struct ibcs2_ipc_perm *);
64static void cvt_iperm2perm(struct ibcs2_ipc_perm *, struct ipc_perm *);
65
66
67/*
68 * iBCS2 msgsys call
69 */
70
71static void
72cvt_msqid2imsqid(bp, ibp)
73struct msqid_ds *bp;
74struct ibcs2_msqid_ds *ibp;
75{
76	cvt_perm2iperm(&bp->msg_perm, &ibp->msg_perm);
77	ibp->msg_first = bp->msg_first;
78	ibp->msg_last = bp->msg_last;
79	ibp->msg_cbytes = (u_short)bp->msg_cbytes;
80	ibp->msg_qnum = (u_short)bp->msg_qnum;
81	ibp->msg_qbytes = (u_short)bp->msg_qbytes;
82	ibp->msg_lspid = (u_short)bp->msg_lspid;
83	ibp->msg_lrpid = (u_short)bp->msg_lrpid;
84	ibp->msg_stime = bp->msg_stime;
85	ibp->msg_rtime = bp->msg_rtime;
86	ibp->msg_ctime = bp->msg_ctime;
87	return;
88}
89
90static void
91cvt_imsqid2msqid(ibp, bp)
92struct ibcs2_msqid_ds *ibp;
93struct msqid_ds *bp;
94{
95	cvt_iperm2perm(&ibp->msg_perm, &bp->msg_perm);
96	bp->msg_first = ibp->msg_first;
97	bp->msg_last = ibp->msg_last;
98	bp->msg_cbytes = ibp->msg_cbytes;
99	bp->msg_qnum = ibp->msg_qnum;
100	bp->msg_qbytes = ibp->msg_qbytes;
101	bp->msg_lspid = ibp->msg_lspid;
102	bp->msg_lrpid = ibp->msg_lrpid;
103	bp->msg_stime = ibp->msg_stime;
104	bp->msg_rtime = ibp->msg_rtime;
105	bp->msg_ctime = ibp->msg_ctime;
106	return;
107}
108
109struct ibcs2_msgget_args {
110	int what;
111	ibcs2_key_t key;
112	int msgflg;
113};
114
115static int
116ibcs2_msgget(struct thread *td, void *v)
117{
118	struct ibcs2_msgget_args *uap = v;
119	struct msgget_args ap;
120
121	ap.key = uap->key;
122	ap.msgflg = uap->msgflg;
123	return sys_msgget(td, &ap);
124}
125
126struct ibcs2_msgctl_args {
127	int what;
128	int msqid;
129	int cmd;
130	struct ibcs2_msqid_ds *buf;
131};
132
133static int
134ibcs2_msgctl(struct thread *td, void *v)
135{
136	struct ibcs2_msgctl_args *uap = v;
137	struct ibcs2_msqid_ds is;
138	struct msqid_ds bs;
139	int error;
140
141	switch (uap->cmd) {
142	case IBCS2_IPC_STAT:
143		error = kern_msgctl(td, uap->msqid, IPC_STAT, &bs);
144		if (!error) {
145			cvt_msqid2imsqid(&bs, &is);
146			error = copyout(&is, uap->buf, sizeof(is));
147		}
148		return (error);
149	case IBCS2_IPC_SET:
150		error = copyin(uap->buf, &is, sizeof(is));
151		if (error)
152			return (error);
153		cvt_imsqid2msqid(&is, &bs);
154		return (kern_msgctl(td, uap->msqid, IPC_SET, &bs));
155	case IBCS2_IPC_RMID:
156		return (kern_msgctl(td, uap->msqid, IPC_RMID, NULL));
157	}
158	return (EINVAL);
159}
160
161struct ibcs2_msgrcv_args {
162	int what;
163	int msqid;
164	void *msgp;
165	size_t msgsz;
166	long msgtyp;
167	int msgflg;
168};
169
170static int
171ibcs2_msgrcv(struct thread *td, void *v)
172{
173	struct ibcs2_msgrcv_args *uap = v;
174	struct msgrcv_args ap;
175
176	ap.msqid = uap->msqid;
177	ap.msgp = uap->msgp;
178	ap.msgsz = uap->msgsz;
179	ap.msgtyp = uap->msgtyp;
180	ap.msgflg = uap->msgflg;
181	return (sys_msgrcv(td, &ap));
182}
183
184struct ibcs2_msgsnd_args {
185	int what;
186	int msqid;
187	void *msgp;
188	size_t msgsz;
189	int msgflg;
190};
191
192static int
193ibcs2_msgsnd(struct thread *td, void *v)
194{
195	struct ibcs2_msgsnd_args *uap = v;
196	struct msgsnd_args ap;
197
198	ap.msqid = uap->msqid;
199	ap.msgp = uap->msgp;
200	ap.msgsz = uap->msgsz;
201	ap.msgflg = uap->msgflg;
202	return (sys_msgsnd(td, &ap));
203}
204
205int
206ibcs2_msgsys(td, uap)
207	struct thread *td;
208	struct ibcs2_msgsys_args *uap;
209{
210	switch (uap->which) {
211	case 0:
212		return (ibcs2_msgget(td, uap));
213	case 1:
214		return (ibcs2_msgctl(td, uap));
215	case 2:
216		return (ibcs2_msgrcv(td, uap));
217	case 3:
218		return (ibcs2_msgsnd(td, uap));
219	default:
220		return (EINVAL);
221	}
222}
223
224/*
225 * iBCS2 semsys call
226 */
227#ifdef unused
228static void
229cvt_sem2isem(bp, ibp)
230struct sem *bp;
231struct ibcs2_sem *ibp;
232{
233	ibp->semval = bp->semval;
234	ibp->sempid = bp->sempid;
235	ibp->semncnt = bp->semncnt;
236	ibp->semzcnt = bp->semzcnt;
237	return;
238}
239
240static void
241cvt_isem2sem(ibp, bp)
242struct ibcs2_sem *ibp;
243struct sem *bp;
244{
245	bp->semval = ibp->semval;
246	bp->sempid = ibp->sempid;
247	bp->semncnt = ibp->semncnt;
248	bp->semzcnt = ibp->semzcnt;
249	return;
250}
251#endif
252
253static void
254cvt_iperm2perm(ipp, pp)
255struct ibcs2_ipc_perm *ipp;
256struct ipc_perm *pp;
257{
258	pp->uid = ipp->uid;
259	pp->gid = ipp->gid;
260	pp->cuid = ipp->cuid;
261	pp->cgid = ipp->cgid;
262	pp->mode = ipp->mode;
263	pp->seq = ipp->seq;
264	pp->key = ipp->key;
265}
266
267static void
268cvt_perm2iperm(pp, ipp)
269struct ipc_perm *pp;
270struct ibcs2_ipc_perm *ipp;
271{
272	ipp->uid = pp->uid;
273	ipp->gid = pp->gid;
274	ipp->cuid = pp->cuid;
275	ipp->cgid = pp->cgid;
276	ipp->mode = pp->mode;
277	ipp->seq = pp->seq;
278	ipp->key = pp->key;
279}
280
281static void
282cvt_semid2isemid(bp, ibp)
283struct semid_ds *bp;
284struct ibcs2_semid_ds *ibp;
285{
286	cvt_perm2iperm(&bp->sem_perm, &ibp->sem_perm);
287	ibp->sem_base = (struct ibcs2_sem *)bp->sem_base;
288	ibp->sem_nsems = bp->sem_nsems;
289	ibp->sem_otime = bp->sem_otime;
290	ibp->sem_ctime = bp->sem_ctime;
291	return;
292}
293
294static void
295cvt_isemid2semid(ibp, bp)
296struct ibcs2_semid_ds *ibp;
297struct semid_ds *bp;
298{
299	cvt_iperm2perm(&ibp->sem_perm, &bp->sem_perm);
300	bp->sem_base = (struct sem *)ibp->sem_base;
301	bp->sem_nsems = ibp->sem_nsems;
302	bp->sem_otime = ibp->sem_otime;
303	bp->sem_ctime = ibp->sem_ctime;
304	return;
305}
306
307struct ibcs2_semctl_args {
308	int what;
309	int semid;
310	int semnum;
311	int cmd;
312	union semun arg;
313};
314
315static int
316ibcs2_semctl(struct thread *td, void *v)
317{
318	struct ibcs2_semctl_args *uap = v;
319	struct ibcs2_semid_ds is;
320	struct semid_ds bs;
321	union semun semun;
322	register_t rval;
323	int error;
324
325	switch(uap->cmd) {
326	case IBCS2_IPC_STAT:
327		semun.buf = &bs;
328		error = kern_semctl(td, uap->semid, uap->semnum, IPC_STAT,
329		    &semun, &rval);
330		if (error)
331			return (error);
332		cvt_semid2isemid(&bs, &is);
333		error = copyout(&is, uap->arg.buf, sizeof(is));
334		if (error == 0)
335			td->td_retval[0] = rval;
336		return (error);
337
338	case IBCS2_IPC_SET:
339		error = copyin(uap->arg.buf, &is, sizeof(is));
340		if (error)
341			return (error);
342		cvt_isemid2semid(&is, &bs);
343		semun.buf = &bs;
344		return (kern_semctl(td, uap->semid, uap->semnum, IPC_SET,
345		    &semun, td->td_retval));
346	}
347
348	return (kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &uap->arg,
349	    td->td_retval));
350}
351
352struct ibcs2_semget_args {
353	int what;
354	ibcs2_key_t key;
355	int nsems;
356	int semflg;
357};
358
359static int
360ibcs2_semget(struct thread *td, void *v)
361{
362	struct ibcs2_semget_args *uap = v;
363	struct semget_args ap;
364
365	ap.key = uap->key;
366	ap.nsems = uap->nsems;
367	ap.semflg = uap->semflg;
368	return (sys_semget(td, &ap));
369}
370
371struct ibcs2_semop_args {
372	int what;
373	int semid;
374	struct sembuf *sops;
375	size_t nsops;
376};
377
378static int
379ibcs2_semop(struct thread *td, void *v)
380{
381	struct ibcs2_semop_args *uap = v;
382	struct semop_args ap;
383
384	ap.semid = uap->semid;
385	ap.sops = uap->sops;
386	ap.nsops = uap->nsops;
387	return (sys_semop(td, &ap));
388}
389
390int
391ibcs2_semsys(td, uap)
392	struct thread *td;
393	struct ibcs2_semsys_args *uap;
394{
395
396	switch (uap->which) {
397	case 0:
398		return (ibcs2_semctl(td, uap));
399	case 1:
400		return (ibcs2_semget(td, uap));
401	case 2:
402		return (ibcs2_semop(td, uap));
403	}
404	return (EINVAL);
405}
406
407
408/*
409 * iBCS2 shmsys call
410 */
411
412static void
413cvt_shmid2ishmid(bp, ibp)
414struct shmid_ds *bp;
415struct ibcs2_shmid_ds *ibp;
416{
417	cvt_perm2iperm(&bp->shm_perm, &ibp->shm_perm);
418	ibp->shm_segsz = bp->shm_segsz;
419	ibp->shm_lpid = bp->shm_lpid;
420	ibp->shm_cpid = bp->shm_cpid;
421	if (bp->shm_nattch > SHRT_MAX)
422		ibp->shm_nattch = SHRT_MAX;
423	else
424		ibp->shm_nattch = bp->shm_nattch;
425	ibp->shm_cnattch = 0;			/* ignored anyway */
426	ibp->shm_atime = bp->shm_atime;
427	ibp->shm_dtime = bp->shm_dtime;
428	ibp->shm_ctime = bp->shm_ctime;
429	return;
430}
431
432static void
433cvt_ishmid2shmid(ibp, bp)
434struct ibcs2_shmid_ds *ibp;
435struct shmid_ds *bp;
436{
437	cvt_iperm2perm(&ibp->shm_perm, &bp->shm_perm);
438	bp->shm_segsz = ibp->shm_segsz;
439	bp->shm_lpid = ibp->shm_lpid;
440	bp->shm_cpid = ibp->shm_cpid;
441	bp->shm_nattch = ibp->shm_nattch;
442	bp->shm_atime = ibp->shm_atime;
443	bp->shm_dtime = ibp->shm_dtime;
444	bp->shm_ctime = ibp->shm_ctime;
445	return;
446}
447
448struct ibcs2_shmat_args {
449	int what;
450	int shmid;
451	const void *shmaddr;
452	int shmflg;
453};
454
455static int
456ibcs2_shmat(struct thread *td, void *v)
457{
458	struct ibcs2_shmat_args *uap = v;
459	struct shmat_args ap;
460
461	ap.shmid = uap->shmid;
462	ap.shmaddr = uap->shmaddr;
463	ap.shmflg = uap->shmflg;
464	return (sys_shmat(td, &ap));
465}
466
467struct ibcs2_shmctl_args {
468	int what;
469	int shmid;
470	int cmd;
471	struct ibcs2_shmid_ds *buf;
472};
473
474static int
475ibcs2_shmctl(struct thread *td, void *v)
476{
477	struct ibcs2_shmctl_args *uap = v;
478	struct ibcs2_shmid_ds is;
479	struct shmid_ds bs;
480	int error;
481
482	switch(uap->cmd) {
483	case IBCS2_IPC_STAT:
484		error = kern_shmctl(td, uap->shmid, IPC_STAT, &bs, NULL);
485		if (error)
486			return (error);
487		cvt_shmid2ishmid(&bs, &is);
488		return (copyout(&is, uap->buf, sizeof(is)));
489
490	case IBCS2_IPC_SET:
491		error = copyin(uap->buf, &is, sizeof(is));
492		if (error)
493			return (error);
494		cvt_ishmid2shmid(&is, &bs);
495		return (kern_shmctl(td, uap->shmid, IPC_SET, &bs, NULL));
496
497	case IPC_INFO:
498	case SHM_INFO:
499	case SHM_STAT:
500		/* XXX: */
501		return (EINVAL);
502	}
503
504	return (kern_shmctl(td, uap->shmid, uap->cmd, NULL, NULL));
505}
506
507struct ibcs2_shmdt_args {
508	int what;
509	const void *shmaddr;
510};
511
512static int
513ibcs2_shmdt(struct thread *td, void *v)
514{
515	struct ibcs2_shmdt_args *uap = v;
516	struct shmdt_args ap;
517
518	ap.shmaddr = uap->shmaddr;
519	return (sys_shmdt(td, &ap));
520}
521
522struct ibcs2_shmget_args {
523	int what;
524	ibcs2_key_t key;
525	size_t size;
526	int shmflg;
527};
528
529static int
530ibcs2_shmget(struct thread *td, void *v)
531{
532	struct ibcs2_shmget_args *uap = v;
533	struct shmget_args ap;
534
535	ap.key = uap->key;
536	ap.size = uap->size;
537	ap.shmflg = uap->shmflg;
538	return (sys_shmget(td, &ap));
539}
540
541int
542ibcs2_shmsys(td, uap)
543	struct thread *td;
544	struct ibcs2_shmsys_args *uap;
545{
546
547	switch (uap->which) {
548	case 0:
549		return (ibcs2_shmat(td, uap));
550	case 1:
551		return (ibcs2_shmctl(td, uap));
552	case 2:
553		return (ibcs2_shmdt(td, uap));
554	case 3:
555		return (ibcs2_shmget(td, uap));
556	}
557	return (EINVAL);
558}
559
560MODULE_DEPEND(ibcs2, sysvmsg, 1, 1, 1);
561MODULE_DEPEND(ibcs2, sysvsem, 1, 1, 1);
562MODULE_DEPEND(ibcs2, sysvshm, 1, 1, 1);
563