The branch stable/13 has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=9258e9e3a867a1135199a03b8d3db1bf06823448

commit 9258e9e3a867a1135199a03b8d3db1bf06823448
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2021-12-05 18:45:50 +0000
Commit:     Konstantin Belousov <k...@freebsd.org>
CommitDate: 2021-12-13 00:58:22 +0000

    fcntl(2): add F_KINFO operation
    
    (cherry picked from commit 794d3e8e63f4a6ebc8926030b6c937109ddc5485)
---
 lib/libc/sys/fcntl.2                  | 17 ++++++++++++++--
 sys/compat/freebsd32/freebsd32_misc.c |  1 +
 sys/kern/kern_descrip.c               | 38 ++++++++++++++++++++++++++++++++++-
 sys/sys/fcntl.h                       |  1 +
 4 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/lib/libc/sys/fcntl.2 b/lib/libc/sys/fcntl.2
index 33ad7a5673e1..c0a13ee6df18 100644
--- a/lib/libc/sys/fcntl.2
+++ b/lib/libc/sys/fcntl.2
@@ -28,7 +28,7 @@
 .\"     @(#)fcntl.2    8.2 (Berkeley) 1/12/94
 .\" $FreeBSD$
 .\"
-.Dd January 6, 2021
+.Dd December 7, 2021
 .Dt FCNTL 2
 .Os
 .Sh NAME
@@ -53,7 +53,7 @@ Depending on the value of
 .Fa cmd ,
 .Fn fcntl
 can take an additional third argument
-.Fa "int arg" .
+.Fa "long arg" .
 .Bl -tag -width F_DUP2FD_CLOEXEC
 .It Dv F_DUPFD
 Return a new descriptor as follows:
@@ -190,6 +190,19 @@ Check if the vnode is part of a union stack (either the 
"union" flag from
 .Xr mount 2
 or unionfs).
 This is a hack not intended to be used outside of libc.
+.It Dv F_KINFO
+Fills a
+.Vt struct kinfo_file
+for the file referenced by the specified file descriptor.
+The
+.Fa arg
+argument should point to the storage for
+.Vt struct kinfo_file .
+The
+.Va kf_structsize
+member of the passed structure must be initialized with the sizeof of
+.Vt struct kinfo_file ,
+to allow for the interface versioning and evolution.
 .El
 .Pp
 The flags for the
diff --git a/sys/compat/freebsd32/freebsd32_misc.c 
b/sys/compat/freebsd32/freebsd32_misc.c
index fd5ef9171982..db707fdbf44d 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -3716,6 +3716,7 @@ freebsd32_fcntl(struct thread *td, struct 
freebsd32_fcntl_args *uap)
        case F_OGETLK:
        case F_OSETLK:
        case F_OSETLKW:
+       case F_KINFO:
                tmp = (unsigned int)(uap->arg);
                break;
        default:
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 5247f8f12e6a..a8952a5e1595 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -480,7 +480,8 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
        struct proc *p;
        struct vnode *vp;
        struct mount *mp;
-       int error, flg, seals, tmp;
+       struct kinfo_file *kif;
+       int error, flg, kif_sz, seals, tmp;
        uint64_t bsize;
        off_t foffset;
 
@@ -855,6 +856,41 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t 
arg)
                fdrop(fp, td);
                break;
 
+       case F_KINFO:
+#ifdef CAPABILITY_MODE
+               if (IN_CAPABILITY_MODE(td)) {
+                       error = ECAPMODE;
+                       break;
+               }
+#endif
+               error = copyin((void *)arg, &kif_sz, sizeof(kif_sz));
+               if (error != 0)
+                       break;
+               if (kif_sz != sizeof(*kif)) {
+                       error = EINVAL;
+                       break;
+               }
+               kif = malloc(sizeof(*kif), M_TEMP, M_WAITOK | M_ZERO);
+               FILEDESC_SLOCK(fdp);
+               error = fget_cap_locked(fdp, fd, &cap_fcntl_rights, &fp, NULL);
+               if (error == 0 && fhold(fp)) {
+                       export_file_to_kinfo(fp, fd, NULL, kif, fdp, 0);
+                       FILEDESC_SUNLOCK(fdp);
+                       fdrop(fp, td);
+                       if ((kif->kf_status & KF_ATTR_VALID) != 0) {
+                               kif->kf_structsize = sizeof(*kif);
+                               error = copyout(kif, (void *)arg, sizeof(*kif));
+                       } else {
+                               error = EBADF;
+                       }
+               } else {
+                       FILEDESC_SUNLOCK(fdp);
+                       if (error == 0)
+                               error = EBADF;
+               }
+               free(kif, M_TEMP);
+               break;
+
        default:
                error = EINVAL;
                break;
diff --git a/sys/sys/fcntl.h b/sys/sys/fcntl.h
index 8fa52aeacafd..65b546abb8ab 100644
--- a/sys/sys/fcntl.h
+++ b/sys/sys/fcntl.h
@@ -270,6 +270,7 @@ typedef     __pid_t         pid_t;
 #define        F_ADD_SEALS     19
 #define        F_GET_SEALS     20
 #define        F_ISUNIONSTACK  21              /* Kludge for libc, don't use 
it. */
+#define        F_KINFO         22              /* Return kinfo_file for this 
fd */
 
 /* Seals (F_ADD_SEALS, F_GET_SEALS). */
 #define        F_SEAL_SEAL     0x0001          /* Prevent adding sealings */

Reply via email to