Module Name: src
Committed By: kamil
Date: Sun Mar 10 22:34:14 UTC 2019
Modified Files:
src/sys/kern: subr_kcov.c
src/tests/modules: t_kcov.c
Log Message:
Introduce enhancements to the kcov(4) code
Add new tests verifying dup2(2) scenarios:
- kcov_dup2
- kcov_basic_dup2_pc
- kcov_basic_dup2_cmp
The dup2(2) trick is used by syzkaller and assert that it works.
All new tests pass.
While there add minor non-functional cleanup changes.
To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/sys/kern/subr_kcov.c
cvs rdiff -u -r1.7 -r1.8 src/tests/modules/t_kcov.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/kern/subr_kcov.c
diff -u src/sys/kern/subr_kcov.c:1.5 src/sys/kern/subr_kcov.c:1.6
--- src/sys/kern/subr_kcov.c:1.5 Sun Mar 10 17:51:00 2019
+++ src/sys/kern/subr_kcov.c Sun Mar 10 22:34:14 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_kcov.c,v 1.5 2019/03/10 17:51:00 kamil Exp $ */
+/* $NetBSD: subr_kcov.c,v 1.6 2019/03/10 22:34:14 kamil Exp $ */
/*
* Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -417,7 +417,7 @@ trace_cmp(uint64_t type, uint64_t arg1,
}
if (kd->mode != KCOV_MODE_TRACE_CMP) {
- /* PC tracing mode not enabled */
+ /* CMP tracing mode not enabled */
return;
}
Index: src/tests/modules/t_kcov.c
diff -u src/tests/modules/t_kcov.c:1.7 src/tests/modules/t_kcov.c:1.8
--- src/tests/modules/t_kcov.c:1.7 Sun Mar 10 17:51:00 2019
+++ src/tests/modules/t_kcov.c Sun Mar 10 22:34:14 2019
@@ -57,6 +57,34 @@ open_kcov(void)
return fd;
}
+static int
+pick_unassigned_fd(int greater_than_fd)
+{
+ int fd2;
+
+ fd2 = greater_than_fd;
+ do {
+ ++fd2;
+ } while (fcntl(fd2, F_GETFL) != -1 || errno != EBADF);
+
+ return fd2;
+}
+
+ATF_TC_WITHOUT_HEAD(kcov_dup2);
+ATF_TC_BODY(kcov_dup2, tc)
+{
+ int fd1, fd2;
+ fd1 = open_kcov();
+
+ fd2 = pick_unassigned_fd(fd1);
+
+ /* Test the dup2(2) trick used by syzkaller */
+ ATF_REQUIRE_EQ(dup2(fd1, fd2), fd2);
+
+ close(fd1);
+ close(fd2);
+}
+
ATF_TC_WITHOUT_HEAD(kcov_multiopen);
ATF_TC_BODY(kcov_multiopen, tc)
{
@@ -216,11 +244,7 @@ ATF_TC_BODY(kcov_enable, tc)
ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == 0);
ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == -1);
- /* Re-enabling should also work */
- ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0);
- ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == 0);
-
- /* Re-enablibling and changing mode should also work */
+ /* Re-enabling and changing mode should also work */
mode = KCOV_MODE_NONE;
ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0);
ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == 0);
@@ -262,14 +286,22 @@ ATF_TC_BODY(kcov_enable_no_disable_no_cl
}
static void *
-common_head(int *fdp)
+common_head_raw(bool fd_dup, int *fdp)
{
void *data;
- int fd;
+ int fd, fd2;
uint64_t size = PAGE_SIZE / KCOV_ENTRY_SIZE;
fd = open_kcov();
+ /* Test the dup2(2) trick used by syzkaller */
+ if (fd_dup) {
+ fd2 = pick_unassigned_fd(fd);
+ ATF_REQUIRE_EQ(dup2(fd, fd2), fd2);
+ close(fd);
+ fd = fd2;
+ }
+
ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) == 0,
"Unable to set the kcov buffer size");
@@ -280,6 +312,13 @@ common_head(int *fdp)
return data;
}
+static void *
+common_head(int *fdp)
+{
+
+ return common_head_raw(false, fdp);
+}
+
static void
common_tail(int fd, kcov_int_t *data)
{
@@ -291,12 +330,12 @@ common_tail(int fd, kcov_int_t *data)
}
static void
-kcov_basic(int mode)
+kcov_basic(bool fd_dup, int mode)
{
kcov_int_t *buf;
int fd;
- buf = common_head(&fd);
+ buf = common_head_raw(fd_dup, &fd);
ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0,
"Unable to enable kcov ");
@@ -315,7 +354,7 @@ ATF_TC_WITHOUT_HEAD(kcov_basic_pc);
ATF_TC_BODY(kcov_basic_pc, tc)
{
- kcov_basic(KCOV_MODE_TRACE_PC);
+ kcov_basic(false, KCOV_MODE_TRACE_PC);
}
ATF_TC_WITHOUT_HEAD(kcov_basic_cmp);
@@ -324,7 +363,23 @@ ATF_TC_BODY(kcov_basic_cmp, tc)
atf_tc_skip("XXX: GCC8 needed");
- kcov_basic(KCOV_MODE_TRACE_CMP);
+ kcov_basic(false, KCOV_MODE_TRACE_CMP);
+}
+
+ATF_TC_WITHOUT_HEAD(kcov_basic_dup2_pc);
+ATF_TC_BODY(kcov_basic_dup2_pc, tc)
+{
+
+ kcov_basic(true, KCOV_MODE_TRACE_PC);
+}
+
+ATF_TC_WITHOUT_HEAD(kcov_basic_dup2_cmp);
+ATF_TC_BODY(kcov_basic_dup2_cmp, tc)
+{
+
+ atf_tc_skip("XXX: GCC8 needed");
+
+ kcov_basic(true, KCOV_MODE_TRACE_CMP);
}
ATF_TC_WITHOUT_HEAD(kcov_multienable_on_the_same_thread);
@@ -486,6 +541,7 @@ KCOV_MULTIPLE_THREADS(32)
ATF_TP_ADD_TCS(tp)
{
+ ATF_TP_ADD_TC(tp, kcov_dup2);
ATF_TP_ADD_TC(tp, kcov_multiopen);
ATF_TP_ADD_TC(tp, kcov_open_close_open);
ATF_TP_ADD_TC(tp, kcov_bufsize);
@@ -498,6 +554,8 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, kcov_mmap_enable_thread_close);
ATF_TP_ADD_TC(tp, kcov_basic_pc);
ATF_TP_ADD_TC(tp, kcov_basic_cmp);
+ ATF_TP_ADD_TC(tp, kcov_basic_dup2_pc);
+ ATF_TP_ADD_TC(tp, kcov_basic_dup2_cmp);
ATF_TP_ADD_TC(tp, kcov_multienable_on_the_same_thread);
ATF_TP_ADD_TC(tp, kcov_buffer_access_from_custom_thread);
ATF_TP_ADD_TC(tp, kcov_thread);