]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/uipc_syscalls.c
xnu-3789.31.2.tar.gz
[apple/xnu.git] / bsd / kern / uipc_syscalls.c
index f44291282652491235f99d5e12165aab78502774..603f8b34d6e370ef5219c5fef63feff93e0d3344 100644 (file)
@@ -491,7 +491,6 @@ accept_nocancel(struct proc *p, struct accept_nocancel_args *uap,
                goto out;
        }
 
-
        /*
         * At this point we know that there is at least one connection
         * ready to be accepted. Remove it from the queue prior to
@@ -502,6 +501,8 @@ accept_nocancel(struct proc *p, struct accept_nocancel_args *uap,
        lck_mtx_assert(mutex_held, LCK_MTX_ASSERT_OWNED);
        so = TAILQ_FIRST(&head->so_comp);
        TAILQ_REMOVE(&head->so_comp, so, so_list);
+       so->so_head = NULL;
+       so->so_state &= ~SS_COMP;
        head->so_qlen--;
        /* unlock head to avoid deadlock with select, keep a ref on head */
        socket_unlock(head, 0);
@@ -515,8 +516,7 @@ accept_nocancel(struct proc *p, struct accept_nocancel_args *uap,
         */
        if ((error = mac_socket_check_accepted(kauth_cred_get(), so)) != 0) {
                socket_lock(so, 1);
-               so->so_state &= ~(SS_NOFDREF | SS_COMP);
-               so->so_head = NULL;
+               so->so_state &= ~SS_NOFDREF;
                socket_unlock(so, 1);
                soclose(so);
                /* Drop reference on listening socket */
@@ -529,7 +529,7 @@ accept_nocancel(struct proc *p, struct accept_nocancel_args *uap,
         * Pass the pre-accepted socket to any interested socket filter(s).
         * Upon failure, the socket would have been closed by the callee.
         */
-       if (so->so_filt != NULL && (error = soacceptfilter(so)) != 0) {
+       if (so->so_filt != NULL && (error = soacceptfilter(so, head)) != 0) {
                /* Drop reference on listening socket */
                sodereference(head);
                /* Propagate socket filter's error code to the caller */
@@ -547,8 +547,7 @@ accept_nocancel(struct proc *p, struct accept_nocancel_args *uap,
                 * just causes the client to spin. Drop the socket.
                 */
                socket_lock(so, 1);
-               so->so_state &= ~(SS_NOFDREF | SS_COMP);
-               so->so_head = NULL;
+               so->so_state &= ~SS_NOFDREF;
                socket_unlock(so, 1);
                soclose(so);
                sodereference(head);
@@ -563,9 +562,6 @@ accept_nocancel(struct proc *p, struct accept_nocancel_args *uap,
        if (dosocklock)
                socket_lock(so, 1);
 
-       so->so_state &= ~SS_COMP;
-       so->so_head = NULL;
-
        /* Sync socket non-blocking/async state with file flags */
        if (fp->f_flag & FNONBLOCK) {
                so->so_state |= SS_NBIO;
@@ -2839,7 +2835,8 @@ getsockaddrlist(struct socket *so, struct sockaddr_list **slp,
 
        *slp = NULL;
 
-       if (uaddr == USER_ADDR_NULL || uaddrlen == 0)
+       if (uaddr == USER_ADDR_NULL || uaddrlen == 0 ||
+           uaddrlen > (sizeof(struct sockaddr_in6) * SOCKADDRLIST_MAX_ENTRIES))
                return (EINVAL);
 
        sl = sockaddrlist_alloc(M_WAITOK);
@@ -2870,7 +2867,7 @@ getsockaddrlist(struct socket *so, struct sockaddr_list **slp,
                } else if (ss.ss_len > sizeof (ss)) {
                        /*
                         * sockaddr_storage size is less than SOCK_MAXADDRLEN,
-                        * so the check here is inclusive.  We could user the
+                        * so the check here is inclusive.  We could use the
                         * latter instead, but seems like an overkill for now.
                         */
                        error = ENAMETOOLONG;
@@ -2878,8 +2875,10 @@ getsockaddrlist(struct socket *so, struct sockaddr_list **slp,
                }
 
                se = sockaddrentry_alloc(M_WAITOK);
-               if (se == NULL)
+               if (se == NULL) {
+                       error = ENOBUFS;
                        break;
+               }
 
                sockaddrlist_insert(sl, se);