aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c81
1 files changed, 73 insertions, 8 deletions
diff --git a/net/socket.c b/net/socket.c
index 64601f900352..a0ce8ad72252 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -63,6 +63,7 @@
63#include <linux/file.h> 63#include <linux/file.h>
64#include <linux/net.h> 64#include <linux/net.h>
65#include <linux/interrupt.h> 65#include <linux/interrupt.h>
66#include <linux/thread_info.h>
66#include <linux/rcupdate.h> 67#include <linux/rcupdate.h>
67#include <linux/netdevice.h> 68#include <linux/netdevice.h>
68#include <linux/proc_fs.h> 69#include <linux/proc_fs.h>
@@ -1225,6 +1226,9 @@ asmlinkage long sys_socket(int family, int type, int protocol)
1225 return -EINVAL; 1226 return -EINVAL;
1226 type &= SOCK_TYPE_MASK; 1227 type &= SOCK_TYPE_MASK;
1227 1228
1229 if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
1230 flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1231
1228 retval = sock_create(family, type, protocol, &sock); 1232 retval = sock_create(family, type, protocol, &sock);
1229 if (retval < 0) 1233 if (retval < 0)
1230 goto out; 1234 goto out;
@@ -1259,6 +1263,9 @@ asmlinkage long sys_socketpair(int family, int type, int protocol,
1259 return -EINVAL; 1263 return -EINVAL;
1260 type &= SOCK_TYPE_MASK; 1264 type &= SOCK_TYPE_MASK;
1261 1265
1266 if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
1267 flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1268
1262 /* 1269 /*
1263 * Obtain the first socket and check if the underlying protocol 1270 * Obtain the first socket and check if the underlying protocol
1264 * supports the socketpair call. 1271 * supports the socketpair call.
@@ -1413,14 +1420,20 @@ asmlinkage long sys_listen(int fd, int backlog)
1413 * clean when we restucture accept also. 1420 * clean when we restucture accept also.
1414 */ 1421 */
1415 1422
1416asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, 1423long do_accept(int fd, struct sockaddr __user *upeer_sockaddr,
1417 int __user *upeer_addrlen) 1424 int __user *upeer_addrlen, int flags)
1418{ 1425{
1419 struct socket *sock, *newsock; 1426 struct socket *sock, *newsock;
1420 struct file *newfile; 1427 struct file *newfile;
1421 int err, len, newfd, fput_needed; 1428 int err, len, newfd, fput_needed;
1422 struct sockaddr_storage address; 1429 struct sockaddr_storage address;
1423 1430
1431 if (flags & ~SOCK_CLOEXEC)
1432 return -EINVAL;
1433
1434 if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
1435 flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1436
1424 sock = sockfd_lookup_light(fd, &err, &fput_needed); 1437 sock = sockfd_lookup_light(fd, &err, &fput_needed);
1425 if (!sock) 1438 if (!sock)
1426 goto out; 1439 goto out;
@@ -1438,7 +1451,7 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr,
1438 */ 1451 */
1439 __module_get(newsock->ops->owner); 1452 __module_get(newsock->ops->owner);
1440 1453
1441 newfd = sock_alloc_fd(&newfile, 0); 1454 newfd = sock_alloc_fd(&newfile, flags & O_CLOEXEC);
1442 if (unlikely(newfd < 0)) { 1455 if (unlikely(newfd < 0)) {
1443 err = newfd; 1456 err = newfd;
1444 sock_release(newsock); 1457 sock_release(newsock);
@@ -1491,6 +1504,50 @@ out_fd:
1491 goto out_put; 1504 goto out_put;
1492} 1505}
1493 1506
1507asmlinkage long sys_paccept(int fd, struct sockaddr __user *upeer_sockaddr,
1508 int __user *upeer_addrlen,
1509 const sigset_t __user *sigmask,
1510 size_t sigsetsize, int flags)
1511{
1512 sigset_t ksigmask, sigsaved;
1513 int ret;
1514
1515 if (sigmask) {
1516 /* XXX: Don't preclude handling different sized sigset_t's. */
1517 if (sigsetsize != sizeof(sigset_t))
1518 return -EINVAL;
1519 if (copy_from_user(&ksigmask, sigmask, sizeof(ksigmask)))
1520 return -EFAULT;
1521
1522 sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
1523 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
1524 }
1525
1526 ret = do_accept(fd, upeer_sockaddr, upeer_addrlen, flags);
1527
1528 if (ret < 0 && signal_pending(current)) {
1529 /*
1530 * Don't restore the signal mask yet. Let do_signal() deliver
1531 * the signal on the way back to userspace, before the signal
1532 * mask is restored.
1533 */
1534 if (sigmask) {
1535 memcpy(&current->saved_sigmask, &sigsaved,
1536 sizeof(sigsaved));
1537 set_restore_sigmask();
1538 }
1539 } else if (sigmask)
1540 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
1541
1542 return ret;
1543}
1544
1545asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr,
1546 int __user *upeer_addrlen)
1547{
1548 return do_accept(fd, upeer_sockaddr, upeer_addrlen, 0);
1549}
1550
1494/* 1551/*
1495 * Attempt to connect to a socket with the server address. The address 1552 * Attempt to connect to a socket with the server address. The address
1496 * is in user space so we verify it is OK and move it to kernel space. 1553 * is in user space so we verify it is OK and move it to kernel space.
@@ -2011,10 +2068,11 @@ out:
2011 2068
2012/* Argument list sizes for sys_socketcall */ 2069/* Argument list sizes for sys_socketcall */
2013#define AL(x) ((x) * sizeof(unsigned long)) 2070#define AL(x) ((x) * sizeof(unsigned long))
2014static const unsigned char nargs[18]={ 2071static const unsigned char nargs[19]={
2015 AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), 2072 AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
2016 AL(3),AL(3),AL(4),AL(4),AL(4),AL(6), 2073 AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
2017 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3) 2074 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3),
2075 AL(6)
2018}; 2076};
2019 2077
2020#undef AL 2078#undef AL
@@ -2033,7 +2091,7 @@ asmlinkage long sys_socketcall(int call, unsigned long __user *args)
2033 unsigned long a0, a1; 2091 unsigned long a0, a1;
2034 int err; 2092 int err;
2035 2093
2036 if (call < 1 || call > SYS_RECVMSG) 2094 if (call < 1 || call > SYS_PACCEPT)
2037 return -EINVAL; 2095 return -EINVAL;
2038 2096
2039 /* copy_from_user should be SMP safe. */ 2097 /* copy_from_user should be SMP safe. */
@@ -2062,8 +2120,8 @@ asmlinkage long sys_socketcall(int call, unsigned long __user *args)
2062 break; 2120 break;
2063 case SYS_ACCEPT: 2121 case SYS_ACCEPT:
2064 err = 2122 err =
2065 sys_accept(a0, (struct sockaddr __user *)a1, 2123 do_accept(a0, (struct sockaddr __user *)a1,
2066 (int __user *)a[2]); 2124 (int __user *)a[2], 0);
2067 break; 2125 break;
2068 case SYS_GETSOCKNAME: 2126 case SYS_GETSOCKNAME:
2069 err = 2127 err =
@@ -2110,6 +2168,13 @@ asmlinkage long sys_socketcall(int call, unsigned long __user *args)
2110 case SYS_RECVMSG: 2168 case SYS_RECVMSG:
2111 err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]); 2169 err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]);
2112 break; 2170 break;
2171 case SYS_PACCEPT:
2172 err =
2173 sys_paccept(a0, (struct sockaddr __user *)a1,
2174 (int __user *)a[2],
2175 (const sigset_t __user *) a[3],
2176 a[4], a[5]);
2177 break;
2113 default: 2178 default:
2114 err = -EINVAL; 2179 err = -EINVAL;
2115 break; 2180 break;