diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/compat.c | 50 | ||||
-rw-r--r-- | net/socket.c | 80 |
2 files changed, 15 insertions, 115 deletions
diff --git a/net/compat.c b/net/compat.c index 6ce1a1cadcc0..a3a2ba0fac08 100644 --- a/net/compat.c +++ b/net/compat.c | |||
@@ -725,7 +725,7 @@ EXPORT_SYMBOL(compat_mc_getsockopt); | |||
725 | static unsigned char nas[19]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), | 725 | static unsigned char nas[19]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), |
726 | AL(3),AL(3),AL(4),AL(4),AL(4),AL(6), | 726 | AL(3),AL(3),AL(4),AL(4),AL(4),AL(6), |
727 | AL(6),AL(2),AL(5),AL(5),AL(3),AL(3), | 727 | AL(6),AL(2),AL(5),AL(5),AL(3),AL(3), |
728 | AL(6)}; | 728 | AL(4)}; |
729 | #undef AL | 729 | #undef AL |
730 | 730 | ||
731 | asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned flags) | 731 | asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned flags) |
@@ -738,52 +738,13 @@ asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, uns | |||
738 | return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); | 738 | return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); |
739 | } | 739 | } |
740 | 740 | ||
741 | asmlinkage long compat_sys_paccept(int fd, struct sockaddr __user *upeer_sockaddr, | ||
742 | int __user *upeer_addrlen, | ||
743 | const compat_sigset_t __user *sigmask, | ||
744 | compat_size_t sigsetsize, int flags) | ||
745 | { | ||
746 | compat_sigset_t ss32; | ||
747 | sigset_t ksigmask, sigsaved; | ||
748 | int ret; | ||
749 | |||
750 | if (sigmask) { | ||
751 | if (sigsetsize != sizeof(compat_sigset_t)) | ||
752 | return -EINVAL; | ||
753 | if (copy_from_user(&ss32, sigmask, sizeof(ss32))) | ||
754 | return -EFAULT; | ||
755 | sigset_from_compat(&ksigmask, &ss32); | ||
756 | |||
757 | sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP)); | ||
758 | sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); | ||
759 | } | ||
760 | |||
761 | ret = do_accept(fd, upeer_sockaddr, upeer_addrlen, flags); | ||
762 | |||
763 | if (ret == -ERESTARTNOHAND) { | ||
764 | /* | ||
765 | * Don't restore the signal mask yet. Let do_signal() deliver | ||
766 | * the signal on the way back to userspace, before the signal | ||
767 | * mask is restored. | ||
768 | */ | ||
769 | if (sigmask) { | ||
770 | memcpy(¤t->saved_sigmask, &sigsaved, | ||
771 | sizeof(sigsaved)); | ||
772 | set_restore_sigmask(); | ||
773 | } | ||
774 | } else if (sigmask) | ||
775 | sigprocmask(SIG_SETMASK, &sigsaved, NULL); | ||
776 | |||
777 | return ret; | ||
778 | } | ||
779 | |||
780 | asmlinkage long compat_sys_socketcall(int call, u32 __user *args) | 741 | asmlinkage long compat_sys_socketcall(int call, u32 __user *args) |
781 | { | 742 | { |
782 | int ret; | 743 | int ret; |
783 | u32 a[6]; | 744 | u32 a[6]; |
784 | u32 a0, a1; | 745 | u32 a0, a1; |
785 | 746 | ||
786 | if (call < SYS_SOCKET || call > SYS_PACCEPT) | 747 | if (call < SYS_SOCKET || call > SYS_ACCEPT4) |
787 | return -EINVAL; | 748 | return -EINVAL; |
788 | if (copy_from_user(a, args, nas[call])) | 749 | if (copy_from_user(a, args, nas[call])) |
789 | return -EFAULT; | 750 | return -EFAULT; |
@@ -804,7 +765,7 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args) | |||
804 | ret = sys_listen(a0, a1); | 765 | ret = sys_listen(a0, a1); |
805 | break; | 766 | break; |
806 | case SYS_ACCEPT: | 767 | case SYS_ACCEPT: |
807 | ret = do_accept(a0, compat_ptr(a1), compat_ptr(a[2]), 0); | 768 | ret = sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), 0); |
808 | break; | 769 | break; |
809 | case SYS_GETSOCKNAME: | 770 | case SYS_GETSOCKNAME: |
810 | ret = sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2])); | 771 | ret = sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2])); |
@@ -844,9 +805,8 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args) | |||
844 | case SYS_RECVMSG: | 805 | case SYS_RECVMSG: |
845 | ret = compat_sys_recvmsg(a0, compat_ptr(a1), a[2]); | 806 | ret = compat_sys_recvmsg(a0, compat_ptr(a1), a[2]); |
846 | break; | 807 | break; |
847 | case SYS_PACCEPT: | 808 | case SYS_ACCEPT4: |
848 | ret = compat_sys_paccept(a0, compat_ptr(a1), compat_ptr(a[2]), | 809 | ret = sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), a[3]); |
849 | compat_ptr(a[3]), a[4], a[5]); | ||
850 | break; | 810 | break; |
851 | default: | 811 | default: |
852 | ret = -EINVAL; | 812 | ret = -EINVAL; |
diff --git a/net/socket.c b/net/socket.c index 57550c3bcabe..92764d836891 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -1426,8 +1426,8 @@ asmlinkage long sys_listen(int fd, int backlog) | |||
1426 | * clean when we restucture accept also. | 1426 | * clean when we restucture accept also. |
1427 | */ | 1427 | */ |
1428 | 1428 | ||
1429 | long do_accept(int fd, struct sockaddr __user *upeer_sockaddr, | 1429 | asmlinkage long sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, |
1430 | int __user *upeer_addrlen, int flags) | 1430 | int __user *upeer_addrlen, int flags) |
1431 | { | 1431 | { |
1432 | struct socket *sock, *newsock; | 1432 | struct socket *sock, *newsock; |
1433 | struct file *newfile; | 1433 | struct file *newfile; |
@@ -1510,66 +1510,10 @@ out_fd: | |||
1510 | goto out_put; | 1510 | goto out_put; |
1511 | } | 1511 | } |
1512 | 1512 | ||
1513 | #if 0 | ||
1514 | #ifdef HAVE_SET_RESTORE_SIGMASK | ||
1515 | asmlinkage long sys_paccept(int fd, struct sockaddr __user *upeer_sockaddr, | ||
1516 | int __user *upeer_addrlen, | ||
1517 | const sigset_t __user *sigmask, | ||
1518 | size_t sigsetsize, int flags) | ||
1519 | { | ||
1520 | sigset_t ksigmask, sigsaved; | ||
1521 | int ret; | ||
1522 | |||
1523 | if (sigmask) { | ||
1524 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
1525 | if (sigsetsize != sizeof(sigset_t)) | ||
1526 | return -EINVAL; | ||
1527 | if (copy_from_user(&ksigmask, sigmask, sizeof(ksigmask))) | ||
1528 | return -EFAULT; | ||
1529 | |||
1530 | sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP)); | ||
1531 | sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); | ||
1532 | } | ||
1533 | |||
1534 | ret = do_accept(fd, upeer_sockaddr, upeer_addrlen, flags); | ||
1535 | |||
1536 | if (ret < 0 && signal_pending(current)) { | ||
1537 | /* | ||
1538 | * Don't restore the signal mask yet. Let do_signal() deliver | ||
1539 | * the signal on the way back to userspace, before the signal | ||
1540 | * mask is restored. | ||
1541 | */ | ||
1542 | if (sigmask) { | ||
1543 | memcpy(¤t->saved_sigmask, &sigsaved, | ||
1544 | sizeof(sigsaved)); | ||
1545 | set_restore_sigmask(); | ||
1546 | } | ||
1547 | } else if (sigmask) | ||
1548 | sigprocmask(SIG_SETMASK, &sigsaved, NULL); | ||
1549 | |||
1550 | return ret; | ||
1551 | } | ||
1552 | #else | ||
1553 | asmlinkage long sys_paccept(int fd, struct sockaddr __user *upeer_sockaddr, | ||
1554 | int __user *upeer_addrlen, | ||
1555 | const sigset_t __user *sigmask, | ||
1556 | size_t sigsetsize, int flags) | ||
1557 | { | ||
1558 | /* The platform does not support restoring the signal mask in the | ||
1559 | * return path. So we do not allow using paccept() with a signal | ||
1560 | * mask. */ | ||
1561 | if (sigmask) | ||
1562 | return -EINVAL; | ||
1563 | |||
1564 | return do_accept(fd, upeer_sockaddr, upeer_addrlen, flags); | ||
1565 | } | ||
1566 | #endif | ||
1567 | #endif | ||
1568 | |||
1569 | asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, | 1513 | asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, |
1570 | int __user *upeer_addrlen) | 1514 | int __user *upeer_addrlen) |
1571 | { | 1515 | { |
1572 | return do_accept(fd, upeer_sockaddr, upeer_addrlen, 0); | 1516 | return sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0); |
1573 | } | 1517 | } |
1574 | 1518 | ||
1575 | /* | 1519 | /* |
@@ -2096,7 +2040,7 @@ static const unsigned char nargs[19]={ | |||
2096 | AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), | 2040 | AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), |
2097 | AL(3),AL(3),AL(4),AL(4),AL(4),AL(6), | 2041 | AL(3),AL(3),AL(4),AL(4),AL(4),AL(6), |
2098 | AL(6),AL(2),AL(5),AL(5),AL(3),AL(3), | 2042 | AL(6),AL(2),AL(5),AL(5),AL(3),AL(3), |
2099 | AL(6) | 2043 | AL(4) |
2100 | }; | 2044 | }; |
2101 | 2045 | ||
2102 | #undef AL | 2046 | #undef AL |
@@ -2115,7 +2059,7 @@ asmlinkage long sys_socketcall(int call, unsigned long __user *args) | |||
2115 | unsigned long a0, a1; | 2059 | unsigned long a0, a1; |
2116 | int err; | 2060 | int err; |
2117 | 2061 | ||
2118 | if (call < 1 || call > SYS_PACCEPT) | 2062 | if (call < 1 || call > SYS_ACCEPT4) |
2119 | return -EINVAL; | 2063 | return -EINVAL; |
2120 | 2064 | ||
2121 | /* copy_from_user should be SMP safe. */ | 2065 | /* copy_from_user should be SMP safe. */ |
@@ -2143,9 +2087,8 @@ asmlinkage long sys_socketcall(int call, unsigned long __user *args) | |||
2143 | err = sys_listen(a0, a1); | 2087 | err = sys_listen(a0, a1); |
2144 | break; | 2088 | break; |
2145 | case SYS_ACCEPT: | 2089 | case SYS_ACCEPT: |
2146 | err = | 2090 | err = sys_accept4(a0, (struct sockaddr __user *)a1, |
2147 | do_accept(a0, (struct sockaddr __user *)a1, | 2091 | (int __user *)a[2], 0); |
2148 | (int __user *)a[2], 0); | ||
2149 | break; | 2092 | break; |
2150 | case SYS_GETSOCKNAME: | 2093 | case SYS_GETSOCKNAME: |
2151 | err = | 2094 | err = |
@@ -2192,12 +2135,9 @@ asmlinkage long sys_socketcall(int call, unsigned long __user *args) | |||
2192 | case SYS_RECVMSG: | 2135 | case SYS_RECVMSG: |
2193 | err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]); | 2136 | err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]); |
2194 | break; | 2137 | break; |
2195 | case SYS_PACCEPT: | 2138 | case SYS_ACCEPT4: |
2196 | err = | 2139 | err = sys_accept4(a0, (struct sockaddr __user *)a1, |
2197 | sys_paccept(a0, (struct sockaddr __user *)a1, | 2140 | (int __user *)a[2], a[3]); |
2198 | (int __user *)a[2], | ||
2199 | (const sigset_t __user *) a[3], | ||
2200 | a[4], a[5]); | ||
2201 | break; | 2141 | break; |
2202 | default: | 2142 | default: |
2203 | err = -EINVAL; | 2143 | err = -EINVAL; |