Deleted Added
full compact
sysv_msg.c (194910) sysv_msg.c (205323)
1/*-
2 * Implementation of SVID messages
3 *
4 * Author: Daniel Boulet
5 *
6 * Copyright 1993 Daniel Boulet and RTMX Inc.
7 *
8 * This system call was implemented by Daniel Boulet under contract from RTMX.

--- 34 unchanged lines hidden (view full) ---

43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 */
49
50#include <sys/cdefs.h>
1/*-
2 * Implementation of SVID messages
3 *
4 * Author: Daniel Boulet
5 *
6 * Copyright 1993 Daniel Boulet and RTMX Inc.
7 *
8 * This system call was implemented by Daniel Boulet under contract from RTMX.

--- 34 unchanged lines hidden (view full) ---

43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 */
49
50#include <sys/cdefs.h>
51__FBSDID("$FreeBSD: head/sys/kern/sysv_msg.c 194910 2009-06-24 21:10:52Z jhb $");
51__FBSDID("$FreeBSD: head/sys/kern/sysv_msg.c 205323 2010-03-19 11:04:42Z kib $");
52
53#include "opt_compat.h"
54#include "opt_sysvipc.h"
55
56#include <sys/param.h>
57#include <sys/systm.h>
58#include <sys/sysproto.h>
59#include <sys/kernel.h>

--- 9 unchanged lines hidden (view full) ---

69#include <sys/sysctl.h>
70#include <sys/malloc.h>
71#include <sys/jail.h>
72
73#include <security/mac/mac_framework.h>
74
75static MALLOC_DEFINE(M_MSG, "msg", "SVID compatible message queues");
76
52
53#include "opt_compat.h"
54#include "opt_sysvipc.h"
55
56#include <sys/param.h>
57#include <sys/systm.h>
58#include <sys/sysproto.h>
59#include <sys/kernel.h>

--- 9 unchanged lines hidden (view full) ---

69#include <sys/sysctl.h>
70#include <sys/malloc.h>
71#include <sys/jail.h>
72
73#include <security/mac/mac_framework.h>
74
75static MALLOC_DEFINE(M_MSG, "msg", "SVID compatible message queues");
76
77static void msginit(void);
77static int msginit(void);
78static int msgunload(void);
79static int sysvmsg_modload(struct module *, int, void *);
80
81#ifdef MSG_DEBUG
82#define DPRINTF(a) printf a
83#else
84#define DPRINTF(a) (void)0
85#endif

--- 61 unchanged lines hidden (view full) ---

147static short free_msgmaps; /* head of linked list of free map entries */
148static struct msg *free_msghdrs;/* list of free msg headers */
149static char *msgpool; /* MSGMAX byte long msg buffer pool */
150static struct msgmap *msgmaps; /* MSGSEG msgmap structures */
151static struct msg *msghdrs; /* MSGTQL msg headers */
152static struct msqid_kernel *msqids; /* MSGMNI msqid_kernel struct's */
153static struct mtx msq_mtx; /* global mutex for message queues. */
154
78static int msgunload(void);
79static int sysvmsg_modload(struct module *, int, void *);
80
81#ifdef MSG_DEBUG
82#define DPRINTF(a) printf a
83#else
84#define DPRINTF(a) (void)0
85#endif

--- 61 unchanged lines hidden (view full) ---

