The branch main has been updated by kib:

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

commit a4993bac41350e85bc9affb862d2974a1a09bb5e
Author:     Konstantin Belousov <[email protected]>
AuthorDate: 2026-06-07 19:39:42 +0000
Commit:     Konstantin Belousov <[email protected]>
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);
 }
 

Reply via email to