Skip to content

Commit 39897df

Browse files
Jiexun Wangkuba-moo
authored andcommitted
af_unix: read UNIX_DIAG_VFS data under unix_state_lock
Exact UNIX diag lookups hold a reference to the socket, but not to u->path. Meanwhile, unix_release_sock() clears u->path under unix_state_lock() and drops the path reference after unlocking. Read the inode and device numbers for UNIX_DIAG_VFS while holding unix_state_lock(), then emit the netlink attribute after dropping the lock. This keeps the VFS data stable while the reply is being built. Fixes: 5f7b056 ("unix_diag: Unix inode info NLA") Reported-by: Yifan Wu <yifanwucs@gmail.com> Reported-by: Juefei Pu <tomapufckgml@gmail.com> Co-developed-by: Yuan Tan <yuantan098@gmail.com> Signed-off-by: Yuan Tan <yuantan098@gmail.com> Suggested-by: Xin Liu <bird@lzu.edu.cn> Tested-by: Ren Wei <enjou1224z@gmail.com> Signed-off-by: Jiexun Wang <wangjiexun2025@gmail.com> Signed-off-by: Ren Wei <n05ec@lzu.edu.cn> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260407080015.1744197-1-n05ec@lzu.edu.cn Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 8e2760e commit 39897df

1 file changed

Lines changed: 13 additions & 8 deletions

File tree

net/unix/diag.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,23 @@ static int sk_diag_dump_name(struct sock *sk, struct sk_buff *nlskb)
2828

2929
static int sk_diag_dump_vfs(struct sock *sk, struct sk_buff *nlskb)
3030
{
31-
struct dentry *dentry = unix_sk(sk)->path.dentry;
31+
struct unix_diag_vfs uv;
32+
struct dentry *dentry;
33+
bool have_vfs = false;
3234

35+
unix_state_lock(sk);
36+
dentry = unix_sk(sk)->path.dentry;
3337
if (dentry) {
34-
struct unix_diag_vfs uv = {
35-
.udiag_vfs_ino = d_backing_inode(dentry)->i_ino,
36-
.udiag_vfs_dev = dentry->d_sb->s_dev,
37-
};
38-
39-
return nla_put(nlskb, UNIX_DIAG_VFS, sizeof(uv), &uv);
38+
uv.udiag_vfs_ino = d_backing_inode(dentry)->i_ino;
39+
uv.udiag_vfs_dev = dentry->d_sb->s_dev;
40+
have_vfs = true;
4041
}
42+
unix_state_unlock(sk);
4143

42-
return 0;
44+
if (!have_vfs)
45+
return 0;
46+
47+
return nla_put(nlskb, UNIX_DIAG_VFS, sizeof(uv), &uv);
4348
}
4449

4550
static int sk_diag_dump_peer(struct sock *sk, struct sk_buff *nlskb)

0 commit comments

Comments
 (0)