Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'af_unix-prepare-for-skb-drop-reason'

Kuniyuki Iwashima says:

====================
af_unix: Prepare for skb drop reason.

This is a prep series and cleans up error paths in the following
functions

* unix_stream_connect()
* unix_stream_sendmsg()
* unix_dgram_sendmsg()

to make it easy to add skb drop reason for AF_UNIX, which seems to
have a potential user.

https://lore.kernel.org/netdev/CAAf2ycmZHti95WaBR3s+L5Epm1q7sXmvZ-EqCK=-oZj=45tOwQ@mail.gmail.com/

v1: https://lore.kernel.org/netdev/20241206052607.1197-1-kuniyu@amazon.com/
====================

Link: https://patch.msgid.link/20241213110850.25453-1-kuniyu@amazon.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+96 -100
+96 -100
net/unix/af_unix.c
··· 286 286 } 287 287 #endif /* CONFIG_SECURITY_NETWORK */ 288 288 289 - static inline int unix_our_peer(struct sock *sk, struct sock *osk) 290 - { 291 - return unix_peer(osk) == sk; 292 - } 293 - 294 289 static inline int unix_may_send(struct sock *sk, struct sock *osk) 295 290 { 296 - return unix_peer(osk) == NULL || unix_our_peer(sk, osk); 291 + return !unix_peer(osk) || unix_peer(osk) == sk; 297 292 } 298 293 299 294 static inline int unix_recvq_full_lockless(const struct sock *sk) ··· 1558 1563 timeo = sock_sndtimeo(sk, flags & O_NONBLOCK); 1559 1564 1560 1565 /* First of all allocate resources. 1561 - If we will make it after state is locked, 1562 - we will have to recheck all again in any case. 1566 + * If we will make it after state is locked, 1567 + * we will have to recheck all again in any case. 1563 1568 */ 1564 1569 1565 1570 /* create new sock for complete connection */ 1566 1571 newsk = unix_create1(net, NULL, 0, sock->type); 1567 1572 if (IS_ERR(newsk)) { 1568 1573 err = PTR_ERR(newsk); 1569 - newsk = NULL; 1570 1574 goto out; 1571 1575 } 1572 1576 1573 - err = -ENOMEM; 1574 - 1575 1577 /* Allocate skb for sending to listening sock */ 1576 1578 skb = sock_wmalloc(newsk, 1, 0, GFP_KERNEL); 1577 - if (skb == NULL) 1578 - goto out; 1579 + if (!skb) { 1580 + err = -ENOMEM; 1581 + goto out_free_sk; 1582 + } 1579 1583 1580 1584 restart: 1581 1585 /* Find listening sock. */ 1582 1586 other = unix_find_other(net, sunaddr, addr_len, sk->sk_type); 1583 1587 if (IS_ERR(other)) { 1584 1588 err = PTR_ERR(other); 1585 - other = NULL; 1586 - goto out; 1589 + goto out_free_skb; 1587 1590 } 1588 1591 1589 1592 unix_state_lock(other); ··· 1593 1600 goto restart; 1594 1601 } 1595 1602 1596 - err = -ECONNREFUSED; 1597 - if (other->sk_state != TCP_LISTEN) 1603 + if (other->sk_state != TCP_LISTEN || 1604 + other->sk_shutdown & RCV_SHUTDOWN) { 1605 + err = -ECONNREFUSED; 1598 1606 goto out_unlock; 1599 - if (other->sk_shutdown & RCV_SHUTDOWN) 1600 - goto out_unlock; 1607 + } 1601 1608 1602 1609 if (unix_recvq_full_lockless(other)) { 1603 - err = -EAGAIN; 1604 - if (!timeo) 1610 + if (!timeo) { 1611 + err = -EAGAIN; 1605 1612 goto out_unlock; 1613 + } 1606 1614 1607 1615 timeo = unix_wait_for_peer(other, timeo); 1616 + sock_put(other); 1608 1617 1609 1618 err = sock_intr_errno(timeo); 1610 1619 if (signal_pending(current)) 1611 - goto out; 1612 - sock_put(other); 1620 + goto out_free_skb; 1621 + 1613 1622 goto restart; 1614 1623 } 1615 1624 ··· 1696 1701 return 0; 1697 1702 1698 1703 out_unlock: 1699 - if (other) 1700 - unix_state_unlock(other); 1701 - 1702 - out: 1704 + unix_state_unlock(other); 1705 + sock_put(other); 1706 + out_free_skb: 1703 1707 kfree_skb(skb); 1704 - if (newsk) 1705 - unix_release_sock(newsk, 0); 1706 - if (other) 1707 - sock_put(other); 1708 + out_free_sk: 1709 + unix_release_sock(newsk, 0); 1710 + out: 1708 1711 return err; 1709 1712 } 1710 1713 ··· 1957 1964 static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, 1958 1965 size_t len) 1959 1966 { 1960 - DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name); 1961 1967 struct sock *sk = sock->sk, *other = NULL; 1962 1968 struct unix_sock *u = unix_sk(sk); 1963 1969 struct scm_cookie scm; ··· 1972 1980 1973 1981 wait_for_unix_gc(scm.fp); 1974 1982 1975 - err = -EOPNOTSUPP; 1976 - if (msg->msg_flags&MSG_OOB) 1983 + if (msg->msg_flags & MSG_OOB) { 1984 + err = -EOPNOTSUPP; 1977 1985 goto out; 1986 + } 1978 1987 1979 1988 if (msg->msg_namelen) { 1980 - err = unix_validate_addr(sunaddr, msg->msg_namelen); 1989 + err = unix_validate_addr(msg->msg_name, msg->msg_namelen); 1981 1990 if (err) 1982 1991 goto out; 1983 1992 ··· 1987 1994 &msg->msg_namelen, 1988 1995 NULL); 1989 1996 if (err) 1990 - goto out; 1991 - } else { 1992 - sunaddr = NULL; 1993 - err = -ENOTCONN; 1994 - other = unix_peer_get(sk); 1995 - if (!other) 1996 1997 goto out; 1997 1998 } 1998 1999 ··· 1998 2011 goto out; 1999 2012 } 2000 2013 2001 - err = -EMSGSIZE; 2002 - if (len > READ_ONCE(sk->sk_sndbuf) - 32) 2014 + if (len > READ_ONCE(sk->sk_sndbuf) - 32) { 2015 + err = -EMSGSIZE; 2003 2016 goto out; 2017 + } 2004 2018 2005 2019 if (len > SKB_MAX_ALLOC) { 2006 2020 data_len = min_t(size_t, ··· 2015 2027 skb = sock_alloc_send_pskb(sk, len - data_len, data_len, 2016 2028 msg->msg_flags & MSG_DONTWAIT, &err, 2017 2029 PAGE_ALLOC_COSTLY_ORDER); 2018 - if (skb == NULL) 2030 + if (!skb) 2019 2031 goto out; 2020 2032 2021 2033 err = unix_scm_to_skb(&scm, skb, true); ··· 2031 2043 2032 2044 timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); 2033 2045 2034 - restart: 2035 - if (!other) { 2036 - err = -ECONNRESET; 2037 - if (sunaddr == NULL) 2038 - goto out_free; 2039 - 2040 - other = unix_find_other(sock_net(sk), sunaddr, msg->msg_namelen, 2041 - sk->sk_type); 2046 + if (msg->msg_namelen) { 2047 + lookup: 2048 + other = unix_find_other(sock_net(sk), msg->msg_name, 2049 + msg->msg_namelen, sk->sk_type); 2042 2050 if (IS_ERR(other)) { 2043 2051 err = PTR_ERR(other); 2044 - other = NULL; 2052 + goto out_free; 2053 + } 2054 + } else { 2055 + other = unix_peer_get(sk); 2056 + if (!other) { 2057 + err = -ENOTCONN; 2045 2058 goto out_free; 2046 2059 } 2047 2060 } ··· 2050 2061 if (sk_filter(other, skb) < 0) { 2051 2062 /* Toss the packet but do not return any error to the sender */ 2052 2063 err = len; 2053 - goto out_free; 2064 + goto out_sock_put; 2054 2065 } 2055 2066 2067 + restart: 2056 2068 sk_locked = 0; 2057 2069 unix_state_lock(other); 2058 2070 restart_locked: 2059 - err = -EPERM; 2060 - if (!unix_may_send(sk, other)) 2071 + 2072 + if (!unix_may_send(sk, other)) { 2073 + err = -EPERM; 2061 2074 goto out_unlock; 2075 + } 2062 2076 2063 2077 if (unlikely(sock_flag(other, SOCK_DEAD))) { 2064 - /* 2065 - * Check with 1003.1g - what should 2066 - * datagram error 2067 - */ 2078 + /* Check with 1003.1g - what should datagram error */ 2079 + 2068 2080 unix_state_unlock(other); 2069 - sock_put(other); 2070 2081 2071 - if (!sk_locked) 2072 - unix_state_lock(sk); 2073 - 2074 - err = 0; 2075 2082 if (sk->sk_type == SOCK_SEQPACKET) { 2076 2083 /* We are here only when racing with unix_release_sock() 2077 2084 * is clearing @other. Never change state to TCP_CLOSE 2078 2085 * unlike SOCK_DGRAM wants. 2079 2086 */ 2080 - unix_state_unlock(sk); 2081 2087 err = -EPIPE; 2082 - } else if (unix_peer(sk) == other) { 2088 + goto out_sock_put; 2089 + } 2090 + 2091 + if (!sk_locked) 2092 + unix_state_lock(sk); 2093 + 2094 + if (unix_peer(sk) == other) { 2083 2095 unix_peer(sk) = NULL; 2084 2096 unix_dgram_peer_wake_disconnect_wakeup(sk, other); 2085 2097 ··· 2090 2100 unix_dgram_disconnected(sk, other); 2091 2101 sock_put(other); 2092 2102 err = -ECONNREFUSED; 2093 - } else { 2094 - unix_state_unlock(sk); 2103 + goto out_sock_put; 2095 2104 } 2096 2105 2097 - other = NULL; 2098 - if (err) 2099 - goto out_free; 2100 - goto restart; 2106 + unix_state_unlock(sk); 2107 + 2108 + if (!msg->msg_namelen) { 2109 + err = -ECONNRESET; 2110 + goto out_sock_put; 2111 + } 2112 + 2113 + goto lookup; 2101 2114 } 2102 2115 2103 - err = -EPIPE; 2104 - if (other->sk_shutdown & RCV_SHUTDOWN) 2116 + if (other->sk_shutdown & RCV_SHUTDOWN) { 2117 + err = -EPIPE; 2105 2118 goto out_unlock; 2119 + } 2106 2120 2107 2121 if (sk->sk_type != SOCK_SEQPACKET) { 2108 2122 err = security_unix_may_send(sk->sk_socket, other->sk_socket); ··· 2126 2132 2127 2133 err = sock_intr_errno(timeo); 2128 2134 if (signal_pending(current)) 2129 - goto out_free; 2135 + goto out_sock_put; 2130 2136 2131 2137 goto restart; 2132 2138 } ··· 2167 2173 if (sk_locked) 2168 2174 unix_state_unlock(sk); 2169 2175 unix_state_unlock(other); 2176 + out_sock_put: 2177 + sock_put(other); 2170 2178 out_free: 2171 2179 kfree_skb(skb); 2172 2180 out: 2173 - if (other) 2174 - sock_put(other); 2175 2181 scm_destroy(&scm); 2176 2182 return err; 2177 2183 } ··· 2250 2256 2251 2257 wait_for_unix_gc(scm.fp); 2252 2258 2253 - err = -EOPNOTSUPP; 2254 2259 if (msg->msg_flags & MSG_OOB) { 2260 + err = -EOPNOTSUPP; 2255 2261 #if IS_ENABLED(CONFIG_AF_UNIX_OOB) 2256 2262 if (len) 2257 2263 len--; ··· 2264 2270 err = READ_ONCE(sk->sk_state) == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP; 2265 2271 goto out_err; 2266 2272 } else { 2267 - err = -ENOTCONN; 2268 2273 other = unix_peer(sk); 2269 - if (!other) 2274 + if (!other) { 2275 + err = -ENOTCONN; 2270 2276 goto out_err; 2277 + } 2271 2278 } 2272 2279 2273 - if (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN) 2274 - goto pipe_err; 2280 + if (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN) { 2281 + if (!(msg->msg_flags & MSG_NOSIGNAL)) 2282 + send_sig(SIGPIPE, current, 0); 2283 + 2284 + err = -EPIPE; 2285 + goto out_err; 2286 + } 2275 2287 2276 2288 while (sent < len) { 2277 2289 size = len - sent; ··· 2306 2306 2307 2307 /* Only send the fds in the first buffer */ 2308 2308 err = unix_scm_to_skb(&scm, skb, !fds_sent); 2309 - if (err < 0) { 2310 - kfree_skb(skb); 2311 - goto out_err; 2312 - } 2309 + if (err < 0) 2310 + goto out_free; 2311 + 2313 2312 fds_sent = true; 2314 2313 2315 2314 if (unlikely(msg->msg_flags & MSG_SPLICE_PAGES)) { 2316 2315 skb->ip_summed = CHECKSUM_UNNECESSARY; 2317 2316 err = skb_splice_from_iter(skb, &msg->msg_iter, size, 2318 2317 sk->sk_allocation); 2319 - if (err < 0) { 2320 - kfree_skb(skb); 2321 - goto out_err; 2322 - } 2318 + if (err < 0) 2319 + goto out_free; 2320 + 2323 2321 size = err; 2324 2322 refcount_add(size, &sk->sk_wmem_alloc); 2325 2323 } else { ··· 2325 2327 skb->data_len = data_len; 2326 2328 skb->len = size; 2327 2329 err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size); 2328 - if (err) { 2329 - kfree_skb(skb); 2330 - goto out_err; 2331 - } 2330 + if (err) 2331 + goto out_free; 2332 2332 } 2333 2333 2334 2334 unix_state_lock(other); 2335 2335 2336 2336 if (sock_flag(other, SOCK_DEAD) || 2337 2337 (other->sk_shutdown & RCV_SHUTDOWN)) 2338 - goto pipe_err_free; 2338 + goto out_pipe; 2339 2339 2340 2340 maybe_add_creds(skb, sock, other); 2341 2341 scm_stat_add(other, skb); ··· 2356 2360 2357 2361 return sent; 2358 2362 2359 - pipe_err_free: 2363 + out_pipe: 2360 2364 unix_state_unlock(other); 2361 - kfree_skb(skb); 2362 - pipe_err: 2363 - if (sent == 0 && !(msg->msg_flags&MSG_NOSIGNAL)) 2365 + if (!sent && !(msg->msg_flags & MSG_NOSIGNAL)) 2364 2366 send_sig(SIGPIPE, current, 0); 2365 2367 err = -EPIPE; 2368 + out_free: 2369 + kfree_skb(skb); 2366 2370 out_err: 2367 2371 scm_destroy(&scm); 2368 2372 return sent ? : err;