summaryrefslogtreecommitdiff
path: root/net/unix/af_unix.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-07-27 22:27:37 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2023-07-27 22:27:37 +0300
commit57012c57536f8814dec92e74197ee96c3498d24e (patch)
treeb389b460d60875b408845384d8244be0227fc8ee /net/unix/af_unix.c
parentbc168790de87bd70371793cfecb0fab26f85b857 (diff)
parentde52e17326c3e9a719c9ead4adb03467b8fae0ef (diff)
downloadlinux-57012c57536f8814dec92e74197ee96c3498d24e.tar.xz
Merge tag 'net-6.5-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Paolo Abeni: "Including fixes from can, netfilter. Current release - regressions: - core: fix splice_to_socket() for O_NONBLOCK socket - af_unix: fix fortify_panic() in unix_bind_bsd(). - can: raw: fix lockdep issue in raw_release() Previous releases - regressions: - tcp: reduce chance of collisions in inet6_hashfn(). - netfilter: skip immediate deactivate in _PREPARE_ERROR - tipc: stop tipc crypto on failure in tipc_node_create - eth: igc: fix kernel panic during ndo_tx_timeout callback - eth: iavf: fix potential deadlock on allocation failure Previous releases - always broken: - ipv6: fix bug where deleting a mngtmpaddr can create a new temporary address - eth: ice: fix memory management in ice_ethtool_fdir.c - eth: hns3: fix the imp capability bit cannot exceed 32 bits issue - eth: vxlan: calculate correct header length for GPE - eth: stmmac: apply redundant write work around on 4.xx too" * tag 'net-6.5-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (49 commits) tipc: stop tipc crypto on failure in tipc_node_create af_unix: Terminate sun_path when bind()ing pathname socket. tipc: check return value of pskb_trim() benet: fix return value check in be_lancer_xmit_workarounds() virtio-net: fix race between set queues and probe net/sched: mqprio: Add length check for TCA_MQPRIO_{MAX/MIN}_RATE64 splice, net: Fix splice_to_socket() for O_NONBLOCK socket net: fec: tx processing does not call XDP APIs if budget is 0 mptcp: more accurate NL event generation selftests: mptcp: join: only check for ip6tables if needed tools: ynl-gen: fix parse multi-attr enum attribute tools: ynl-gen: fix enum index in _decode_enum(..) netfilter: nf_tables: disallow rule addition to bound chain via NFTA_RULE_CHAIN_ID netfilter: nf_tables: skip immediate deactivate in _PREPARE_ERROR netfilter: nft_set_rbtree: fix overlap expiration walk igc: Fix Kernel Panic during ndo_tx_timeout callback net: dsa: qca8k: fix mdb add/del case with 0 VID net: dsa: qca8k: fix broken search_and_del net: dsa: qca8k: fix search_and_insert wrong handling of new rule net: dsa: qca8k: enable use_single_write for qca8xxx ...
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r--net/unix/af_unix.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 123b35ddfd71..78585217f61a 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -289,17 +289,29 @@ static int unix_validate_addr(struct sockaddr_un *sunaddr, int addr_len)
return 0;
}
-static void unix_mkname_bsd(struct sockaddr_un *sunaddr, int addr_len)
+static int unix_mkname_bsd(struct sockaddr_un *sunaddr, int addr_len)
{
+ struct sockaddr_storage *addr = (struct sockaddr_storage *)sunaddr;
+ short offset = offsetof(struct sockaddr_storage, __data);
+
+ BUILD_BUG_ON(offset != offsetof(struct sockaddr_un, sun_path));
+
/* This may look like an off by one error but it is a bit more
* subtle. 108 is the longest valid AF_UNIX path for a binding.
* sun_path[108] doesn't as such exist. However in kernel space
* we are guaranteed that it is a valid memory location in our
* kernel address buffer because syscall functions always pass
* a pointer of struct sockaddr_storage which has a bigger buffer
- * than 108.
+ * than 108. Also, we must terminate sun_path for strlen() in
+ * getname_kernel().
+ */
+ addr->__data[addr_len - offset] = 0;
+
+ /* Don't pass sunaddr->sun_path to strlen(). Otherwise, 108 will
+ * cause panic if CONFIG_FORTIFY_SOURCE=y. Let __fortify_strlen()
+ * know the actual buffer.
*/
- ((char *)sunaddr)[addr_len] = 0;
+ return strlen(addr->__data) + offset + 1;
}
static void __unix_remove_socket(struct sock *sk)
@@ -1208,10 +1220,7 @@ static int unix_bind_bsd(struct sock *sk, struct sockaddr_un *sunaddr,
struct path parent;
int err;
- unix_mkname_bsd(sunaddr, addr_len);
- addr_len = strlen(sunaddr->sun_path) +
- offsetof(struct sockaddr_un, sun_path) + 1;
-
+ addr_len = unix_mkname_bsd(sunaddr, addr_len);
addr = unix_create_addr(sunaddr, addr_len);
if (!addr)
return -ENOMEM;