git: 6fd60c4887cb - main - ufs: st_rdev is only meaningful for special nodes

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Sun, 17 Aug 2025 16:11:17 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=6fd60c4887cb08203f654e6aac6b4dbaaf76111b

commit 6fd60c4887cb08203f654e6aac6b4dbaaf76111b
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-08-17 13:03:05 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-08-17 16:06:44 +0000

    ufs: st_rdev is only meaningful for special nodes
    
    Instead of leaking di_db[0] (for regular files this is the index of the
    first block of the file), return NODEV when not a special node.
    
    Reported and reviewed by:       des
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D51943
---
 sys/ufs/ufs/ufs_vnops.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index ffc993aef9fc..c1cf2dcdaa9f 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -540,7 +540,8 @@ ufs_stat(struct vop_stat_args *ap)
 	sb->st_uid = ip->i_uid;
 	sb->st_gid = ip->i_gid;
 	if (I_IS_UFS1(ip)) {
-		sb->st_rdev = ip->i_din1->di_rdev;
+		sb->st_rdev = (vp->v_type == VBLK || vp->v_type == VCHR) ?
+		    ip->i_din1->di_rdev : NODEV;
 		sb->st_size = ip->i_din1->di_size;
 		sb->st_mtim.tv_sec = ip->i_din1->di_mtime;
 		sb->st_mtim.tv_nsec = ip->i_din1->di_mtimensec;
@@ -551,7 +552,8 @@ ufs_stat(struct vop_stat_args *ap)
 		sb->st_blocks = dbtob((uint64_t)ip->i_din1->di_blocks) / S_BLKSIZE;
 		sb->st_filerev = ip->i_din1->di_modrev;
 	} else {
-		sb->st_rdev = ip->i_din2->di_rdev;
+		sb->st_rdev = (vp->v_type == VBLK || vp->v_type == VCHR) ?
+		    ip->i_din2->di_rdev : NODEV;
 		sb->st_size = ip->i_din2->di_size;
 		sb->st_mtim.tv_sec = ip->i_din2->di_mtime;
 		sb->st_mtim.tv_nsec = ip->i_din2->di_mtimensec;
@@ -603,7 +605,8 @@ ufs_getattr(
 	vap->va_uid = ip->i_uid;
 	vap->va_gid = ip->i_gid;
 	if (I_IS_UFS1(ip)) {
-		vap->va_rdev = ip->i_din1->di_rdev;
+		vap->va_rdev = (vp->v_type == VBLK || vp->v_type == VCHR) ?
+		    ip->i_din1->di_rdev : NODEV;
 		vap->va_size = ip->i_din1->di_size;
 		vap->va_mtime.tv_sec = ip->i_din1->di_mtime;
 		vap->va_mtime.tv_nsec = ip->i_din1->di_mtimensec;
@@ -612,7 +615,8 @@ ufs_getattr(
 		vap->va_bytes = dbtob((uint64_t)ip->i_din1->di_blocks);
 		vap->va_filerev = ip->i_din1->di_modrev;
 	} else {
-		vap->va_rdev = ip->i_din2->di_rdev;
+		vap->va_rdev = (vp->v_type == VBLK || vp->v_type == VCHR) ?
+		    ip->i_din2->di_rdev : NODEV;
 		vap->va_size = ip->i_din2->di_size;
 		vap->va_mtime.tv_sec = ip->i_din2->di_mtime;
 		vap->va_mtime.tv_nsec = ip->i_din2->di_mtimensec;