patch-2.1.38 linux/net/socket.c
Next file: linux/net/sunrpc/pmap_clnt.c
Previous file: linux/net/netsyms.c
Back to the patch index
Back to the overall index
- Lines: 183
- Date:
Wed May 14 15:01:21 1997
- Orig file:
v2.1.37/linux/net/socket.c
- Orig date:
Tue May 13 22:41:25 1997
diff -u --recursive --new-file v2.1.37/linux/net/socket.c linux/net/socket.c
@@ -39,6 +39,8 @@
* for sockets. May have errors at the
* moment.
* Kevin Buhr : Fixed the dumb errors in the above.
+ * Andi Kleen : Some small cleanups, optimizations,
+ * and fixed a copy_from_user() bug.
*
*
* This program is free software; you can redistribute it and/or
@@ -180,7 +182,7 @@
* "fromlen shall refer to the value before truncation.."
* 1003.1g
*/
- return put_user(klen, ulen);
+ return __put_user(klen, ulen);
}
/*
@@ -365,6 +367,7 @@
if (size==0) /* Match SYS5 behaviour */
return 0;
+ /* FIXME: I think this can be removed now. */
if ((err=verify_area(VERIFY_WRITE,ubuf,size))<0)
return err;
msg.msg_name=NULL;
@@ -398,7 +401,8 @@
if(size==0) /* Match SYS5 behaviour */
return 0;
-
+
+ /* FIXME: I think this can be removed now */
if ((err=verify_area(VERIFY_READ,ubuf,size))<0)
return err;
@@ -797,7 +801,6 @@
{
if (!(newsock = sock_alloc()))
{
- printk(KERN_WARNING "accept: no more sockets\n");
err=-EMFILE;
goto out;
}
@@ -1130,6 +1133,7 @@
struct msghdr msg_sys;
int err= -EINVAL;
int total_len;
+ unsigned char *ctl_buf = ctl;
lock_kernel();
@@ -1149,22 +1153,26 @@
if (msg_sys.msg_controllen)
{
- if (msg_sys.msg_controllen > sizeof(ctl))
+ /* XXX We just limit the buffer and assume that the
+ * skbuff accounting stops it from going too far.
+ * I hope this is correct.
+ */
+ if (msg_sys.msg_controllen > sizeof(ctl) &&
+ msg_sys.msg_controllen <= 256)
{
- char *tmp = kmalloc(msg_sys.msg_controllen, GFP_KERNEL);
- if (tmp == NULL)
+ ctl_buf = kmalloc(msg_sys.msg_controllen, GFP_KERNEL);
+ if (ctl_buf == NULL)
{
err = -ENOBUFS;
goto failed2;
}
- err = copy_from_user(tmp, msg_sys.msg_control, msg_sys.msg_controllen);
- msg_sys.msg_control = tmp;
- } else {
- err = copy_from_user(ctl, msg_sys.msg_control, msg_sys.msg_controllen);
- msg_sys.msg_control = ctl;
}
- if (err)
+ if (copy_from_user(ctl_buf, msg_sys.msg_control,
+ msg_sys.msg_controllen)) {
+ err = -EFAULT;
goto failed;
+ }
+ msg_sys.msg_control = ctl_buf;
}
msg_sys.msg_flags = flags;
if (current->files->fd[fd]->f_flags & O_NONBLOCK)
@@ -1177,8 +1185,8 @@
}
failed:
- if (msg_sys.msg_controllen && msg_sys.msg_control != ctl)
- kfree(msg_sys.msg_control);
+ if (ctl_buf != ctl)
+ kfree_s(ctl_buf, msg_sys.msg_controllen);
failed2:
if (msg_sys.msg_iov != iov)
kfree(msg_sys.msg_iov);
@@ -1240,7 +1248,6 @@
if (current->files->fd[fd]->f_flags&O_NONBLOCK)
flags |= MSG_DONTWAIT;
-
if ((sock = sockfd_lookup(fd, &err))!=NULL)
{
err=sock_recvmsg(sock, &msg_sys, total_len, flags);
@@ -1253,9 +1260,12 @@
if (uaddr != NULL && err>=0)
err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len);
- if (err>=0 && (put_user(msg_sys.msg_flags, &msg->msg_flags) ||
- put_user((unsigned long)msg_sys.msg_control-cmsg_ptr, &msg->msg_controllen)))
- err = -EFAULT;
+ if (err>=0) {
+ err = __put_user(msg_sys.msg_flags, &msg->msg_flags);
+ if (!err)
+ err = __put_user((unsigned long)msg_sys.msg_control-cmsg_ptr,
+ &msg->msg_controllen);
+ }
out:
unlock_kernel();
if(err<0)
@@ -1280,33 +1290,33 @@
return(-EINVAL);
}
+/* Argument list sizes for sys_socketcall */
+#define AL(x) ((x) * sizeof(unsigned long))
+static unsigned char nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
+ AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
+ AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
+#undef AL
/*
* System call vectors.
*
* Argument checking cleaned up. Saved 20% in size.
+ * This function doesn't need to set the kernel lock because
+ * it is set by the callees.
*/
asmlinkage int sys_socketcall(int call, unsigned long *args)
{
- unsigned char nargs[18]={0,3,3,3,2,3,3,3,
- 4,4,4,6,6,2,5,5,3,3};
unsigned long a[6];
unsigned long a0,a1;
- int err = -EINVAL;
-
- lock_kernel();
+ int err;
+
if(call<1||call>SYS_RECVMSG)
- goto out;
- err = -EFAULT;
+ return -EINVAL;
- /*
- * Ideally we want to precompute the maths, but unsigned long
- * isnt a fixed size....
- */
-
- if ((copy_from_user(a, args, nargs[call] * sizeof(unsigned long))))
- goto out;
+ /* copy_from_user should be SMP safe. */
+ if (copy_from_user(a, args, nargs[call]))
+ return -EFAULT;
a0=a[0];
a1=a[1];
@@ -1370,11 +1380,8 @@
err = -EINVAL;
break;
}
-out:
- unlock_kernel();
return err;
}
-
/*
* This function is called by a protocol handler that wants to
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov