git: a4993bac4135 - main - pseudofs: ensure that the target process vmspace is stable for VOP_READ/WRITE
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 21 Jun 2026 11:48:14 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=a4993bac41350e85bc9affb862d2974a1a09bb5e
commit a4993bac41350e85bc9affb862d2974a1a09bb5e
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-06-07 19:39:42 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-06-21 11:46:53 +0000
pseudofs: ensure that the target process vmspace is stable for VOP_READ/WRITE
Reviewed by: markj
Tested by: pho
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D57497
---
sys/fs/pseudofs/pseudofs_vnops.c | 59 ++++++++++++++++++++++++++++------------
1 file changed, 41 insertions(+), 18 deletions(-)
diff --git a/sys/fs/pseudofs/pseudofs_vnops.c b/sys/fs/pseudofs/pseudofs_vnops.c
index d14ed15f3329..229f762914bc 100644
--- a/sys/fs/pseudofs/pseudofs_vnops.c
+++ b/sys/fs/pseudofs/pseudofs_vnops.c
@@ -676,6 +676,7 @@ pfs_read(struct vop_read_args *va)
struct pfs_node *pn = pvd->pvd_pn;
struct uio *uio = va->a_uio;
struct proc *proc;
+ struct thread *td;
struct sbuf *sb = NULL;
int error, locked;
off_t buflen, buflim;
@@ -694,21 +695,30 @@ pfs_read(struct vop_read_args *va)
if (pn->pn_fill == NULL)
PFS_RETURN (EIO);
+ td = curthread;
+
/*
* This is necessary because either process' privileges may
* have changed since the open() call.
*/
- if (!pfs_visible(curthread, pn, pvd->pvd_pid, &proc))
+ if (!pfs_visible(td, pn, pvd->pvd_pid, &proc))
PFS_RETURN (EIO);
- if (proc != NULL) {
- _PHOLD(proc);
- PROC_UNLOCK(proc);
- }
vhold(vn);
locked = VOP_ISLOCKED(vn);
VOP_UNLOCK(vn);
+ if (proc != NULL) {
+ _PHOLD(proc);
+ execve_block_wait(td, proc);
+ if (!pfs_visible_proc(td, pn, proc)) {
+ PROC_UNLOCK(proc);
+ error = EIO;
+ goto ret;
+ }
+ PROC_UNLOCK(proc);
+ }
+
if (pn->pn_flags & PFS_RAWRD) {
PFS_TRACE(("%zd resid", uio->uio_resid));
error = pn_fill(curthread, proc, pn, NULL, uio);
@@ -778,8 +788,12 @@ pfs_read(struct vop_read_args *va)
ret:
vn_lock(vn, locked | LK_RETRY);
vdrop(vn);
- if (proc != NULL)
- PRELE(proc);
+ if (proc != NULL) {
+ PROC_LOCK(proc);
+ execve_unblock(td, proc);
+ _PRELE(proc);
+ PROC_UNLOCK(proc);
+ }
PFS_RETURN (error);
}
@@ -1087,6 +1101,7 @@ pfs_write(struct vop_write_args *va)
struct pfs_node *pn = pvd->pvd_pn;
struct uio *uio = va->a_uio;
struct proc *proc;
+ struct thread *td;
struct sbuf sb;
int error;
@@ -1106,36 +1121,44 @@ pfs_write(struct vop_write_args *va)
if (uio->uio_resid > PFS_MAXBUFSIZ)
PFS_RETURN (EIO);
+ td = curthread;
+
/*
* This is necessary because either process' privileges may
* have changed since the open() call.
*/
- if (!pfs_visible(curthread, pn, pvd->pvd_pid, &proc))
+ if (!pfs_visible(td, pn, pvd->pvd_pid, &proc))
PFS_RETURN (EIO);
if (proc != NULL) {
_PHOLD(proc);
+ execve_block_wait(td, proc);
+ if (!pfs_visible_proc(td, pn, proc)) {
+ PROC_UNLOCK(proc);
+ error = EIO;
+ goto out;
+ }
PROC_UNLOCK(proc);
}
if (pn->pn_flags & PFS_RAWWR) {
error = pn_fill(curthread, proc, pn, NULL, uio);
- if (proc != NULL)
- PRELE(proc);
- PFS_RETURN (error);
+ goto out;
}
sbuf_uionew(&sb, uio, &error);
- if (error) {
- if (proc != NULL)
- PRELE(proc);
- PFS_RETURN (error);
- }
+ if (error != 0)
+ goto out;
error = pn_fill(curthread, proc, pn, &sb, uio);
sbuf_delete(&sb);
- if (proc != NULL)
- PRELE(proc);
+out:
+ if (proc != NULL) {
+ PROC_LOCK(proc);
+ execve_unblock(td, proc);
+ _PRELE(proc);
+ PROC_UNLOCK(proc);
+ }
PFS_RETURN (error);
}