patch-2.1.116 linux/ipc/msg.c
Next file: linux/kernel/capability.c
Previous file: linux/include/linux/videodev.h
Back to the patch index
Back to the overall index
- Lines: 208
- Date:
Sat Aug 15 22:36:25 1998
- Orig file:
v2.1.115/linux/ipc/msg.c
- Orig date:
Thu May 7 22:51:55 1998
diff -u --recursive --new-file v2.1.115/linux/ipc/msg.c linux/ipc/msg.c
@@ -1,6 +1,13 @@
/*
* linux/ipc/msg.c
* Copyright (C) 1992 Krishna Balasubramanian
+ *
+ * Removed all the remaining kerneld mess
+ * Catch the -EFAULT stuff properly
+ * Use GFP_KERNEL for messages as in 1.2
+ * Fixed up the unchecked user space derefs
+ * Copyright (C) 1998 Alan Cox & Andi Kleen
+ *
*/
#include <linux/errno.h>
@@ -29,7 +36,7 @@
static int max_msqid = 0;
static struct wait_queue *msg_lock = NULL;
-__initfunc(void msg_init (void))
+void __init msg_init (void)
{
int id;
@@ -42,21 +49,16 @@
static int real_msgsnd (int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg)
{
- int id, err;
+ int id;
struct msqid_ds *msq;
struct ipc_perm *ipcp;
struct msg *msgh;
long mtype;
- unsigned long flags;
if (msgsz > MSGMAX || (long) msgsz < 0 || msqid < 0)
return -EINVAL;
- if (!msgp)
- return -EFAULT;
- err = verify_area (VERIFY_READ, msgp->mtext, msgsz);
- if (err)
- return err;
- get_user(mtype, &msgp->mtype);
+ if (get_user(mtype, &msgp->mtype))
+ return -EFAULT;
if (mtype < 1)
return -EINVAL;
id = (unsigned int) msqid % MSGMNI;
@@ -85,12 +87,16 @@
}
/* allocate message header and text space*/
- msgh = (struct msg *) kmalloc (sizeof(*msgh) + msgsz, GFP_ATOMIC);
+ msgh = (struct msg *) kmalloc (sizeof(*msgh) + msgsz, GFP_KERNEL);
if (!msgh)
return -ENOMEM;
msgh->msg_spot = (char *) (msgh + 1);
- copy_from_user (msgh->msg_spot, msgp->mtext, msgsz);
+ if (copy_from_user(msgh->msg_spot, msgp->mtext, msgsz))
+ {
+ kfree(msgh);
+ return -EFAULT;
+ }
if (msgque[id] == IPC_UNUSED || msgque[id] == IPC_NOID
|| msq->msg_perm.seq != (unsigned int) msqid / MSGMNI) {
@@ -103,8 +109,6 @@
msgh->msg_type = mtype;
msgh->msg_stime = CURRENT_TIME;
- save_flags(flags);
- cli();
if (!msq->msg_first)
msq->msg_first = msq->msg_last = msgh;
else {
@@ -117,7 +121,6 @@
msq->msg_qnum++;
msq->msg_lspid = current->pid;
msq->msg_stime = CURRENT_TIME;
- restore_flags(flags);
wake_up (&msq->rwait);
return 0;
}
@@ -128,17 +131,10 @@
struct ipc_perm *ipcp;
struct msg *tmsg, *leastp = NULL;
struct msg *nmsg = NULL;
- int id, err;
- unsigned long flags;
+ int id;
if (msqid < 0 || (long) msgsz < 0)
return -EINVAL;
- if (!msgp || !msgp->mtext)
- return -EFAULT;
-
- err = verify_area (VERIFY_WRITE, msgp->mtext, msgsz);
- if (err)
- return err;
id = (unsigned int) msqid % MSGMNI;
msq = msgque [id];
@@ -160,8 +156,6 @@
return -EACCES;
}
- save_flags(flags);
- cli();
if (msgtyp == 0)
nmsg = msq->msg_first;
else if (msgtyp > 0) {
@@ -186,15 +180,12 @@
if (leastp && leastp->msg_type <= - msgtyp)
nmsg = leastp;
}
- restore_flags(flags);
if (nmsg) { /* done finding a message */
if ((msgsz < nmsg->msg_ts) && !(msgflg & MSG_NOERROR)) {
return -E2BIG;
}
msgsz = (msgsz > nmsg->msg_ts)? nmsg->msg_ts : msgsz;
- save_flags(flags);
- cli();
if (nmsg == msq->msg_first)
msq->msg_first = nmsg->msg_next;
else {
@@ -214,10 +205,10 @@
msgbytes -= nmsg->msg_ts;
msghdrs--;
msq->msg_cbytes -= nmsg->msg_ts;
- restore_flags(flags);
wake_up (&msq->wwait);
- put_user (nmsg->msg_type, &msgp->mtype);
- copy_to_user (msgp->mtext, nmsg->msg_spot, msgsz);
+ if (put_user (nmsg->msg_type, &msgp->mtype) ||
+ copy_to_user (msgp->mtext, nmsg->msg_spot, msgsz))
+ msgsz = -EFAULT;
kfree(nmsg);
return msgsz;
} else { /* did not find a message */
@@ -395,19 +386,16 @@
msginfo.msgmap = msghdrs;
msginfo.msgtql = msgbytes;
}
- err = verify_area (VERIFY_WRITE, buf, sizeof (struct msginfo));
- if (err)
- goto out;
- copy_to_user (buf, &msginfo, sizeof(struct msginfo));
+
+ err = -EFAULT;
+ if (copy_to_user (buf, &msginfo, sizeof(struct msginfo)))
+ goto out;
err = max_msqid;
goto out;
}
case MSG_STAT:
if (!buf)
goto out;
- err = verify_area (VERIFY_WRITE, buf, sizeof (*buf));
- if (err)
- goto out;
err = -EINVAL;
if (msqid > max_msqid)
goto out;
@@ -427,23 +415,21 @@
tbuf.msg_qbytes = msq->msg_qbytes;
tbuf.msg_lspid = msq->msg_lspid;
tbuf.msg_lrpid = msq->msg_lrpid;
- copy_to_user (buf, &tbuf, sizeof(*buf));
+ err = -EFAULT;
+ if (copy_to_user (buf, &tbuf, sizeof(*buf)))
+ goto out;
err = id;
goto out;
case IPC_SET:
if (!buf)
goto out;
- err = verify_area (VERIFY_READ, buf, sizeof (*buf));
- if (err)
- goto out;
- copy_from_user (&tbuf, buf, sizeof (*buf));
+ err = -EFAULT;
+ if (!copy_from_user (&tbuf, buf, sizeof (*buf)))
+ err = 0;
break;
case IPC_STAT:
if (!buf)
goto out;
- err = verify_area (VERIFY_WRITE, buf, sizeof(*buf));
- if (err)
- goto out;
break;
}
@@ -471,8 +457,9 @@
tbuf.msg_qbytes = msq->msg_qbytes;
tbuf.msg_lspid = msq->msg_lspid;
tbuf.msg_lrpid = msq->msg_lrpid;
- copy_to_user (buf, &tbuf, sizeof (*buf));
- err = 0;
+ err = -EFAULT;
+ if (!copy_to_user (buf, &tbuf, sizeof (*buf)))
+ err = 0;
goto out;
case IPC_SET:
err = -EPERM;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov