Fuchsia: Turn safeside ret2spec tests into a library
ret2spec is a class of Spectre V2-related speculative execution
information leaks, where the contents of return address stacks are
poisoned. Poisoned return address stacks can be used to cause
sensitive code to (speculatively) execute attacker-controlled
code, which can be used as a building block in infoleak attacks.
Ret2spec attacks can be carried out within a process, across
user/kernel boundaries on a CPU, and across processes.
Safeside is a collection of demos of speculative execution
attacks, including ret2spec; we plan to use its demos to test
Fuchsia's speculative execution mitigations.
Convert Safeside's standalone ret2spec demos into a library,
so that Fuchsia-driven tests can use them. We do not have a
test in-tree of ret2spec_ca (cross-address-space), but will adapt
ret2spec_sa into one.
Bug: 12540 Speculative Execution Mitigations.
Bug: 33667 Spectre mitigations?
Change-Id: I239a8ba1f1b73f6ef58b6baa2b1f54ac6f3c3cb3
diff --git a/BUILD.gn b/BUILD.gn
index 0983c79..56e4046 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -2,32 +2,28 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import("//build/package.gni")
+import("//build/config/compiler.gni")
-executable("ret2spec_sa_bin") {
- output_name = "ret2spec_sa"
-
+target("static_library", "safeside") {
sources = [
+ "demos/ret2spec_callret_disparity.cc",
"demos/ret2spec_sa.cc",
"demos/cache_sidechannel.cc",
"demos/utils.cc",
"demos/instr.cc",
]
-
include_dirs = [
"demos",
]
- deps = [ "//zircon/public/lib/fdio" ]
-}
+ deps = [ "//sdk/lib/fdio" ]
-package("safeside") {
- deps = [ ":ret2spec_sa_bin" ]
+ if (is_fuchsia) {
+ configs += [ "//build/config/fuchsia:static_cpp_standard_library" ]
+ }
- binaries = [
- {
- name = "ret2spec_sa"
- shell = true
- },
- ]
+ # Safeside must be built with compiler optimizations; otherwise intervening
+ # memory accesses or text confounds reliability of the tests.
+ configs -= [ "//build/config:default_optimize" ]
+ configs += [ "//build/config:optimize_debug" ]
}
diff --git a/demos/local_content.h b/demos/local_content.h
index 33aa4c4..ce44511 100644
--- a/demos/local_content.h
+++ b/demos/local_content.h
@@ -21,6 +21,6 @@
// intended to be leaked outside of the C++ execution model using sidechannels.
// Concrete sidechannel is dependent on the concrete vulnerability that we are
// demonstrating.
-const char *public_data = "Hello, world!";
-const char *private_data = "It's a s3kr3t!!!";
+static const char *public_data = "Hello, world!";
+static const char *private_data = "It's a s3kr3t!!!";
#endif // DEMOS_LOCAL_CONTENT_H
diff --git a/demos/ret2spec_callret_disparity.cc b/demos/ret2spec_callret_disparity.cc
index 08589ef..2780a17 100644
--- a/demos/ret2spec_callret_disparity.cc
+++ b/demos/ret2spec_callret_disparity.cc
@@ -106,7 +106,7 @@
}
}
-int main() {
+int ret2spec_callret_disparity_main() {
std::cout << "Leaking the string: ";
std::cout.flush();
for (size_t i = 0; i < strlen(private_data); ++i) {
diff --git a/demos/ret2spec_sa.cc b/demos/ret2spec_sa.cc
index c6c8d2a..06fb855 100644
--- a/demos/ret2spec_sa.cc
+++ b/demos/ret2spec_sa.cc
@@ -48,8 +48,8 @@
// calls. Since we flush whole stack frames from the cache, it is important not
// to store on stack any data that might be affected by being flushed from
// cache.
-size_t current_offset;
-const std::array<BigByte, 256> *oracle_ptr;
+static size_t current_offset;
+static const std::array<BigByte, 256> *oracle_ptr;
// Return value of ReturnsFalse that never changes. Avoiding compiler
// optimizations with it.
@@ -122,7 +122,7 @@
}
}
-int main() {
+int ret2spec_sa_main() {
std::cout << "Leaking the string: ";
std::cout.flush();
for (size_t i = 0; i < strlen(private_data); ++i) {
@@ -131,4 +131,5 @@
std::cout.flush();
}
std::cout << "\nDone!\n";
+ return 0;
}