aboutsummaryrefslogtreecommitdiffstats
path: root/executor
diff options
context:
space:
mode:
Diffstat (limited to 'executor')
-rw-r--r--executor/common_test.h11
-rw-r--r--executor/executor.cc20
-rw-r--r--executor/executor_bsd.h5
-rw-r--r--executor/executor_darwin.h5
-rw-r--r--executor/executor_linux.h11
-rw-r--r--executor/executor_test.h25
-rw-r--r--executor/nocover.h5
7 files changed, 67 insertions, 15 deletions
diff --git a/executor/common_test.h b/executor/common_test.h
index 971108df8..67585be9a 100644
--- a/executor/common_test.h
+++ b/executor/common_test.h
@@ -153,3 +153,14 @@ static long syz_test_fuzzer1(volatile long a, volatile long b, volatile long c)
}
#endif
+
+#if SYZ_EXECUTOR || __NR_syz_inject_cover
+static long syz_inject_cover(volatile long a, volatile long b, volatile long c)
+#if SYZ_EXECUTOR
+ ; // defined in executor_test.h
+#else
+{
+ return 0;
+}
+#endif
+#endif
diff --git a/executor/executor.cc b/executor/executor.cc
index 88a0963c8..a8cc2259f 100644
--- a/executor/executor.cc
+++ b/executor/executor.cc
@@ -218,8 +218,8 @@ const uint64 binary_format_stroct = 4;
const uint64 no_copyout = -1;
static int running;
-uint32 completed;
-bool is_kernel_64_bit = true;
+static uint32 completed;
+static bool is_kernel_64_bit = true;
static uint8* input_data;
@@ -1278,11 +1278,14 @@ void execute_call(thread_t* th)
static uint32 hash(uint32 a)
{
+ // For test OS we disable hashing for determinism and testability.
+#if !GOOS_test
a = (a ^ 61) ^ (a >> 16);
a = a + (a << 3);
a = a ^ (a >> 4);
a = a * 0x27d4eb2d;
a = a ^ (a >> 15);
+#endif
return a;
}
@@ -1577,21 +1580,12 @@ bool kcov_comparison_t::ignore() const
return true;
if (arg2 >= out_start && arg2 <= out_end)
return true;
-#if defined(GOOS_linux)
// Filter out kernel physical memory addresses.
// These are internal kernel comparisons and should not be interesting.
- // The range covers first 1TB of physical mapping.
- uint64 kmem_start = (uint64)0xffff880000000000ull;
- uint64 kmem_end = (uint64)0xffff890000000000ull;
- bool kptr1 = arg1 >= kmem_start && arg1 <= kmem_end;
- bool kptr2 = arg2 >= kmem_start && arg2 <= kmem_end;
+ bool kptr1 = is_kernel_data(arg1) || arg1 == 0;
+ bool kptr2 = is_kernel_data(arg2) || arg2 == 0;
if (kptr1 && kptr2)
return true;
- if (kptr1 && arg2 == 0)
- return true;
- if (kptr2 && arg1 == 0)
- return true;
-#endif
}
return !coverage_filter(pc);
}
diff --git a/executor/executor_bsd.h b/executor/executor_bsd.h
index 43c2a19a9..1f54e0f41 100644
--- a/executor/executor_bsd.h
+++ b/executor/executor_bsd.h
@@ -179,6 +179,11 @@ static void cover_collect(cover_t* cov)
cov->size = *(uint64*)cov->data;
}
+static bool is_kernel_data(uint64 addr)
+{
+ return false;
+}
+
static bool use_cover_edges(uint64 pc)
{
return true;
diff --git a/executor/executor_darwin.h b/executor/executor_darwin.h
index aeba30a1d..83fe90c45 100644
--- a/executor/executor_darwin.h
+++ b/executor/executor_darwin.h
@@ -122,6 +122,11 @@ static void cover_collect(cover_t* cov)
cov->pc_offset = trace->offset;
}
+static bool is_kernel_data(uint64 addr)
+{
+ return false;
+}
+
static bool use_cover_edges(uint64 pc)
{
return true;
diff --git a/executor/executor_linux.h b/executor/executor_linux.h
index bfd81776f..445a278e2 100644
--- a/executor/executor_linux.h
+++ b/executor/executor_linux.h
@@ -182,6 +182,17 @@ static bool use_cover_edges(uint32 pc)
return true;
}
+static bool is_kernel_data(uint64 addr)
+{
+#if GOARCH_386 || GOARCH_amd64
+ // This range corresponds to the first 1TB of the physical memory mapping,
+ // see Documentation/arch/x86/x86_64/mm.rst.
+ return addr >= 0xffff880000000000ull && addr < 0xffff890000000000ull;
+#else
+ return false;
+#endif
+}
+
static bool use_cover_edges(uint64 pc)
{
#if GOARCH_amd64 || GOARCH_arm64
diff --git a/executor/executor_test.h b/executor/executor_test.h
index dd133e422..f796aed04 100644
--- a/executor/executor_test.h
+++ b/executor/executor_test.h
@@ -54,12 +54,15 @@ static void cover_enable(cover_t* cov, bool collect_comps, bool extra)
static void cover_reset(cover_t* cov)
{
- *(unsigned long*)(cov->data) = 0;
+ *(uint64*)(cov->data) = 0;
}
static void cover_collect(cover_t* cov)
{
- cov->size = *(unsigned long*)(cov->data);
+ if (is_kernel_64_bit)
+ cov->size = *(uint64*)cov->data;
+ else
+ cov->size = *(uint32*)cov->data;
}
static void cover_protect(cover_t* cov)
@@ -87,7 +90,25 @@ static void cover_unprotect(cover_t* cov)
{
}
+static bool is_kernel_data(uint64 addr)
+{
+ return addr >= 0xda1a0000 && addr <= 0xda1a1000;
+}
+
static bool use_cover_edges(uint64 pc)
{
return true;
}
+
+static long syz_inject_cover(volatile long a, volatile long b, volatile long c)
+{
+ cover_t* cov = &current_thread->cov;
+ if (cov->data == nullptr)
+ return ENOENT;
+ is_kernel_64_bit = a;
+ cov->data_offset = is_kernel_64_bit ? sizeof(uint64_t) : sizeof(uint32_t);
+ uint32 size = std::min((uint32)c, cov->mmap_alloc_size);
+ memcpy(cov->data, (void*)b, size);
+ memset(cov->data + size, 0xcd, std::min<uint64>(100, cov->mmap_alloc_size - size));
+ return 0;
+}
diff --git a/executor/nocover.h b/executor/nocover.h
index 0ba7a56cc..ba26dd1d5 100644
--- a/executor/nocover.h
+++ b/executor/nocover.h
@@ -29,6 +29,11 @@ static void cover_unprotect(cover_t* cov)
{
}
+static bool is_kernel_data(uint64 addr)
+{
+ return false;
+}
+
static bool use_cover_edges(uint64 pc)
{
return true;