git: bea382f25b16 - main - kern/coredump_vnode.c: avoid dumping to the mount point we suspended
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 07 Oct 2026 17:01:12 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=bea382f25b16fec0e9a1c2be130935e739075287
commit bea382f25b16fec0e9a1c2be130935e739075287
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-10-03 23:59:30 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-10-07 17:00:53 +0000
kern/coredump_vnode.c: avoid dumping to the mount point we suspended
PR: 299095
Reported by: Rick Richard <rick@sloservers.com>
Reviewed by: markj
Tested by: Rick Richard <rick@sloservers.com> (previous version)
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D60283
---
sys/kern/vfs_vnops.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 45 insertions(+), 1 deletion(-)
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 7b86bb2bdb3f..96b1c5696251 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -241,6 +241,42 @@ vfs_check_namedattr(struct vnode *vp)
return (error);
}
+/*
+ * This check is performed when a vnode is opened for dumping the core
+ * from userspace process. The /dev/ufssuspend device allows userspace
+ * to suspend the UFS volume, and we must check that the dump does not
+ * go into the volume the coredumping process suspended.
+ *
+ * Taking MNT_ILOCK around checks is not required, because the process
+ * is single-threaded around dumping core, and we in particular check
+ * if the current process is the suspension owner.
+ */
+static int
+vn_open_nosuspend(struct vnode *vp, u_int vn_open_flags)
+{
+ struct mount *mp;
+ struct thread *susp_owner;
+ int error;
+
+ if ((vn_open_flags & VN_OPEN_COREDUMP) == 0)
+ return (0);
+ MPASS((curproc->p_flag & P_HADTHREADS) == 0 ||
+ (curproc->p_flag & (P_SINGLE_BOUNDARY | P_SINGLE_EXIT |
+ P_STOPPED)) != 0);
+
+ mp = NULL;
+ error = VOP_GETWRITEMOUNT(vp, &mp);
+ if (error != 0 || mp == NULL)
+ return (0);
+ susp_owner = atomic_load_ptr(&mp->mnt_susp_owner);
+ if ((atomic_load_int(&mp->mnt_kern_flag) & (MNTK_SUSPEND |
+ MNTK_SUSPENDED)) != 0 && susp_owner != NULL &&
+ susp_owner->td_proc == curproc)
+ error = EBUSY;
+ vfs_rel(mp);
+ return (error);
+}
+
/*
* Common code for vnode open operations via a name lookup.
* Lookup the vnode and invoke VOP_CREATE if needed.
@@ -295,6 +331,12 @@ restart:
ndp->ni_dvp = NULL;
goto bad;
}
+ error = vn_open_nosuspend(ndp->ni_dvp, vn_open_flags);
+ if (error != 0) {
+ vp = ndp->ni_dvp;
+ ndp->ni_dvp = NULL;
+ goto bad;
+ }
VATTR_NULL(vap);
vap->va_type = VREG;
vap->va_mode = cmode;
@@ -375,7 +417,9 @@ restart:
goto bad;
}
}
- error = vn_open_vnode(vp, fmode, cred, curthread, fp);
+ error = vn_open_nosuspend(vp, vn_open_flags);
+ if (error == 0)
+ error = vn_open_vnode(vp, fmode, cred, curthread, fp);
if (first_open) {
VI_LOCK(vp);
vp->v_iflag &= ~VI_FOPENING;