X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=net%2Fsocket.c;h=ea8f81abc45cee0dcc69e6375c37d109d31ab807;hb=90f30eccf41302a2542f5d374af243061902bd98;hp=5f374e1ff5268922371fa6c485f63a5ae2089ba6;hpb=b22364c8eec89e6b0c081a237f3b6348df87796f;p=linux-2.6-omap-h63xx.git diff --git a/net/socket.c b/net/socket.c index 5f374e1ff52..ea8f81abc45 100644 --- a/net/socket.c +++ b/net/socket.c @@ -117,7 +117,7 @@ static ssize_t sock_sendpage(struct file *file, struct page *page, * in the operation structures but are done directly via the socketcall() multiplexor. */ -static struct file_operations socket_file_ops = { +static const struct file_operations socket_file_ops = { .owner = THIS_MODULE, .llseek = no_llseek, .aio_read = sock_aio_read, @@ -1194,6 +1194,7 @@ asmlinkage long sys_socketpair(int family, int type, int protocol, { struct socket *sock1, *sock2; int fd1, fd2, err; + struct file *newfile1, *newfile2; /* * Obtain the first socket and check if the underlying protocol @@ -1212,18 +1213,37 @@ asmlinkage long sys_socketpair(int family, int type, int protocol, if (err < 0) goto out_release_both; - fd1 = fd2 = -1; + fd1 = sock_alloc_fd(&newfile1); + if (unlikely(fd1 < 0)) + goto out_release_both; - err = sock_map_fd(sock1); - if (err < 0) + fd2 = sock_alloc_fd(&newfile2); + if (unlikely(fd2 < 0)) { + put_filp(newfile1); + put_unused_fd(fd1); goto out_release_both; - fd1 = err; + } - err = sock_map_fd(sock2); - if (err < 0) - goto out_close_1; - fd2 = err; + err = sock_attach_fd(sock1, newfile1); + if (unlikely(err < 0)) { + goto out_fd2; + } + + err = sock_attach_fd(sock2, newfile2); + if (unlikely(err < 0)) { + fput(newfile1); + goto out_fd1; + } + + err = audit_fd_pair(fd1, fd2); + if (err < 0) { + fput(newfile1); + fput(newfile2); + goto out_fd; + } + fd_install(fd1, newfile1); + fd_install(fd2, newfile2); /* fd1 and fd2 may be already another descriptors. * Not kernel problem. */ @@ -1238,17 +1258,23 @@ asmlinkage long sys_socketpair(int family, int type, int protocol, sys_close(fd1); return err; -out_close_1: - sock_release(sock2); - sys_close(fd1); - return err; - out_release_both: sock_release(sock2); out_release_1: sock_release(sock1); out: return err; + +out_fd2: + put_filp(newfile1); + sock_release(sock1); +out_fd1: + put_filp(newfile2); + sock_release(sock2); +out_fd: + put_unused_fd(fd1); + put_unused_fd(fd2); + goto out; } /* @@ -1355,7 +1381,7 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, err = sock_attach_fd(newsock, newfile); if (err < 0) - goto out_fd; + goto out_fd_simple; err = security_socket_accept(sock, newsock); if (err) @@ -1388,6 +1414,11 @@ out_put: fput_light(sock->file, fput_needed); out: return err; +out_fd_simple: + sock_release(newsock); + put_filp(newfile); + put_unused_fd(newfd); + goto out_put; out_fd: fput(newfile); put_unused_fd(newfd); @@ -2180,7 +2211,7 @@ done: } int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen, - int flags) + int flags) { return sock->ops->connect(sock, addr, addrlen, flags); }