mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
kern/coredump_vnode.c: avoid dumping to the mount point we suspended
PR: 299095 Reported by: Rick Richard <[email protected]> Reviewed by: markj Tested by: Rick Richard <[email protected]> (previous version) Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D60283
This commit is contained in:
1 parent
ccd44c5e48
commit
bea382f25b
1 file changed
+45
-1
+45
-1
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user