git: 794d3e8e63f4 - main - fcntl(2): add F_KINFO operation
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 06 Dec 2021 20:18:34 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=794d3e8e63f4a6ebc8926030b6c937109ddc5485
commit 794d3e8e63f4a6ebc8926030b6c937109ddc5485
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2021-12-05 18:45:50 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2021-12-06 20:18:09 +0000
fcntl(2): add F_KINFO operation
that returns struct kinfo_file for the given file descriptor. Among
other data, it also returns kf_path, if file op was able to restore file
path.
Reviewed by: jhb, markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D33277
---
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 a51daec85fcd..89322772a83c 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -3767,6 +3767,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 8970e80a9818..03cc77ff31ba 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 934c648aecc0..491b0172a1e6 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 */