aboutsummaryrefslogtreecommitdiffstats
path: root/executor/executor_bsd.h
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2025-02-18 15:12:31 +0000
committerAleksandr Nogikh <nogikh@google.com>2025-02-21 17:21:17 +0000
commitd34966d146f584d390b49f213d1fccd59548dc6d (patch)
treed400f6becc0b35195e23fccc7d87077b3eaaa4f9 /executor/executor_bsd.h
parent0808a665bc75ab0845906bfeca0d12fb520ae6eb (diff)
executor: fix cover_protect() on FreeBSD
During machine checks, syzkaller will execute calls with coverage disabled, in which case per-thread coverage structures are zeroed out. write_output() will temporarily map the coverage data as writeable via CoverAccessScope, whether or not cover is enabled. In effect, write_output() may trigger a call mprotect(0, kCoverSize, PROT_RW). On FreeBSD, mprotect() silently ignores unmapped regions, so this does not result in an error. In fact, kCoverSize is now large enough that this ends up removing the eXecute bit from part of syz-executor's text region. Make CoverAccessScope a no-op if coverage is not enabled. Modify BSD cover_protect() and cover_unprotect() to fail if invoked when coverage is disabled.
Diffstat (limited to 'executor/executor_bsd.h')
-rw-r--r--executor/executor_bsd.h4
1 files changed, 4 insertions, 0 deletions
diff --git a/executor/executor_bsd.h b/executor/executor_bsd.h
index 0eb76c588..b7cbdd4f5 100644
--- a/executor/executor_bsd.h
+++ b/executor/executor_bsd.h
@@ -120,6 +120,8 @@ static void cover_mmap(cover_t* cov)
static void cover_protect(cover_t* cov)
{
+ if (cov->data == NULL)
+ fail("cover_protect invoked on an unmapped cover_t object");
#if GOOS_freebsd
size_t mmap_alloc_size = kCoverSize * KCOV_ENTRY_SIZE;
long page_size = sysconf(_SC_PAGESIZE);
@@ -139,6 +141,8 @@ static void cover_protect(cover_t* cov)
static void cover_unprotect(cover_t* cov)
{
+ if (cov->data == NULL)
+ fail("cover_unprotect invoked on an unmapped cover_t object");
#if GOOS_freebsd
size_t mmap_alloc_size = kCoverSize * KCOV_ENTRY_SIZE;
mprotect(cov->data, mmap_alloc_size, PROT_READ | PROT_WRITE);