diff options
| author | kamil <kamil@NetBSD.org> | 2019-03-10 22:34:14 +0000 |
|---|---|---|
| committer | kamil <kamil@NetBSD.org> | 2019-03-10 22:34:14 +0000 |
| commit | 82af7138a1c8a1a36bbe959c55b1f9092ba38ad0 (patch) | |
| tree | 974e11002598b37e405374d63258916c2ecc23cf /tests/modules | |
| parent | fc3ee6fd246799bdc94af24c4c2e5119b2b600b4 (diff) | |
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.
Diffstat (limited to 'tests/modules')
| -rw-r--r-- | tests/modules/t_kcov.c | 80 |
1 files changed, 69 insertions, 11 deletions
diff --git a/tests/modules/t_kcov.c b/tests/modules/t_kcov.c index e40ce34dc1d..ca4f1ee88d2 100644 --- a/tests/modules/t_kcov.c +++ b/tests/modules/t_kcov.c @@ -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_close, tc) } 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); |
