summaryrefslogtreecommitdiffstats
path: root/sys/compat
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2006-12-20 20:08:45 +0000
committerjkim <jkim@FreeBSD.org>2006-12-20 20:08:45 +0000
commit32be6116587f790003891e0bb8b64be55589ed4e (patch)
treebec7ca1fc1b8901052e85395de016b4961e06c7b /sys/compat
parent0ce1631e99be578d5c73f4862a609eb75e180614 (diff)
downloadFreeBSD-src-32be6116587f790003891e0bb8b64be55589ed4e.zip
FreeBSD-src-32be6116587f790003891e0bb8b64be55589ed4e.tar.gz
MFP4: 110179
Add rudimentary IPC_INFO/MSG_INFO command support for linux_msgctl() to pacify Linux ipcs(1). While I am here, add more bound checks for linux_msgsnd() and linux_msgrcv().
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/linux/linux_ipc.c44
1 files changed, 41 insertions, 3 deletions
diff --git a/sys/compat/linux/linux_ipc.c b/sys/compat/linux/linux_ipc.c
index 256c21c..ec8df56 100644
--- a/sys/compat/linux/linux_ipc.c
+++ b/sys/compat/linux/linux_ipc.c
@@ -83,6 +83,17 @@ struct l_shm_info {
l_ulong swap_successes;
};
+struct l_msginfo {
+ l_int msgpool;
+ l_int msgmap;
+ l_int msgmax;
+ l_int msgmnb;
+ l_int msgmni;
+ l_int msgssz;
+ l_int msgtql;
+ l_ushort msgseg;
+};
+
static void
bsd_to_linux_shminfo( struct shminfo *bpp, struct l_shminfo *lpp)
{
@@ -580,7 +591,7 @@ linux_msgsnd(struct thread *td, struct linux_msgsnd_args *args)
l_long lmtype;
int error;
- if ((l_long)args->msgsz < 0)
+ 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)
@@ -599,7 +610,7 @@ linux_msgrcv(struct thread *td, struct linux_msgrcv_args *args)
l_long lmtype;
int error;
- if ((l_long)args->msgsz < 0)
+ 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,
@@ -631,12 +642,39 @@ linux_msgctl(struct thread *td, struct linux_msgctl_args *args)
struct msqid_ds bsd_msqid;
bsd_cmd = args->cmd & ~LINUX_IPC_64;
- if (bsd_cmd == LINUX_IPC_SET) {
+ switch (bsd_cmd) {
+ case LINUX_IPC_INFO:
+ case LINUX_MSG_INFO: {
+ struct l_msginfo linux_msginfo;
+
+ /*
+ * XXX MSG_INFO uses the same data structure but returns different
+ * dynamic counters in msgpool, msgmap, and msgtql fields.
+ */
+ linux_msginfo.msgpool = (long)msginfo.msgmni *
+ (long)msginfo.msgmnb / 1024L; /* XXX MSG_INFO. */
+ linux_msginfo.msgmap = msginfo.msgmnb; /* XXX MSG_INFO. */
+ linux_msginfo.msgmax = msginfo.msgmax;
+ linux_msginfo.msgmnb = msginfo.msgmnb;
+ linux_msginfo.msgmni = msginfo.msgmni;
+ linux_msginfo.msgssz = msginfo.msgssz;
+ linux_msginfo.msgtql = msginfo.msgtql; /* XXX MSG_INFO. */
+ linux_msginfo.msgseg = msginfo.msgseg;
+ error = copyout(&linux_msginfo, PTRIN(args->buf),
+ sizeof(linux_msginfo));
+ if (error == 0)
+ td->td_retval[0] = msginfo.msgmni; /* XXX */
+
+ return (error);
+ }
+
+ case LINUX_IPC_SET:
error = linux_msqid_pullup(args->cmd & LINUX_IPC_64,
&linux_msqid, PTRIN(args->buf));
if (error)
return (error);
linux_to_bsd_msqid_ds(&linux_msqid, &bsd_msqid);
+ break;
}
error = kern_msgctl(td, args->msqid, bsd_cmd, &bsd_msqid);
OpenPOWER on IntegriCloud