[RFC PATCH 1/3] af_unix: factor out unix_lookup_bsd_path()
From: John Ericson <hidden>
Date: 2026-07-03 07:40:48
Also in:
linux-fsdevel, linux-security-module, lkml
Subsystem:
networking [general], networking [unix sockets], the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Kuniyuki Iwashima, Linus Torvalds
From: John Ericson <redacted> Split the inode -> sock mapping out of `unix_find_bsd()` into a new helper, `unix_lookup_bsd_path()`: given an already-resolved `struct path`, check it is a socket, look the bound socket up by inode, and check its type, returning a held `struct sock` (or an `ERR_PTR`). `unix_find_bsd()` keeps doing the path resolution, the `MAY_WRITE` permission check, the `security_unix_find()` LSM hook and `touch_atime()`, and calls the helper for the lookup. No functional change. The function documentation anticipates (in an example) the way this will be used later in the patch series. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: John Ericson <redacted> --- include/net/af_unix.h | 1 + net/unix/af_unix.c | 50 ++++++++++++++++++++++++++++++++----------- 2 files changed, 39 insertions(+), 12 deletions(-)
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 34f53dde65ce..fe4547508af1 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h@@ -14,6 +14,7 @@ #if IS_ENABLED(CONFIG_UNIX) struct unix_sock *unix_get_socket(struct file *filp); +struct sock *unix_lookup_bsd_path(const struct path *path, int type); #else static inline struct unix_sock *unix_get_socket(struct file *filp) {
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index f7a9d55eee8a..3270299238c4 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c@@ -1185,10 +1185,43 @@ static int unix_release(struct socket *sock) return 0; } +/** + * unix_lookup_bsd_path - find the AF_UNIX socket bound at a resolved path + * @path: a path the caller has already resolved under its own policy + * @type: required socket type (SOCK_STREAM/SOCK_SEQPACKET/SOCK_DGRAM) + * + * Unlike the connect(2) lookup, this performs no path resolution and no + * DAC or LSM check of its own: the caller is responsible for having + * resolved @path with whatever policy is appropriate. Used by kernel + * callers (e.g. coredump-to-socket) that must resolve the path under + * their own root and credentials rather than the current task's. + * + * Returns a held sock, or an ERR_PTR. + */ +struct sock *unix_lookup_bsd_path(const struct path *path, int type) +{ + struct inode *inode = d_backing_inode(path->dentry); + struct sock *sk; + + if (!S_ISSOCK(inode->i_mode)) + return ERR_PTR(-ECONNREFUSED); + + sk = unix_find_socket_byinode(inode); + if (!sk) + return ERR_PTR(-ECONNREFUSED); + + if (sk->sk_type != type) { + sock_put(sk); + return ERR_PTR(-EPROTOTYPE); + } + + return sk; +} +EXPORT_SYMBOL_GPL(unix_lookup_bsd_path); + static struct sock *unix_find_bsd(struct sockaddr_un *sunaddr, int addr_len, int type, int flags) { - struct inode *inode; struct path path; struct sock *sk; int err;
@@ -1219,18 +1252,11 @@ static struct sock *unix_find_bsd(struct sockaddr_un *sunaddr, int addr_len, goto path_put; } - err = -ECONNREFUSED; - inode = d_backing_inode(path.dentry); - if (!S_ISSOCK(inode->i_mode)) + sk = unix_lookup_bsd_path(&path, type); + if (IS_ERR(sk)) { + err = PTR_ERR(sk); goto path_put; - - sk = unix_find_socket_byinode(inode); - if (!sk) - goto path_put; - - err = -EPROTOTYPE; - if (sk->sk_type != type) - goto sock_put; + } err = security_unix_find(&path, sk, flags); if (err)
--
2.54.0