git: 850d4562928e - main - cdevsw: add D_NONPASSABLE flag

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Mon, 05 Oct 2026 22:19:29 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=850d4562928ea9308dd9188d5014bcabe7049938

commit 850d4562928ea9308dd9188d5014bcabe7049938
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-10-04 00:50:23 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-10-05 21:56:53 +0000

    cdevsw: add D_NONPASSABLE flag
    
    to make the opened device files non-passable.
    
    Reviewed by:    markj
    Tested by:      pho (previous version)
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D60285
---
 sys/fs/devfs/devfs_vnops.c | 27 +++++++++++++++++++++++++--
 sys/sys/conf.h             |  2 ++
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
index d594b1584757..cd6cd1959d6b 100644
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -67,6 +67,7 @@
 static struct vop_vector devfs_vnodeops;
 static struct vop_vector devfs_specops;
 static const struct fileops devfs_ops_f;
+static const struct fileops devfs_ops_nonpassable_f;
 
 #include <fs/devfs/devfs.h>
 #include <fs/devfs/devfs_int.h>
@@ -1344,8 +1345,11 @@ devfs_open(struct vop_open_args *ap)
 	if (fp == NULL)
 		return (error);
 #endif
-	if (fp->f_ops == &badfileops)
-		finit(fp, fp->f_flag, DTYPE_VNODE, dev, &devfs_ops_f);
+	if (fp->f_ops == &badfileops) {
+		finit(fp, fp->f_flag, DTYPE_VNODE, dev,
+		    (dsw->d_flags & D_NONPASSABLE) == 0 ? &devfs_ops_f :
+		    &devfs_ops_nonpassable_f);
+	}
 	return (error);
 }
 
@@ -2096,6 +2100,25 @@ static const struct fileops devfs_ops_f = {
 	.fo_flags =	DFLAG_PASSABLE | DFLAG_SEEKABLE
 };
 
+static const struct fileops devfs_ops_nonpassable_f = {
+	.fo_read =	devfs_read_f,
+	.fo_write =	devfs_write_f,
+	.fo_truncate =	devfs_truncate_f,
+	.fo_ioctl =	devfs_ioctl_f,
+	.fo_poll =	devfs_poll_f,
+	.fo_kqfilter =	devfs_kqfilter_f,
+	.fo_stat =	devfs_stat_f,
+	.fo_close =	devfs_close_f,
+	.fo_chmod =	vn_chmod,
+	.fo_chown =	vn_chown,
+	.fo_sendfile =	vn_sendfile,
+	.fo_seek =	vn_seek,
+	.fo_fill_kinfo = vn_fill_kinfo,
+	.fo_mmap =	devfs_mmap_f,
+	.fo_cmp =	devfs_cmp_f,
+	.fo_flags =	DFLAG_SEEKABLE
+};
+
 /* Vops for non-CHR vnodes in /dev. */
 static struct vop_vector devfs_vnodeops = {
 	.vop_default =		&default_vnodeops,
diff --git a/sys/sys/conf.h b/sys/sys/conf.h
index a6713ee91190..bf626298c05f 100644
--- a/sys/sys/conf.h
+++ b/sys/sys/conf.h
@@ -177,6 +177,8 @@ typedef int dumper_hdr_t(struct dumperinfo *di, struct kerneldumpheader *kdh);
 #define	D_GIANTOK	0x00200000	/* suppress warning about using Giant */
 #define	D_NEEDGIANT	0x00400000	/* driver want Giant */
 #define	D_NEEDMINOR	0x00800000	/* driver uses clone_create() */
+#define	D_NONPASSABLE	0x01000000	/* file is not passable with
+					   SCM_RIGHTS or fork(2) */
 
 /*
  * Version numbers.