Page MenuHomeFreeBSD

D60283.id188708.diff
No OneTemporary

D60283.id188708.diff

diff --git a/sys/kern/coredump_vnode.c b/sys/kern/coredump_vnode.c
--- a/sys/kern/coredump_vnode.c
+++ b/sys/kern/coredump_vnode.c
@@ -216,7 +216,7 @@
nextvp = oldvp = NULL;
cmode = S_IRUSR | S_IWUSR;
- oflags = VN_OPEN_NOAUDIT | VN_OPEN_NAMECACHE |
+ oflags = VN_OPEN_NOAUDIT | VN_OPEN_NAMECACHE | VN_OPEN_NOTSUSPENDED |
(capmode_coredump ? VN_OPEN_NOCAPCHECK : 0);
for (i = 0; i < ncores; i++) {
@@ -397,6 +397,7 @@
} else {
cmode = S_IRUSR | S_IWUSR;
oflags = VN_OPEN_NOAUDIT | VN_OPEN_NAMECACHE |
+ VN_OPEN_NOTSUSPENDED |
(capmode_coredump ? VN_OPEN_NOCAPCHECK : 0);
flags = O_CREAT | FWRITE | O_NOFOLLOW;
if ((td->td_proc->p_flag & P_SUGID) != 0)
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -241,6 +241,37 @@
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;
+
+ if ((vn_open_flags & VN_OPEN_NOTSUSPENDED) == 0)
+ return (0);
+ MPASS((curproc->p_flag & P_HADTHREADS) == 0 ||
+ (curproc->p_flag & (P_SINGLE_BOUNDARY | P_SINGLE_EXIT |
+ P_STOPPED)) != 0);
+
+ mp = vp->v_mount;
+ 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)
+ return (0);
+ return (EBUSY);
+}
+
/*
* Common code for vnode open operations via a name lookup.
* Lookup the vnode and invoke VOP_CREATE if needed.
@@ -295,6 +326,12 @@
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,6 +412,10 @@
goto bad;
}
}
+ error = vn_open_nosuspend(vp, vn_open_flags);
+ if (error != 0)
+ goto bad;
+
error = vn_open_vnode(vp, fmode, cred, curthread, fp);
if (first_open) {
VI_LOCK(vp);
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -627,6 +627,7 @@
#define VN_OPEN_NAMECACHE 0x00000004
#define VN_OPEN_INVFS 0x00000008
#define VN_OPEN_WANTIOCTLCAPS 0x00000010
+#define VN_OPEN_NOTSUSPENDED 0x00000020
/* copy_file_range kernel flags */
#define COPY_FILE_RANGE_KFLAGS 0xff000000

File Metadata

Mime Type
text/plain
Expires
Thu, Oct 8, 6:42 AM (7 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40409478
Default Alt Text
D60283.id188708.diff (2 KB)

Event Timeline