Page MenuHomeFreeBSD

D60283.id188882.diff
No OneTemporary

D60283.id188882.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_COREDUMP |
(capmode_coredump ? VN_OPEN_NOCAPCHECK : 0);
for (i = 0; i < ncores; i++) {
@@ -396,7 +396,7 @@
}
} else {
cmode = S_IRUSR | S_IWUSR;
- oflags = VN_OPEN_NOAUDIT | VN_OPEN_NAMECACHE |
+ oflags = VN_OPEN_NOAUDIT | VN_OPEN_COREDUMP |
(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,42 @@
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 @@
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;
@@ -309,7 +351,7 @@
NDREINIT(ndp);
goto restart;
}
- if ((vn_open_flags & VN_OPEN_NAMECACHE) != 0 ||
+ if ((vn_open_flags & VN_OPEN_COREDUMP) != 0 ||
(vn_irflag_read(ndp->ni_dvp) & VIRF_INOTIFY) != 0)
ndp->ni_cnd.cn_flags |= MAKEENTRY;
#ifdef MAC
@@ -375,7 +417,9 @@
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;
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -624,7 +624,7 @@
/* vn_open_flags */
#define VN_OPEN_NOAUDIT 0x00000001
#define VN_OPEN_NOCAPCHECK 0x00000002
-#define VN_OPEN_NAMECACHE 0x00000004
+#define VN_OPEN_COREDUMP 0x00000004
#define VN_OPEN_INVFS 0x00000008
#define VN_OPEN_WANTIOCTLCAPS 0x00000010

File Metadata

Mime Type
text/plain
Expires
Sun, Oct 11, 8:39 AM (9 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40373698
Default Alt Text
D60283.id188882.diff (3 KB)

Event Timeline