Annotation of sys/compat/common/kern_ipc_35.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: kern_ipc_35.c,v 1.3 2004/07/15 11:00:12 millert Exp $ */
2:
3: /*
4: * Copyright (c) 2004 Todd C. Miller <Todd.Miller@courtesan.com>
5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18:
19: #include <sys/param.h>
20: #include <sys/systm.h>
21: #include <sys/kernel.h>
22: #include <sys/proc.h>
23: #include <sys/msg.h>
24: #include <sys/sem.h>
25: #include <sys/shm.h>
26:
27: #include <sys/mount.h>
28: #include <sys/syscallargs.h>
29:
30: #ifdef SYSVMSG
31: /*
32: * Old-style shmget(2) used int for the size parameter, we now use size_t.
33: */
34: int
35: compat_35_sys_shmget(struct proc *p, void *v, register_t *retval)
36: {
37: struct compat_35_sys_shmget_args /* {
38: syscallarg(key_t) key;
39: syscallarg(int) size;
40: syscallarg(int) shmflg;
41: } */ *uap = v;
42: struct sys_shmget_args /* {
43: syscallarg(key_t) key;
44: syscallarg(size_t) size;
45: syscallarg(int) shmflg;
46: } */ shmget_args;
47:
48: SCARG(&shmget_args, key) = SCARG(uap, key);
49: SCARG(&shmget_args, size) = (size_t)SCARG(uap, size);
50: SCARG(&shmget_args, shmflg) = SCARG(uap, shmflg);
51:
52: return (sys_shmget(p, &shmget_args, retval));
53: }
54: #endif
55:
56: #ifdef SYSVSEM
57: /*
58: * Old-style shmget(2) used u_int for the nsops parameter, we now use size_t.
59: */
60: int
61: compat_35_sys_semop(struct proc *p, void *v, register_t *retval)
62: {
63: struct compat_35_sys_semop_args /* {
64: syscallarg(int) semid;
65: syscallarg(struct sembuf *) sops;
66: syscallarg(u_int) nsops;
67: } */ *uap = v;
68: struct sys_semop_args /* {
69: syscallarg(int) semid;
70: syscallarg(struct sembuf *) sops;
71: syscallarg(size_t) nsops;
72: } */ semop_args;
73:
74: SCARG(&semop_args, semid) = SCARG(uap, semid);
75: SCARG(&semop_args, sops) = SCARG(uap, sops);
76: SCARG(&semop_args, nsops) = (size_t)SCARG(uap, nsops);
77:
78: return (sys_semop(p, &semop_args, retval));
79: }
80: #endif
81:
82: /*
83: * Convert between new and old struct {msq,sem,shm}id_ds (both ways)
84: */
85: #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
86: #define cvt_ds(to, from, type, base) do { \
87: (to)->type##_perm.cuid = (from)->type##_perm.cuid; \
88: (to)->type##_perm.cgid = (from)->type##_perm.cgid; \
89: (to)->type##_perm.uid = (from)->type##_perm.uid; \
90: (to)->type##_perm.gid = (from)->type##_perm.gid; \
91: (to)->type##_perm.mode = (from)->type##_perm.mode & 0xffffU; \
92: (to)->type##_perm.seq = (from)->type##_perm.seq; \
93: (to)->type##_perm.key = (from)->type##_perm.key; \
94: bcopy((caddr_t)&(from)->base, (caddr_t)&(to)->base, \
95: sizeof(*(to)) - ((caddr_t)&(to)->base - (caddr_t)to)); \
96: } while (0)
97: #endif /* SYSVMSG || SYSVSEM || SYSVSHM */
98:
99: #ifdef SYSVMSG
100: /*
101: * Copy a struct msqid_ds35 from userland and convert to struct msqid_ds
102: */
103: static int
104: msqid_copyin(const void *uaddr, void *kaddr, size_t len)
105: {
106: struct msqid_ds *msqbuf = kaddr;
107: struct msqid_ds35 omsqbuf;
108: int error;
109:
110: if (len != sizeof(struct msqid_ds))
111: return (EFAULT);
112: if ((error = copyin(uaddr, &omsqbuf, sizeof(omsqbuf))) == 0)
113: cvt_ds(msqbuf, &omsqbuf, msg, msg_first);
114: return (error);
115: }
116:
117: /*
118: * Convert a struct msqid_ds to struct msqid_ds35 and copy to userland
119: */
120: static int
121: msqid_copyout(const void *kaddr, void *uaddr, size_t len)
122: {
123: const struct msqid_ds *msqbuf = kaddr;
124: struct msqid_ds35 omsqbuf;
125:
126: if (len != sizeof(struct msqid_ds))
127: return (EFAULT);
128: cvt_ds(&omsqbuf, msqbuf, msg, msg_first);
129: return (copyout(&omsqbuf, uaddr, sizeof(omsqbuf)));
130: }
131:
132: /*
133: * OpenBSD 3.5 msgctl(2) with 16bit mode_t in struct ipcperm.
134: */
135: int
136: compat_35_sys_msgctl(struct proc *p, void *v, register_t *retval)
137: {
138: struct compat_35_sys_msgctl_args /* {
139: syscallarg(int) msqid;
140: syscallarg(int) cmd;
141: syscallarg(struct msqid_ds35 *) buf;
142: } */ *uap = v;
143:
144: return (msgctl1(p, SCARG(uap, msqid), SCARG(uap, cmd),
145: (caddr_t)SCARG(uap, buf), msqid_copyin, msqid_copyout));
146: }
147: #endif /* SYSVMSG */
148:
149: #ifdef SYSVSEM
150: /*
151: * Copy a struct semid_ds35 from userland and convert to struct semid_ds
152: */
153: static int
154: semid_copyin(const void *uaddr, void *kaddr, size_t len)
155: {
156: struct semid_ds *sembuf = kaddr;
157: struct semid_ds35 osembuf;
158: int error;
159:
160: if (len != sizeof(struct semid_ds))
161: return (EFAULT);
162: if ((error = copyin(uaddr, &osembuf, sizeof(osembuf))) == 0)
163: cvt_ds(sembuf, &osembuf, sem, sem_base);
164: return (error);
165: }
166:
167: /*
168: * Convert a struct semid_ds to struct semid_ds35 and copy to userland
169: */
170: static int
171: semid_copyout(const void *kaddr, void *uaddr, size_t len)
172: {
173: const struct semid_ds *sembuf = kaddr;
174: struct semid_ds35 osembuf;
175:
176: if (len != sizeof(struct semid_ds))
177: return (EFAULT);
178: cvt_ds(&osembuf, sembuf, sem, sem_base);
179: return (copyout(&osembuf, uaddr, sizeof(osembuf)));
180: }
181:
182: /*
183: * OpenBSD 3.5 semctl(2) with 16bit mode_t in struct ipcperm.
184: */
185: int
186: compat_35_sys___semctl(struct proc *p, void *v, register_t *retval)
187: {
188: struct compat_35_sys___semctl_args /* {
189: syscallarg(int) semid;
190: syscallarg(int) semnum;
191: syscallarg(int) cmd;
192: syscallarg(union semun *) arg;
193: } */ *uap = v;
194: union semun arg;
195: int error = 0, cmd = SCARG(uap, cmd);
196:
197: switch (cmd) {
198: case IPC_SET:
199: case IPC_STAT:
200: case GETALL:
201: case SETVAL:
202: case SETALL:
203: error = copyin(SCARG(uap, arg), &arg, sizeof(arg));
204: break;
205: }
206: if (error == 0) {
207: error = semctl1(p, SCARG(uap, semid), SCARG(uap, semnum),
208: cmd, &arg, retval, semid_copyin, semid_copyout);
209: }
210: return (error);
211: }
212: #endif /* SYSVSEM */
213:
214: #ifdef SYSVSHM
215: /*
216: * Copy a struct shmid_ds35 from userland and convert to struct shmid_ds
217: */
218: static int
219: shmid_copyin(const void *uaddr, void *kaddr, size_t len)
220: {
221: struct shmid_ds *shmbuf = kaddr;
222: struct shmid_ds35 oshmbuf;
223: int error;
224:
225: if (len != sizeof(struct shmid_ds))
226: return (EFAULT);
227: if ((error = copyin(uaddr, &oshmbuf, sizeof(oshmbuf))) == 0)
228: cvt_ds(shmbuf, &oshmbuf, shm, shm_segsz);
229: return (error);
230: }
231:
232: /*
233: * Convert a struct shmid_ds to struct shmid_ds35 and copy to userland
234: */
235: static int
236: shmid_copyout(const void *kaddr, void *uaddr, size_t len)
237: {
238: const struct shmid_ds *shmbuf = kaddr;
239: struct shmid_ds35 oshmbuf;
240:
241: if (len != sizeof(struct shmid_ds))
242: return (EFAULT);
243: cvt_ds(&oshmbuf, shmbuf, shm, shm_segsz);
244: return (copyout(&oshmbuf, uaddr, sizeof(oshmbuf)));
245: }
246:
247: /*
248: * OpenBSD 3.5 shmctl(2) with 16bit mode_t in struct ipcperm.
249: */
250: int
251: compat_35_sys_shmctl(struct proc *p, void *v, register_t *retval)
252: {
253: struct compat_35_sys_shmctl_args /* {
254: syscallarg(int) shmid;
255: syscallarg(int) cmd;
256: syscallarg(struct shmid_ds35 *) buf;
257: } */ *uap = v;
258:
259: return (shmctl1(p, SCARG(uap, shmid), SCARG(uap, cmd),
260: (caddr_t)SCARG(uap, buf), shmid_copyin, shmid_copyout));
261: }
262: #endif /* SYSVSHM */
CVSweb