git: 08539f60ebeb - releng/15.1 - file: Add a helper function to check whether filecaps are full

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Tue, 29 Sep 2026 16:00:05 UTC
The branch releng/15.1 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=08539f60ebeb748dfa5dab08bc098c766db1261a

commit 08539f60ebeb748dfa5dab08bc098c766db1261a
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-09-28 14:42:29 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-09-29 01:01:48 +0000

    file: Add a helper function to check whether filecaps are full
    
    In a couple of places we want to know whether someone has limited rights
    on an fd.  There, we want a predicate which determines whether the set
    of rights is smaller than CAP_ALL, and whether there are explicit ioctl
    or fcntl lists.  Factor this out into a helper function, in preparation
    for use elsewhere.
    
    No functional change intended.
    
    Approved by:    so
    Security:       FreeBSD-SA-26:66.jail
    Reviewed by:    kib
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D59884
---
 sys/kern/kern_descrip.c | 20 ++++++++++++--------
 sys/sys/filedesc.h      |  1 +
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 2fa0621bdfca..e9ee752712f0 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1935,6 +1935,16 @@ filecaps_free(struct filecaps *fcaps)
 	bzero(fcaps, sizeof(*fcaps));
 }
 
+bool
+filecaps_full(const struct filecaps *fcaps)
+{
+	cap_rights_t allrights;
+
+	CAP_ALL(&allrights);
+	return (cap_rights_contains(&fcaps->fc_rights, &allrights) &&
+	    fcaps->fc_fcntls == CAP_FCNTL_ALL && fcaps->fc_nioctls == -1);
+}
+
 static u_long *
 filecaps_free_prep(struct filecaps *fcaps)
 {
@@ -3257,10 +3267,7 @@ fgetvp_lookup_smr(struct nameidata *ndp, struct vnode **vpp, int *flagsp)
 	 *
 	 * Not yet supported by fast path.
 	 */
-	CAP_ALL(&rights);
-	if (!cap_rights_contains(&ndp->ni_filecaps.fc_rights, &rights) ||
-	    ndp->ni_filecaps.fc_fcntls != CAP_FCNTL_ALL ||
-	    ndp->ni_filecaps.fc_nioctls != -1) {
+	if (!filecaps_full(&ndp->ni_filecaps)) {
 #ifdef notyet
 		ndp->ni_lcf |= NI_LCF_STRICTREL;
 #else
@@ -3362,10 +3369,7 @@ fgetvp_lookup(struct nameidata *ndp, struct vnode **vpp)
 	 * all lookups relative to it must also be
 	 * strictly relative.
 	 */
-	CAP_ALL(&rights);
-	if (!cap_rights_contains(&ndp->ni_filecaps.fc_rights, &rights) ||
-	    ndp->ni_filecaps.fc_fcntls != CAP_FCNTL_ALL ||
-	    ndp->ni_filecaps.fc_nioctls != -1) {
+	if (!filecaps_full(&ndp->ni_filecaps)) {
 		ndp->ni_lcf |= NI_LCF_STRICTREL;
 		ndp->ni_resflags |= NIRES_STRICTREL;
 	}
diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h
index c6499a18b884..2f9dedec1905 100644
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -244,6 +244,7 @@ bool	filecaps_copy(const struct filecaps *src, struct filecaps *dst,
 	    bool locked);
 void	filecaps_move(struct filecaps *src, struct filecaps *dst);
 void	filecaps_free(struct filecaps *fcaps);
+bool	filecaps_full(const struct filecaps *fcaps);
 
 int	closef(struct file *fp, struct thread *td);
 void	closef_nothread(struct file *fp);