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))