Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 20 Sep 2025 19:34:28 GMT
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 4c3a868d13c0 - main - fcntl(F_SETFL): only allow one thread to perform F_SETFL
Message-ID:  <202509201934.58KJYSEN040345@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=4c3a868d13c053ef173268cdfe1365978a282178

commit 4c3a868d13c053ef173268cdfe1365978a282178
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-09-11 10:05:04 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-09-20 19:24:10 +0000

    fcntl(F_SETFL): only allow one thread to perform F_SETFL
    
    Use f_vflags file locking for this.
    Allowing more than one thread handling F_SETFL might cause de-sync
    between real driver state and flags.
    
    Reviewed by:    markj
    Tested by:      pho
    Sponsored by:   The FreeBSD Foundation
    MFC after:      2 weeks
    Differential revision:  https://reviews.freebsd.org/D52487
---
 sys/kern/kern_descrip.c |  3 +++
 sys/kern/vfs_vnops.c    | 36 ++++++++++++++++++++++++++++++++++++
 sys/sys/file.h          |  4 ++++
 3 files changed, 43 insertions(+)

diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 2a833d2eafbe..19118eb7f275 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -658,6 +658,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
 			error = EBADF;
 			break;
 		}
+		fsetfl_lock(fp);
 		do {
 			tmp = flg = fp->f_flag;
 			tmp &= ~FCNTLFLAGS;
@@ -677,6 +678,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
 			if (error != 0)
 				goto revert_nonblock;
 		}
+		fsetfl_unlock(fp);
 		fdrop(fp, td);
 		break;
 revert_nonblock:
@@ -691,6 +693,7 @@ revert_flags:
 			tmp |= got_cleared;
 			tmp &= ~got_set;
 		} while (atomic_cmpset_int(&fp->f_flag, flg, tmp) == 0);
+		fsetfl_unlock(fp);
 		fdrop(fp, td);
 		break;
 
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index f81c2033d95e..3d4567b6ab1e 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -896,6 +896,18 @@ foffset_read(struct file *fp)
 	return (atomic_load_long(&fp->f_offset));
 }
 
+void
+fsetfl_lock(struct file *fp)
+{
+	file_v_lock(fp, FILE_V_SETFL_LOCKED, FILE_V_SETFL_LOCK_WAITING);
+}
+
+void
+fsetfl_unlock(struct file *fp)
+{
+	file_v_unlock(fp, FILE_V_SETFL_LOCKED, FILE_V_SETFL_LOCK_WAITING);
+}
+
 #else	/* OFF_MAX <= LONG_MAX */
 
 static void
@@ -971,6 +983,30 @@ foffset_read(struct file *fp)
 
 	return (foffset_lock(fp, FOF_NOLOCK));
 }
+
+void
+fsetfl_lock(struct file *fp)
+{
+	struct mtx *mtxp;
+
+	mtxp = mtx_pool_find(mtxpool_sleep, fp);
+	mtx_lock(mtxp);
+	file_v_lock_mtxp(fp, mtxp, FILE_V_SETFL_LOCKED,
+	    FILE_V_SETFL_LOCK_WAITING);
+	mtx_unlock(mtxp);
+}
+
+void
+fsetfl_unlock(struct file *fp)
+{
+	struct mtx *mtxp;
+
+	mtxp = mtx_pool_find(mtxpool_sleep, fp);
+	mtx_lock(mtxp);
+	file_v_unlock_mtxp(fp, mtxp, FILE_V_SETFL_LOCKED,
+	    FILE_V_SETFL_LOCK_WAITING);
+	mtx_unlock(mtxp);
+}
 #endif
 
 void
diff --git a/sys/sys/file.h b/sys/sys/file.h
index 9a072121e25f..c44fd0f28929 100644
--- a/sys/sys/file.h
+++ b/sys/sys/file.h
@@ -93,6 +93,8 @@ void foffset_lock_pair(struct file *fp1, off_t *off1p, struct file *fp2,
 void foffset_lock_uio(struct file *fp, struct uio *uio, int flags);
 void foffset_unlock(struct file *fp, off_t val, int flags);
 void foffset_unlock_uio(struct file *fp, struct uio *uio, int flags);
+void fsetfl_lock(struct file *fp);
+void fsetfl_unlock(struct file *fp);
 
 static inline off_t
 foffset_get(struct file *fp)
@@ -222,6 +224,8 @@ struct file {
 
 #define	FILE_V_FOFFSET_LOCKED		0x0001
 #define	FILE_V_FOFFSET_LOCK_WAITING	0x0002
+#define	FILE_V_SETFL_LOCKED		0x0004
+#define	FILE_V_SETFL_LOCK_WAITING	0x0008
 #endif /* __BSD_VISIBLE */
 
 #endif /* _KERNEL || _WANT_FILE */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202509201934.58KJYSEN040345>