From c3a6603be2cc031a8f2fa69e757e04a4ce647080 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Wed, 14 Aug 2024 17:46:34 +0200 Subject: executor: protect kcov/output regions with pkeys Protect KCOV regions with pkeys if they are available. Protect output region with pkeys in snapshot mode. Snapshot mode is especially sensitive to output buffer corruption since its location is not randomized. --- executor/snapshot.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'executor/snapshot.h') diff --git a/executor/snapshot.h b/executor/snapshot.h index 5479a162f..ce3e355b0 100644 --- a/executor/snapshot.h +++ b/executor/snapshot.h @@ -87,6 +87,11 @@ static void FindIvshmemDevices() input, static_cast(rpc::Const::MaxInputSize)); debug("mapped shmem output at at %p/%llu\n", output, static_cast(rpc::Const::MaxOutputSize)); +#if GOOS_linux + if (pkeys_enabled && pkey_mprotect(output, static_cast(rpc::Const::MaxOutputSize), + PROT_READ | PROT_WRITE, RESERVED_PKEY)) + exitf("failed to pkey_mprotect output buffer"); +#endif } close(res2); } @@ -175,6 +180,8 @@ static void TouchMemory(void* ptr, size_t size) #if SYZ_EXECUTOR_USES_FORK_SERVER static void SnapshotPrepareParent() { + // This allows access to the output region. + CoverAccessScope scope(nullptr); TouchMemory((char*)output_data + output_size - kOutputPopulate, kOutputPopulate); // Notify SnapshotStart that we finished prefaulting memory in the parent. output_data->completed = 1; @@ -188,6 +195,7 @@ static void SnapshotPrepareParent() static void SnapshotStart() { debug("SnapshotStart\n"); + CoverAccessScope scope(nullptr); // Prefault as much memory as we can before the snapshot is taken. // Also pre-create some threads and let them block. // This is intended to make execution after each snapshot restore faster, @@ -241,6 +249,7 @@ static void SnapshotStart() NORETURN static void SnapshotDone(bool failed) { debug("SnapshotDone\n"); + CoverAccessScope scope(nullptr); uint32 num_calls = output_data->num_calls.load(std::memory_order_relaxed); auto data = finish_output(output_data, 0, 0, num_calls, 0, 0, failed ? kFailStatus : 0, nullptr); ivs.hdr->output_offset = data.data() - reinterpret_cast(ivs.hdr); -- cgit mrf-deployment