Hi,
When a kcov fd is in an enabled state, disallow mmap() calls using the
same fd. Sometimes, syzkaller manages to create a device node using
mknod() with major=22 and minor=X where X maps to an already open kcov
fd in the current process; it then mmap() the kcov coverage buffer which
is used as input to other syscalls causing the coverage buffer to be
corrupted:

  kd = open("/dev/kcov")
  # kd = 3
  ioctl(kd, KIOSETBUFSIZE, ...)
  ioctl(kd, KIOENABLE, ...)
  mknod("./nod", major=22, minor=3)
  fd = open("./nod")
  # fd = dup(kd)
  p = mmap(fd, ...)
  lstat("./nod", p)
  # lstat() will corrupt the coverage buffer

A similiar check is also presents in Linux.

Comments? OK?

Index: dev/kcov.c
===================================================================
RCS file: /cvs/src/sys/dev/kcov.c,v
retrieving revision 1.9
diff -u -p -r1.9 kcov.c
--- dev/kcov.c  3 Jan 2019 08:56:53 -0000       1.9
+++ dev/kcov.c  14 Jan 2019 16:52:12 -0000
@@ -209,7 +209,7 @@ kcovmmap(dev_t dev, off_t offset, int pr
        vaddr_t va;
 
        kd = kd_lookup(minor(dev));
-       if (kd == NULL)
+       if (kd == NULL || kd->kd_state != KCOV_STATE_READY)
                return (paddr_t)(-1);
 
        if (offset < 0 || offset >= kd->kd_nmemb * sizeof(uintptr_t))

Reply via email to