Do not allow send/receive of kcov descriptors as the file descriptor can
authoranton <anton@openbsd.org>
Wed, 29 Dec 2021 07:15:13 +0000 (07:15 +0000)
committeranton <anton@openbsd.org>
Wed, 29 Dec 2021 07:15:13 +0000 (07:15 +0000)
be kept alive longer than expected causing syzkaller to no longer being
able to enable remote coverage.

ok visa@

Reported-by: syzbot+ab2016d729cda7b0d003@syzkaller.appspotmail.com
sys/dev/kcov.c
sys/kern/uipc_usrreq.c
sys/sys/kcov.h

index 5db7e76..31231b2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kcov.c,v 1.43 2021/12/28 17:50:10 anton Exp $ */
+/*     $OpenBSD: kcov.c,v 1.44 2021/12/29 07:15:13 anton Exp $ */
 
 /*
  * Copyright (c) 2018 Anton Lindqvist <anton@openbsd.org>
 #include <sys/stdint.h>
 #include <sys/queue.h>
 
+/* kcov_vnode() */
+#include <sys/conf.h>
+#include <sys/vnode.h>
+#include <sys/specdev.h>
+
 #include <uvm/uvm_extern.h>
 
 #define KCOV_BUF_MEMB_SIZE     sizeof(uintptr_t)
@@ -449,6 +454,16 @@ kcov_exit(struct proc *p)
        mtx_leave(&kcov_mtx);
 }
 
+/*
+ * Returns non-zero if the given vnode refers to a kcov device.
+ */
+int
+kcov_vnode(struct vnode *vp)
+{
+       return (vp->v_type == VCHR &&
+           cdevsw[major(vp->v_rdev)].d_open == kcovopen);
+}
+
 struct kcov_dev *
 kd_lookup(int unit)
 {
index 160ff15..dbb1845 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uipc_usrreq.c,v 1.160 2021/12/26 23:41:41 mvs Exp $   */
+/*     $OpenBSD: uipc_usrreq.c,v 1.161 2021/12/29 07:15:13 anton Exp $ */
 /*     $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $        */
 
 /*
 #include <sys/sysctl.h>
 #include <sys/lock.h>
 
+#include "kcov.h"
+#if NKCOV > 0
+#include <sys/kcov.h>
+#endif
+
 /*
  * Locks used to protect global data and struct members:
  *      I       immutable after creation
@@ -1085,6 +1090,13 @@ morespace:
                        error = EINVAL;
                        goto fail;
                }
+#if NKCOV > 0
+               /* kcov descriptors cannot be copied */
+               if (fp->f_type == DTYPE_VNODE && kcov_vnode(fp->f_data)) {
+                       error = EINVAL;
+                       goto fail;
+               }
+#endif
                rp->fp = fp;
                rp->flags = fdp->fd_ofileflags[fd] & UF_PLEDGED;
                rp--;
index a499953..2c357f8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kcov.h,v 1.7 2020/09/26 11:59:59 anton Exp $  */
+/*     $OpenBSD: kcov.h,v 1.8 2021/12/29 07:15:13 anton Exp $  */
 
 /*
  * Copyright (c) 2018 Anton Lindqvist <anton@openbsd.org>
@@ -42,6 +42,7 @@ struct kio_remote_attach {
 struct proc;
 
 void kcov_exit(struct proc *);
+int kcov_vnode(struct vnode *);
 void kcov_remote_register(int, void *);
 void kcov_remote_unregister(int, void *);
 void kcov_remote_enter(int, void *);