Grab the KERNEL_LOCK() in MP-unsafe fo_close routines. This prevents
authorvisa <visa@openbsd.org>
Wed, 15 Aug 2018 13:19:06 +0000 (13:19 +0000)
committervisa <visa@openbsd.org>
Wed, 15 Aug 2018 13:19:06 +0000 (13:19 +0000)
a scenario where MP-unsafe code gets run without the kernel lock
as a consequence of an unlocked system call.

OK mpi@, kettenis@

sys/dev/pci/drm/drm_linux.c
sys/kern/kern_event.c
sys/kern/sys_pipe.c
sys/kern/vfs_vnops.c

index a342ebc..667e64a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: drm_linux.c,v 1.27 2018/08/12 19:05:37 kettenis Exp $ */
+/*     $OpenBSD: drm_linux.c,v 1.28 2018/08/15 13:19:06 visa Exp $     */
 /*
  * Copyright (c) 2013 Jonathan Gray <jsg@openbsd.org>
  * Copyright (c) 2015, 2016 Mark Kettenis <kettenis@openbsd.org>
@@ -855,7 +855,9 @@ dmabuf_close(struct file *fp, struct proc *p)
        struct dma_buf *dmabuf = fp->f_data;
 
        fp->f_data = NULL;
+       KERNEL_LOCK();
        dmabuf->ops->release(dmabuf);
+       KERNEL_UNLOCK();
        free(dmabuf, M_DRM, sizeof(struct dma_buf));
        return (0);
 }
index c141f2a..4556569 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_event.c,v 1.96 2018/08/09 15:02:45 visa Exp $    */
+/*     $OpenBSD: kern_event.c,v 1.97 2018/08/15 13:19:06 visa Exp $    */
 
 /*-
  * Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
@@ -905,6 +905,8 @@ kqueue_close(struct file *fp, struct proc *p)
        struct kqueue *kq = fp->f_data;
        int i;
 
+       KERNEL_LOCK();
+
        for (i = 0; i < kq->kq_knlistsize; i++)
                knote_remove(p, &kq->kq_knlist[i]);
        if (kq->kq_knhashmask != 0) {
@@ -917,6 +919,8 @@ kqueue_close(struct file *fp, struct proc *p)
        kqueue_wakeup(kq);
        KQRELE(kq);
 
+       KERNEL_UNLOCK();
+
        return (0);
 }
 
index d9c68a3..7c83786 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sys_pipe.c,v 1.83 2018/08/13 14:35:29 mpi Exp $       */
+/*     $OpenBSD: sys_pipe.c,v 1.84 2018/08/15 13:19:06 visa Exp $      */
 
 /*
  * Copyright (c) 1996 John S. Dyson
@@ -757,7 +757,9 @@ pipe_close(struct file *fp, struct proc *p)
 
        fp->f_ops = NULL;
        fp->f_data = NULL;
+       KERNEL_LOCK();
        pipeclose(cpipe);
+       KERNEL_UNLOCK();
        return (0);
 }
 
index c20982e..bc7d9ec 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vfs_vnops.c,v 1.95 2018/07/03 20:40:25 kettenis Exp $ */
+/*     $OpenBSD: vfs_vnops.c,v 1.96 2018/08/15 13:19:06 visa Exp $     */
 /*     $NetBSD: vfs_vnops.c,v 1.20 1996/02/04 02:18:41 christos Exp $  */
 
 /*
@@ -545,7 +545,9 @@ vn_closefile(struct file *fp, struct proc *p)
 {
        struct vnode *vp = fp->f_data;
        struct flock lf;
+       int error;
 
+       KERNEL_LOCK();
        if ((fp->f_iflags & FIF_HASLOCK)) {
                lf.l_whence = SEEK_SET;
                lf.l_start = 0;
@@ -553,8 +555,9 @@ vn_closefile(struct file *fp, struct proc *p)
                lf.l_type = F_UNLCK;
                (void) VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK);
        }
-
-       return (vn_close(vp, fp->f_flag, fp->f_cred, p));
+       error = vn_close(vp, fp->f_flag, fp->f_cred, p);
+       KERNEL_UNLOCK();
+       return (error);
 }
 
 int