147static short free_msgmaps; /* head of linked list of free map entries */
148static struct msg *free_msghdrs;/* list of free msg headers */
149static char *msgpool; /* MSGMAX byte long msg buffer pool */
150static struct msgmap *msgmaps; /* MSGSEG msgmap structures */
151static struct msg *msghdrs; /* MSGTQL msg headers */
152static struct msqid_kernel *msqids; /* MSGMNI msqid_kernel struct's */
153static struct mtx msq_mtx; /* global mutex for message queues. */
154
155static void
155static struct syscall_helper_data msg_syscalls[] = {
156 SYSCALL_INIT_HELPER(msgctl),
157 SYSCALL_INIT_HELPER(msgget),
158 SYSCALL_INIT_HELPER(msgsnd),
159 SYSCALL_INIT_HELPER(msgrcv),
160#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
161 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
162 SYSCALL_INIT_HELPER(msgsys),
163 SYSCALL_INIT_HELPER(freebsd7_msgctl),
164#endif
165 SYSCALL_INIT_LAST
166};
167
168#ifdef COMPAT_FREEBSD32
169#include <compat/freebsd32/freebsd32.h>
170#include <compat/freebsd32/freebsd32_ipc.h>
171#include <compat/freebsd32/freebsd32_proto.h>
172#include <compat/freebsd32/freebsd32_signal.h>
173#include <compat/freebsd32/freebsd32_syscall.h>
174#include <compat/freebsd32/freebsd32_util.h>
175
176static struct syscall_helper_data msg32_syscalls[] = {
177 SYSCALL32_INIT_HELPER(freebsd32_msgctl),
178 SYSCALL32_INIT_HELPER(freebsd32_msgsnd),
179 SYSCALL32_INIT_HELPER(freebsd32_msgrcv),
180 SYSCALL32_INIT_HELPER(msgget),
181 SYSCALL32_INIT_HELPER(freebsd32_msgsys),
182#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
183 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
184 SYSCALL32_INIT_HELPER(freebsd7_freebsd32_msgctl),
185#endif
186 SYSCALL_INIT_LAST
187};
188#endif
189
190static int
156msginit()
157{
191msginit()
192{
158 register int i;
193 int i, error;
159
160 TUNABLE_INT_FETCH("kern.ipc.msgseg", &msginfo.msgseg);
161 TUNABLE_INT_FETCH("kern.ipc.msgssz", &msginfo.msgssz);
162 msginfo.msgmax = msginfo.msgseg * msginfo.msgssz;
163 TUNABLE_INT_FETCH("kern.ipc.msgmni", &msginfo.msgmni);
164 TUNABLE_INT_FETCH("kern.ipc.msgmnb", &msginfo.msgmnb);
165 TUNABLE_INT_FETCH("kern.ipc.msgtql", &msginfo.msgtql);
166

--- 63 unchanged lines hidden (view full) ---

230 msqids[i].u.msg_qbytes = 0; /* implies entry is available */
231 msqids[i].u.msg_perm.seq = 0; /* reset to a known value */
232 msqids[i].u.msg_perm.mode = 0;
233#ifdef MAC
234 mac_sysvmsq_init(&msqids[i]);
235#endif
236 }
237 mtx_init(&msq_mtx, "msq", NULL, MTX_DEF);
194
195 TUNABLE_INT_FETCH("kern.ipc.msgseg", &msginfo.msgseg);
196 TUNABLE_INT_FETCH("kern.ipc.msgssz", &msginfo.msgssz);
197 msginfo.msgmax = msginfo.msgseg * msginfo.msgssz;
198 TUNABLE_INT_FETCH("kern.ipc.msgmni", &msginfo.msgmni);
199 TUNABLE_INT_FETCH("kern.ipc.msgmnb", &msginfo.msgmnb);
200 TUNABLE_INT_FETCH("kern.ipc.msgtql", &msginfo.msgtql);
201

--- 63 unchanged lines hidden (view full) ---

265 msqids[i].u.msg_qbytes = 0; /* implies entry is available */
266 msqids[i].u.msg_perm.seq = 0; /* reset to a known value */
267 msqids[i].u.msg_perm.mode = 0;
268#ifdef MAC
269 mac_sysvmsq_init(&msqids[i]);
270#endif
271 }
272 mtx_init(&msq_mtx, "msq", NULL, MTX_DEF);
273
274 error = syscall_helper_register(msg_syscalls);
275 if (error != 0)
276 return (error);
277#ifdef COMPAT_FREEBSD32
278 error = syscall32_helper_register(msg32_syscalls);
279 if (error != 0)
280 return (error);
281#endif
282 return (0);
238}
239
240static int
241msgunload()
242{
243 struct msqid_kernel *msqkptr;
244 int msqid;
245#ifdef MAC
246 int i;
247#endif
248
283}
284
285static int
286msgunload()
287{
288 struct msqid_kernel *msqkptr;
289 int msqid;
290#ifdef MAC
291 int i;
292#endif
293
294 syscall_helper_unregister(msg_syscalls);
295#ifdef COMPAT_FREEBSD32
296 syscall32_helper_unregister(msg32_syscalls);
297#endif
298
249 for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
250 /*
251 * Look for an unallocated and unlocked msqid_ds.
252 * msqid_ds's can be locked by msgsnd or msgrcv while
253 * they are copying the message in/out. We can't
254 * re-use the entry until they release it.
255 */
256 msqkptr = &msqids[msqid];

--- 21 unchanged lines hidden (view full) ---

278
279static int
280sysvmsg_modload(struct module *module, int cmd, void *arg)
281{
282 int error = 0;
283
284 switch (cmd) {
285 case MOD_LOAD:
299 for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
300 /*
301 * Look for an unallocated and unlocked msqid_ds.
302 * msqid_ds's can be locked by msgsnd or msgrcv while
303 * they are copying the message in/out. We can't
304 * re-use the entry until they release it.
305 */
306 msqkptr = &msqids[msqid];

--- 21 unchanged lines hidden (view full) ---

328
329static int
330sysvmsg_modload(struct module *module, int cmd, void *arg)
331{
332 int error = 0;
333
334 switch (cmd) {
335 case MOD_LOAD:
286 msginit();
336 error = msginit();
337 if (error != 0)
338 msgunload();
287 break;
288 case MOD_UNLOAD:
289 error = msgunload();
290 break;
291 case MOD_SHUTDOWN:
292 break;
293 default:
294 error = EINVAL;
295 break;
296 }
297 return (error);
298}
299
300static moduledata_t sysvmsg_mod = {
301 "sysvmsg",
302 &sysvmsg_modload,
303 NULL
304};
305
339 break;
340 case MOD_UNLOAD:
341 error = msgunload();
342 break;
343 case MOD_SHUTDOWN:
344 break;
345 default:
346 error = EINVAL;
347 break;
348 }
349 return (error);
350}
351
352static moduledata_t sysvmsg_mod = {
353 "sysvmsg",
354 &sysvmsg_modload,
355 NULL
356};
357
306SYSCALL_MODULE_HELPER(msgctl);
307SYSCALL_MODULE_HELPER(msgget);
308SYSCALL_MODULE_HELPER(msgsnd);
309SYSCALL_MODULE_HELPER(msgrcv);
310
311DECLARE_MODULE(sysvmsg, sysvmsg_mod, SI_SUB_SYSV_MSG, SI_ORDER_FIRST);
312MODULE_VERSION(sysvmsg, 1);
313
314static void
315msg_freehdr(msghdr)
316 struct msg *msghdr;
317{
318 while (msghdr->msg_ts > 0) {

--- 933 unchanged lines hidden (view full) ---

1252 "Maximum number of messages in the system");
1253SYSCTL_INT(_kern_ipc, OID_AUTO, msgssz, CTLFLAG_RDTUN, &msginfo.msgssz, 0,
1254 "Size of a message segment");
1255SYSCTL_INT(_kern_ipc, OID_AUTO, msgseg, CTLFLAG_RDTUN, &msginfo.msgseg, 0,
1256 "Number of message segments");
1257SYSCTL_PROC(_kern_ipc, OID_AUTO, msqids, CTLFLAG_RD,
1258 NULL, 0, sysctl_msqids, "", "Message queue IDs");
1259
358DECLARE_MODULE(sysvmsg, sysvmsg_mod, SI_SUB_SYSV_MSG, SI_ORDER_FIRST);
359MODULE_VERSION(sysvmsg, 1);
360
361static void
362msg_freehdr(msghdr)
363 struct msg *msghdr;
364{
365 while (msghdr->msg_ts > 0) {

--- 933 unchanged lines hidden (view full) ---

1299 "Maximum number of messages in the system");
1300SYSCTL_INT(_kern_ipc, OID_AUTO, msgssz, CTLFLAG_RDTUN, &msginfo.msgssz, 0,
1301 "Size of a message segment");
1302SYSCTL_INT(_kern_ipc, OID_AUTO, msgseg, CTLFLAG_RDTUN, &msginfo.msgseg, 0,
1303 "Number of message segments");
1304SYSCTL_PROC(_kern_ipc, OID_AUTO, msqids, CTLFLAG_RD,
1305 NULL, 0, sysctl_msqids, "", "Message queue IDs");
1306
1307#ifdef COMPAT_FREEBSD32
1308int
1309freebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
1310{
1311
1260#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
1261 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
1312#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
1313 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
1262SYSCALL_MODULE_HELPER(msgsys);
1263SYSCALL_MODULE_HELPER(freebsd7_msgctl);
1314 switch (uap->which) {
1315 case 0:
1316 return (freebsd7_freebsd32_msgctl(td,
1317 (struct freebsd7_freebsd32_msgctl_args *)&uap->a2));
1318 case 2:
1319 return (freebsd32_msgsnd(td,
1320 (struct freebsd32_msgsnd_args *)&uap->a2));
1321 case 3:
1322 return (freebsd32_msgrcv(td,
1323 (struct freebsd32_msgrcv_args *)&uap->a2));
1324 default:
1325 return (msgsys(td, (struct msgsys_args *)uap));
1326 }
1327#else
1328 return (nosys(td, NULL));
1329#endif
1330}
1264
1331
1332#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
1333 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
1334int
1335freebsd7_freebsd32_msgctl(struct thread *td,
1336 struct freebsd7_freebsd32_msgctl_args *uap)
1337{
1338 struct msqid_ds msqbuf;
1339 struct msqid_ds32_old msqbuf32;
1340 int error;
1341
1342 if (uap->cmd == IPC_SET) {
1343 error = copyin(uap->buf, &msqbuf32, sizeof(msqbuf32));
1344 if (error)
1345 return (error);
1346 freebsd32_ipcperm_old_in(&msqbuf32.msg_perm, &msqbuf.msg_perm);
1347 PTRIN_CP(msqbuf32, msqbuf, msg_first);
1348 PTRIN_CP(msqbuf32, msqbuf, msg_last);
1349 CP(msqbuf32, msqbuf, msg_cbytes);
1350 CP(msqbuf32, msqbuf, msg_qnum);
1351 CP(msqbuf32, msqbuf, msg_qbytes);
1352 CP(msqbuf32, msqbuf, msg_lspid);
1353 CP(msqbuf32, msqbuf, msg_lrpid);
1354 CP(msqbuf32, msqbuf, msg_stime);
1355 CP(msqbuf32, msqbuf, msg_rtime);
1356 CP(msqbuf32, msqbuf, msg_ctime);
1357 }
1358 error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf);
1359 if (error)
1360 return (error);
1361 if (uap->cmd == IPC_STAT) {
1362 bzero(&msqbuf32, sizeof(msqbuf32));
1363 freebsd32_ipcperm_old_out(&msqbuf.msg_perm, &msqbuf32.msg_perm);
1364 PTROUT_CP(msqbuf, msqbuf32, msg_first);
1365 PTROUT_CP(msqbuf, msqbuf32, msg_last);
1366 CP(msqbuf, msqbuf32, msg_cbytes);
1367 CP(msqbuf, msqbuf32, msg_qnum);
1368 CP(msqbuf, msqbuf32, msg_qbytes);
1369 CP(msqbuf, msqbuf32, msg_lspid);
1370 CP(msqbuf, msqbuf32, msg_lrpid);
1371 CP(msqbuf, msqbuf32, msg_stime);
1372 CP(msqbuf, msqbuf32, msg_rtime);
1373 CP(msqbuf, msqbuf32, msg_ctime);
1374 error = copyout(&msqbuf32, uap->buf, sizeof(struct msqid_ds32));
1375 }
1376 return (error);
1377}
1378#endif
1379
1380int
1381freebsd32_msgctl(struct thread *td, struct freebsd32_msgctl_args *uap)
1382{
1383 struct msqid_ds msqbuf;
1384 struct msqid_ds32 msqbuf32;
1385 int error;
1386
1387 if (uap->cmd == IPC_SET) {
1388 error = copyin(uap->buf, &msqbuf32, sizeof(msqbuf32));
1389 if (error)
1390 return (error);
1391 freebsd32_ipcperm_in(&msqbuf32.msg_perm, &msqbuf.msg_perm);
1392 PTRIN_CP(msqbuf32, msqbuf, msg_first);
1393 PTRIN_CP(msqbuf32, msqbuf, msg_last);
1394 CP(msqbuf32, msqbuf, msg_cbytes);
1395 CP(msqbuf32, msqbuf, msg_qnum);
1396 CP(msqbuf32, msqbuf, msg_qbytes);
1397 CP(msqbuf32, msqbuf, msg_lspid);
1398 CP(msqbuf32, msqbuf, msg_lrpid);
1399 CP(msqbuf32, msqbuf, msg_stime);
1400 CP(msqbuf32, msqbuf, msg_rtime);
1401 CP(msqbuf32, msqbuf, msg_ctime);
1402 }
1403 error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf);
1404 if (error)
1405 return (error);
1406 if (uap->cmd == IPC_STAT) {
1407 freebsd32_ipcperm_out(&msqbuf.msg_perm, &msqbuf32.msg_perm);
1408 PTROUT_CP(msqbuf, msqbuf32, msg_first);
1409 PTROUT_CP(msqbuf, msqbuf32, msg_last);
1410 CP(msqbuf, msqbuf32, msg_cbytes);
1411 CP(msqbuf, msqbuf32, msg_qnum);
1412 CP(msqbuf, msqbuf32, msg_qbytes);
1413 CP(msqbuf, msqbuf32, msg_lspid);
1414 CP(msqbuf, msqbuf32, msg_lrpid);
1415 CP(msqbuf, msqbuf32, msg_stime);
1416 CP(msqbuf, msqbuf32, msg_rtime);
1417 CP(msqbuf, msqbuf32, msg_ctime);
1418 error = copyout(&msqbuf32, uap->buf, sizeof(struct msqid_ds32));
1419 }
1420 return (error);
1421}
1422
1423int
1424freebsd32_msgsnd(struct thread *td, struct freebsd32_msgsnd_args *uap)
1425{
1426 const void *msgp;
1427 long mtype;
1428 int32_t mtype32;
1429 int error;
1430
1431 msgp = PTRIN(uap->msgp);
1432 if ((error = copyin(msgp, &mtype32, sizeof(mtype32))) != 0)
1433 return (error);
1434 mtype = mtype32;
1435 return (kern_msgsnd(td, uap->msqid,
1436 (const char *)msgp + sizeof(mtype32),
1437 uap->msgsz, uap->msgflg, mtype));
1438}
1439
1440int
1441freebsd32_msgrcv(struct thread *td, struct freebsd32_msgrcv_args *uap)
1442{
1443 void *msgp;
1444 long mtype;
1445 int32_t mtype32;
1446 int error;
1447
1448 msgp = PTRIN(uap->msgp);
1449 if ((error = kern_msgrcv(td, uap->msqid,
1450 (char *)msgp + sizeof(mtype32), uap->msgsz,
1451 uap->msgtyp, uap->msgflg, &mtype)) != 0)
1452 return (error);
1453 mtype32 = (int32_t)mtype;
1454 return (copyout(&mtype32, msgp, sizeof(mtype32)));
1455}
1456#endif
1457
1458#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
1459 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
1460
1265/* XXX casting to (sy_call_t *) is bogus, as usual. */
1266static sy_call_t *msgcalls[] = {
1267 (sy_call_t *)freebsd7_msgctl, (sy_call_t *)msgget,
1268 (sy_call_t *)msgsnd, (sy_call_t *)msgrcv
1269};
1270
1271/*
1272 * Entry point for all MSG calls.

--- 17 unchanged lines hidden (view full) ---

1290 return (ENOSYS);
1291 if (uap->which < 0 ||
1292 uap->which >= sizeof(msgcalls)/sizeof(msgcalls[0]))
1293 return (EINVAL);
1294 error = (*msgcalls[uap->which])(td, &uap->a2);
1295 return (error);
1296}
1297
1461/* XXX casting to (sy_call_t *) is bogus, as usual. */
1462static sy_call_t *msgcalls[] = {
1463 (sy_call_t *)freebsd7_msgctl, (sy_call_t *)msgget,
1464 (sy_call_t *)msgsnd, (sy_call_t *)msgrcv
1465};
1466
1467/*
1468 * Entry point for all MSG calls.

--- 17 unchanged lines hidden (view full) ---

1486 return (ENOSYS);
1487 if (uap->which < 0 ||
1488 uap->which >= sizeof(msgcalls)/sizeof(msgcalls[0]))
1489 return (EINVAL);
1490 error = (*msgcalls[uap->which])(td, &uap->a2);
1491 return (error);
1492}
1493
1494#ifndef CP
1298#define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0)
1495#define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0)
1496#endif
1299
1300#ifndef _SYS_SYSPROTO_H_
1301struct freebsd7_msgctl_args {
1302 int msqid;
1303 int cmd;
1304 struct msqid_ds_old *buf;
1305};
1306#endif

--- 52 unchanged lines hidden ---
1497
1498#ifndef _SYS_SYSPROTO_H_
1499struct freebsd7_msgctl_args {
1500 int msqid;
1501 int cmd;
1502 struct msqid_ds_old *buf;
1503};
1504#endif

--- 52 unchanged lines hidden ---