aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c54
-rw-r--r--sys/compat/freebsd32/syscalls.master4
-rw-r--r--sys/compat/linux/linux_ipc.c50
-rw-r--r--sys/kern/sysv_msg.c173
-rw-r--r--sys/sys/syscallsubr.h2
5 files changed, 168 insertions, 115 deletions
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index 500c9ba1acde..5fb9ad1685cf 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -1331,10 +1331,56 @@ freebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
int
freebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
{
- /*
- * Vector through to msgsys if it is loaded.
- */
- return sysent[SYS_msgsys].sy_call(td, uap);
+ switch (uap->which) {
+ case 2:
+ return (freebsd32_msgsnd(td,
+ (struct freebsd32_msgsnd_args *)&uap->a2));
+ break;
+ case 3:
+ return (freebsd32_msgrcv(td,
+ (struct freebsd32_msgrcv_args *)&uap->a2));
+ break;
+ default:
+ /*
+ * Vector through to msgsys if it is loaded.
+ */
+ return (sysent[SYS_msgsys].sy_call(td, uap));
+ break;
+ }
+}
+
+int
+freebsd32_msgsnd(struct thread *td, struct freebsd32_msgsnd_args *uap)
+{
+ const void *msgp;
+ long mtype;
+ int32_t mtype32;
+ int error;
+
+ msgp = PTRIN(uap->msgp);
+ if ((error = copyin(msgp, &mtype32, sizeof(mtype32))) != 0)
+ return (error);
+ mtype = mtype32;
+ return (kern_msgsnd(td, uap->msqid,
+ (const char *)msgp + sizeof(mtype32),
+ uap->msgsz, uap->msgflg, mtype));
+}
+
+int
+freebsd32_msgrcv(struct thread *td, struct freebsd32_msgrcv_args *uap)
+{
+ void *msgp;
+ long mtype;
+ int32_t mtype32;
+ int error;
+
+ msgp = PTRIN(uap->msgp);
+ if ((error = kern_msgrcv(td, uap->msqid,
+ (char *)msgp + sizeof(mtype32), uap->msgsz,
+ uap->msgtyp, uap->msgflg, &mtype)) != 0)
+ return (error);
+ mtype32 = (int32_t)mtype;
+ return (copyout(&mtype32, msgp, sizeof(mtype32)));
}
int
diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master
index dff103cca51f..e52c300950bd 100644
--- a/sys/compat/freebsd32/syscalls.master
+++ b/sys/compat/freebsd32/syscalls.master
@@ -409,9 +409,9 @@
224 AUE_MSGCTL MNOPROTO { int msgctl(int msqid, int cmd, \
struct msqid_ds *buf); }
225 AUE_MSGGET MNOPROTO { int msgget(key_t key, int msgflg); }
-226 AUE_MSGSND MNOPROTO { int msgsnd(int msqid, void *msgp, \
+226 AUE_MSGSND MSTD { int freebsd32_msgsnd(int msqid, void *msgp, \
size_t msgsz, int msgflg); }
-227 AUE_MSGRCV MNOPROTO { int msgrcv(int msqid, void *msgp, \
+227 AUE_MSGRCV MSTD { int freebsd32_msgrcv(int msqid, void *msgp, \
size_t msgsz, long msgtyp, int msgflg); }
228 AUE_SHMAT MNOPROTO { int shmat(int shmid, void *shmaddr, \
int shmflg); }
diff --git a/sys/compat/linux/linux_ipc.c b/sys/compat/linux/linux_ipc.c
index 5c52ed1533dd..93ed617c09c3 100644
--- a/sys/compat/linux/linux_ipc.c
+++ b/sys/compat/linux/linux_ipc.c
@@ -575,37 +575,39 @@ linux_semctl(struct thread *td, struct linux_semctl_args *args)
int
linux_msgsnd(struct thread *td, struct linux_msgsnd_args *args)
{
- struct msgsnd_args /* {
- int msqid;
- void *msgp;
- size_t msgsz;
- int msgflg;
- } */ bsd_args;
+ const void *msgp;
+ long mtype;
+ l_long lmtype;
+ int error;
- bsd_args.msqid = args->msqid;
- bsd_args.msgp = PTRIN(args->msgp);
- bsd_args.msgsz = args->msgsz;
- bsd_args.msgflg = args->msgflg;
- return msgsnd(td, &bsd_args);
+ if ((l_long)args->msgsz < 0 || args->msgsz > (l_long)msginfo.msgmax)
+ return (EINVAL);
+ msgp = PTRIN(args->msgp);
+ if ((error = copyin(msgp, &lmtype, sizeof(lmtype))) != 0)
+ return (error);
+ mtype = (long)lmtype;
+ return (kern_msgsnd(td, args->msqid,
+ (const char *)msgp + sizeof(lmtype),
+ args->msgsz, args->msgflg, mtype));
}
int
linux_msgrcv(struct thread *td, struct linux_msgrcv_args *args)
{
- struct msgrcv_args /* {
- int msqid;
- void *msgp;
- size_t msgsz;
- long msgtyp;
- int msgflg;
- } */ bsd_args;
+ void *msgp;
+ long mtype;
+ l_long lmtype;
+ int error;
- bsd_args.msqid = args->msqid;
- bsd_args.msgp = PTRIN(args->msgp);
- bsd_args.msgsz = args->msgsz;
- bsd_args.msgtyp = args->msgtyp;
- bsd_args.msgflg = args->msgflg;
- return msgrcv(td, &bsd_args);
+ if ((l_long)args->msgsz < 0 || args->msgsz > (l_long)msginfo.msgmax)
+ return (EINVAL);
+ msgp = PTRIN(args->msgp);
+ if ((error = kern_msgrcv(td, args->msqid,
+ (char *)msgp + sizeof(lmtype), args->msgsz,
+ args->msgtyp, args->msgflg, &mtype)) != 0)
+ return (error);
+ lmtype = (l_long)mtype;
+ return (copyout(&lmtype, msgp, sizeof(lmtype)));
}
int
diff --git a/sys/kern/sysv_msg.c b/sys/kern/sysv_msg.c
index 60a943171a6e..1a8be178a149 100644
--- a/sys/kern/sysv_msg.c
+++ b/sys/kern/sysv_msg.c
@@ -399,7 +399,7 @@ msgctl(td, uap)
struct msqid_ds msqbuf;
int error;
- DPRINTF(("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, uap->buf));
+ DPRINTF(("call to msgctl(%d, %d, %p)\n", msqid, cmd, uap->buf));
if (cmd == IPC_SET &&
(error = copyin(uap->buf, &msqbuf, sizeof(msqbuf))) != 0)
return (error);
@@ -682,45 +682,40 @@ struct msgsnd_args {
};
#endif
-/*
- * MPSAFE
- */
int
-msgsnd(td, uap)
+kern_msgsnd(td, msqid, msgp, msgsz, msgflg, mtype)
struct thread *td;
- register struct msgsnd_args *uap;
+ int msqid;
+ const void *msgp; /* XXX msgp is actually mtext. */
+ size_t msgsz;
+ int msgflg;
+ long mtype;
{
- int msqid = uap->msqid;
- const void *user_msgp = uap->msgp;
- size_t msgsz = uap->msgsz;
- int msgflg = uap->msgflg;
- int segs_needed, error = 0;
+ int msqix, segs_needed, error = 0;
register struct msqid_kernel *msqkptr;
register struct msg *msghdr;
short next;
- DPRINTF(("call to msgsnd(%d, 0x%x, %d, %d)\n", msqid, user_msgp, msgsz,
- msgflg));
if (!jail_sysvipc_allowed && jailed(td->td_ucred))
return (ENOSYS);
mtx_lock(&msq_mtx);
- msqid = IPCID_TO_IX(msqid);
+ msqix = IPCID_TO_IX(msqid);
- if (msqid < 0 || msqid >= msginfo.msgmni) {
- DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
+ if (msqix < 0 || msqix >= msginfo.msgmni) {
+ DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqix,
msginfo.msgmni));
error = EINVAL;
goto done2;
}
- msqkptr = &msqids[msqid];
+ msqkptr = &msqids[msqix];
if (msqkptr->u.msg_qbytes == 0) {
DPRINTF(("no such message queue id\n"));
error = EINVAL;
goto done2;
}
- if (msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
+ if (msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(msqid)) {
DPRINTF(("wrong sequence number\n"));
error = EINVAL;
goto done2;
@@ -740,8 +735,8 @@ msgsnd(td, uap)
#endif
segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz;
- DPRINTF(("msgsz=%d, msgssz=%d, segs_needed=%d\n", msgsz, msginfo.msgssz,
- segs_needed));
+ DPRINTF(("msgsz=%zu, msgssz=%d, segs_needed=%d\n", msgsz,
+ msginfo.msgssz, segs_needed));
for (;;) {
int need_more_resources = 0;
@@ -852,6 +847,7 @@ msgsnd(td, uap)
free_msghdrs = msghdr->msg_next;
msghdr->msg_spot = -1;
msghdr->msg_ts = msgsz;
+ msghdr->msg_type = mtype;
#ifdef MAC
/*
* XXXMAC: Should the mac_check_sysv_msgmsq check follow here
@@ -884,23 +880,6 @@ msgsnd(td, uap)
}
/*
- * Copy in the message type
- */
-
- mtx_unlock(&msq_mtx);
- if ((error = copyin(user_msgp, &msghdr->msg_type,
- sizeof(msghdr->msg_type))) != 0) {
- mtx_lock(&msq_mtx);
- DPRINTF(("error %d copying the message type\n", error));
- msg_freehdr(msghdr);
- msqkptr->u.msg_perm.mode &= ~MSG_LOCKED;
- wakeup(msqkptr);
- goto done2;
- }
- mtx_lock(&msq_mtx);
- user_msgp = (const char *)user_msgp + sizeof(msghdr->msg_type);
-
- /*
* Validate the message type
*/
@@ -908,7 +887,7 @@ msgsnd(td, uap)
msg_freehdr(msghdr);
msqkptr->u.msg_perm.mode &= ~MSG_LOCKED;
wakeup(msqkptr);
- DPRINTF(("mtype (%d) < 1\n", msghdr->msg_type));
+ DPRINTF(("mtype (%ld) < 1\n", msghdr->msg_type));
error = EINVAL;
goto done2;
}
@@ -929,7 +908,7 @@ msgsnd(td, uap)
if (next >= msginfo.msgseg)
panic("next out of range #2");
mtx_unlock(&msq_mtx);
- if ((error = copyin(user_msgp, &msgpool[next * msginfo.msgssz],
+ if ((error = copyin(msgp, &msgpool[next * msginfo.msgssz],
tlen)) != 0) {
mtx_lock(&msq_mtx);
DPRINTF(("error %d copying in message segment\n",
@@ -941,7 +920,7 @@ msgsnd(td, uap)
}
mtx_lock(&msq_mtx);
msgsz -= tlen;
- user_msgp = (const char *)user_msgp + tlen;
+ msgp = (const char *)msgp + tlen;
next = msgmaps[next].next;
}
if (next != -1)
@@ -1009,6 +988,29 @@ done2:
return (error);
}
+/*
+ * MPSAFE
+ */
+int
+msgsnd(td, uap)
+ struct thread *td;
+ register struct msgsnd_args *uap;
+{
+ int error;
+ long mtype;
+
+ DPRINTF(("call to msgsnd(%d, %p, %zu, %d)\n", uap->msqid, uap->msgp,
+ uap->msgsz, uap->msgflg));
+
+ if ((error = copyin(uap->msgp, &mtype, sizeof(mtype))) != 0) {
+ DPRINTF(("error %d copying the message type\n", error));
+ return (error);
+ }
+ return (kern_msgsnd(td, uap->msqid,
+ (const char *)uap->msgp + sizeof(mtype),
+ uap->msgsz, uap->msgflg, mtype));
+}
+
#ifndef _SYS_SYSPROTO_H_
struct msgrcv_args {
int msqid;
@@ -1019,47 +1021,41 @@ struct msgrcv_args {
};
#endif
-/*
- * MPSAFE
- */
int
-msgrcv(td, uap)
+kern_msgrcv(td, msqid, msgp, msgsz, msgtyp, msgflg, mtype)
struct thread *td;
- register struct msgrcv_args *uap;
+ int msqid;
+ void *msgp; /* XXX msgp is actually mtext. */
+ size_t msgsz;
+ long msgtyp;
+ int msgflg;
+ long *mtype;
{
- int msqid = uap->msqid;
- void *user_msgp = uap->msgp;
- size_t msgsz = uap->msgsz;
- long msgtyp = uap->msgtyp;
- int msgflg = uap->msgflg;
size_t len;
register struct msqid_kernel *msqkptr;
register struct msg *msghdr;
- int error = 0;
+ int msqix, error = 0;
short next;
- DPRINTF(("call to msgrcv(%d, 0x%x, %d, %ld, %d)\n", msqid, user_msgp,
- msgsz, msgtyp, msgflg));
-
if (!jail_sysvipc_allowed && jailed(td->td_ucred))
return (ENOSYS);
- msqid = IPCID_TO_IX(msqid);
+ msqix = IPCID_TO_IX(msqid);
- if (msqid < 0 || msqid >= msginfo.msgmni) {
- DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
+ if (msqix < 0 || msqix >= msginfo.msgmni) {
+ DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqix,
msginfo.msgmni));
return (EINVAL);
}
- msqkptr = &msqids[msqid];
+ msqkptr = &msqids[msqix];
mtx_lock(&msq_mtx);
if (msqkptr->u.msg_qbytes == 0) {
DPRINTF(("no such message queue id\n"));
error = EINVAL;
goto done2;
}
- if (msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
+ if (msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(msqid)) {
DPRINTF(("wrong sequence number\n"));
error = EINVAL;
goto done2;
@@ -1086,7 +1082,7 @@ msgrcv(td, uap)
if (msgsz < msghdr->msg_ts &&
(msgflg & MSG_NOERROR) == 0) {
DPRINTF(("first message on the queue "
- "is too big (want %d, got %d)\n",
+ "is too big (want %zu, got %d)\n",
msgsz, msghdr->msg_ts));
error = E2BIG;
goto done2;
@@ -1127,14 +1123,14 @@ msgrcv(td, uap)
if (msgtyp == msghdr->msg_type ||
msghdr->msg_type <= -msgtyp) {
- DPRINTF(("found message type %d, "
- "requested %d\n",
+ DPRINTF(("found message type %ld, "
+ "requested %ld\n",
msghdr->msg_type, msgtyp));
if (msgsz < msghdr->msg_ts &&
(msgflg & MSG_NOERROR) == 0) {
DPRINTF(("requested message "
"on the queue is too big "
- "(want %d, got %d)\n",
+ "(want %zu, got %hu)\n",
msgsz, msghdr->msg_ts));
error = E2BIG;
goto done2;
@@ -1188,7 +1184,7 @@ msgrcv(td, uap)
*/
if ((msgflg & IPC_NOWAIT) != 0) {
- DPRINTF(("no appropriate message found (msgtyp=%d)\n",
+ DPRINTF(("no appropriate message found (msgtyp=%ld)\n",
msgtyp));
/* The SVID says to return ENOMSG. */
error = ENOMSG;
@@ -1215,7 +1211,7 @@ msgrcv(td, uap)
*/
if (msqkptr->u.msg_qbytes == 0 ||
- msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
+ msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(msqid)) {
DPRINTF(("msqid deleted\n"));
error = EIDRM;
goto done2;
@@ -1239,26 +1235,11 @@ msgrcv(td, uap)
* (since msgsz is never increased).
*/
- DPRINTF(("found a message, msgsz=%d, msg_ts=%d\n", msgsz,
+ DPRINTF(("found a message, msgsz=%zu, msg_ts=%hu\n", msgsz,
msghdr->msg_ts));
if (msgsz > msghdr->msg_ts)
msgsz = msghdr->msg_ts;
-
- /*
- * Return the type to the user.
- */
-
- mtx_unlock(&msq_mtx);
- error = copyout(&(msghdr->msg_type), user_msgp,
- sizeof(msghdr->msg_type));
- mtx_lock(&msq_mtx);
- if (error != 0) {
- DPRINTF(("error (%d) copying out message type\n", error));
- msg_freehdr(msghdr);
- wakeup(msqkptr);
- goto done2;
- }
- user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type);
+ *mtype = msghdr->msg_type;
/*
* Return the segments to the user
@@ -1277,8 +1258,7 @@ msgrcv(td, uap)
if (next >= msginfo.msgseg)
panic("next out of range #3");
mtx_unlock(&msq_mtx);
- error = copyout(&msgpool[next * msginfo.msgssz],
- user_msgp, tlen);
+ error = copyout(&msgpool[next * msginfo.msgssz], msgp, tlen);
mtx_lock(&msq_mtx);
if (error != 0) {
DPRINTF(("error (%d) copying out message segment\n",
@@ -1287,7 +1267,7 @@ msgrcv(td, uap)
wakeup(msqkptr);
goto done2;
}
- user_msgp = (char *)user_msgp + tlen;
+ msgp = (char *)msgp + tlen;
next = msgmaps[next].next;
}
@@ -1303,6 +1283,29 @@ done2:
return (error);
}
+/*
+ * MPSAFE
+ */
+int
+msgrcv(td, uap)
+ struct thread *td;
+ register struct msgrcv_args *uap;
+{
+ int error;
+ long mtype;
+
+ DPRINTF(("call to msgrcv(%d, %p, %zu, %ld, %d)\n", uap->msqid,
+ uap->msgp, uap->msgsz, uap->msgtyp, uap->msgflg));
+
+ if ((error = kern_msgrcv(td, uap->msqid,
+ (char *)uap->msgp + sizeof(mtype), uap->msgsz,
+ uap->msgtyp, uap->msgflg, &mtype)) != 0)
+ return (error);
+ if ((error = copyout(&mtype, uap->msgp, sizeof(mtype))) != 0)
+ DPRINTF(("error %d copying the message type\n", error));
+ return (error);
+}
+
static int
sysctl_msqids(SYSCTL_HANDLER_ARGS)
{
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
index fe68ea100bfd..b73106c4ac7f 100644
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -102,6 +102,8 @@ int kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg,
int kern_mknod(struct thread *td, char *path, enum uio_seg pathseg,
int mode, int dev);
int kern_msgctl(struct thread *, int, int, struct msqid_ds *);
+int kern_msgsnd(struct thread *, int, const void *, size_t, int, long);
+int kern_msgrcv(struct thread *, int, void *, size_t, long, int, long *);
int kern_nanosleep(struct thread *td, struct timespec *rqt,
struct timespec *rmt);
int kern_open(struct thread *td, char *path, enum uio_seg pathseg,