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; |
