git: eb34be853a21 - stable/13 - Add fget_remote()

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Sun, 11 Feb 2024 01:52:44 UTC
The branch stable/13 has been updated by kib:

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

commit eb34be853a21e05db54ad6f22abe366bc5b6086b
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-01-22 22:31:55 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-02-11 01:40:28 +0000

    Add fget_remote()
    
    (cherry picked from commit 58d3171698341c664d7c676541b86385a924ae93)
---
 sys/kern/kern_descrip.c | 32 ++++++++++++++++++++++++++++++++
 sys/sys/file.h          |  1 +
 2 files changed, 33 insertions(+)

diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 0bd011ac2425..0a28f47bccdf 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -3055,6 +3055,38 @@ get_locked:
 	return (error);
 }
 
+int
+fget_remote(struct thread *td, struct proc *p, int fd, struct file **fpp)
+{
+	struct filedesc *fdp;
+	struct file *fp;
+	int error;
+
+	if (p == td->td_proc)	/* curproc */
+		return (fget_unlocked(p->p_fd, fd, &cap_no_rights, fpp));
+
+	PROC_LOCK(p);
+	fdp = fdhold(p);
+	PROC_UNLOCK(p);
+	if (fdp == NULL)
+		return (ENOENT);
+	FILEDESC_SLOCK(fdp);
+	if (refcount_load(&fdp->fd_refcnt) != 0) {
+		fp = fget_locked(fdp, fd);
+		if (fp != NULL && fhold(fp)) {
+			*fpp = fp;
+			error = 0;
+		} else {
+			error = EBADF;
+		}
+	} else {
+		error = ENOENT;
+	}
+	FILEDESC_SUNLOCK(fdp);
+	fddrop(fdp);
+	return (error);
+}
+
 #ifdef CAPABILITIES
 int
 fgetvp_lookup_smr(int fd, struct nameidata *ndp, struct vnode **vpp, bool *fsearch)
diff --git a/sys/sys/file.h b/sys/sys/file.h
index e5532b37572f..ca8a229b994a 100644
--- a/sys/sys/file.h
+++ b/sys/sys/file.h
@@ -257,6 +257,7 @@ int fget_write(struct thread *td, int fd, cap_rights_t *rightsp,
 int fget_fcntl(struct thread *td, int fd, cap_rights_t *rightsp,
     int needfcntl, struct file **fpp);
 int _fdrop(struct file *fp, struct thread *td);
+int fget_remote(struct thread *td, struct proc *p, int fd, struct file **fpp);
 
 fo_rdwr_t	invfo_rdwr;
 fo_truncate_t	invfo_truncate;