Enable basic stack canary.
Change-Id: Iee065af935e9276133779a4bd24089be065a0588
diff --git a/build/BUILD.gn b/build/BUILD.gn
index 8d33be6..1adba35 100644
--- a/build/BUILD.gn
+++ b/build/BUILD.gn
@@ -24,6 +24,8 @@
#"-Wextra",
"-Wpedantic",
"-Werror",
+
+ "-fstack-protector-all",
]
cflags_c = [ "-std=c11" ]
diff --git a/build/toolchain/embedded.gni b/build/toolchain/embedded.gni
index 9731763..ddf17d9 100644
--- a/build/toolchain/embedded.gni
+++ b/build/toolchain/embedded.gni
@@ -227,7 +227,7 @@
"\"platform_name\" must be defined for ${target_name}.")
defines = ""
- cflags = "-fno-stack-protector -fno-builtin -ffreestanding -fpic"
+ cflags = "-fno-builtin -ffreestanding -fpic"
ldflags = "--defsym=ORIGIN_ADDRESS=${invoker.origin_address}"
if (defined(invoker.extra_defines)) {
defines += " ${invoker.extra_defines}"
diff --git a/inc/hf/abort.h b/inc/hf/abort.h
new file mode 100644
index 0000000..f5548e0
--- /dev/null
+++ b/inc/hf/abort.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2019 The Hafnium Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdnoreturn.h>
+
+noreturn void abort(void);
diff --git a/src/BUILD.gn b/src/BUILD.gn
index d7c0d92..6bdf1af 100644
--- a/src/BUILD.gn
+++ b/src/BUILD.gn
@@ -46,6 +46,7 @@
# sharing.
source_set("src_testable") {
sources = [
+ "abort.c",
"api.c",
"cpu.c",
"fdt_handler.c",
@@ -100,6 +101,12 @@
]
}
+source_set("panic") {
+ sources = [
+ "panic.c",
+ ]
+}
+
executable("unit_tests") {
testonly = true
sources = [
diff --git a/src/abort.c b/src/abort.c
new file mode 100644
index 0000000..f16d2f7
--- /dev/null
+++ b/src/abort.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2019 The Hafnium Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "hf/abort.h"
+
+/**
+ * Causes execution to halt and prevent progress of the current and less
+ * privileged software components. This should be triggered when a
+ * non-recoverable event is identified which leaves the system in an
+ * inconsistent state.
+ *
+ * TODO: Should this also reset the system?
+ */
+noreturn void abort(void)
+{
+ /* TODO: Block all CPUs. */
+ for (;;) {
+ }
+}
diff --git a/src/arch/aarch64/BUILD.gn b/src/arch/aarch64/BUILD.gn
index e1d9ebe..5733da7 100644
--- a/src/arch/aarch64/BUILD.gn
+++ b/src/arch/aarch64/BUILD.gn
@@ -47,6 +47,7 @@
source_set("std") {
sources = [
+ "stack_protector.c",
"std.c",
]
}
diff --git a/src/arch/aarch64/stack_protector.c b/src/arch/aarch64/stack_protector.c
new file mode 100644
index 0000000..489bb50
--- /dev/null
+++ b/src/arch/aarch64/stack_protector.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2019 The Hafnium Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+#include <stdnoreturn.h>
+
+#include "hf/panic.h"
+
+/**
+ * This is the value that is used as the stack canary. It is written to the top
+ * of the stack when entering a function and compared against the stack when
+ * exiting a function. If there is a mismatch, a failure is triggered.
+ *
+ * As the value must be the same at the beginning and end of the function, this
+ * is a global variable and there are multiple CPUs executing concurrently, this
+ * value cannot change after being initialized.
+ *
+ * TODO: initialize to a random value at boot.
+ */
+uint64_t __attribute__((used)) __stack_chk_guard = 0x72afaf72bad0feed;
+
+/**
+ * Called when the stack canary is invalid. The stack can no longer be trusted
+ * so this function must not return.
+ */
+noreturn void __stack_chk_fail(void)
+{
+ panic("stack corruption");
+}
diff --git a/src/panic.c b/src/panic.c
index 17399dc..9c0a4f6 100644
--- a/src/panic.c
+++ b/src/panic.c
@@ -18,10 +18,11 @@
#include <stdarg.h>
+#include "hf/abort.h"
#include "hf/dlog.h"
/**
- * Blocks the hypervisor.
+ * Logs a reason before calling abort.
*
* TODO: Determine if we want to omit strings on non-debug builds.
*/
@@ -29,8 +30,6 @@
{
va_list args;
- /* TODO: Block all CPUs. */
-
dlog("Panic: ");
va_start(args, fmt);
@@ -39,6 +38,5 @@
dlog("\n");
- for (;;) {
- }
+ abort();
}
diff --git a/test/hftest/BUILD.gn b/test/hftest/BUILD.gn
index 9f1df7c..787a77d 100644
--- a/test/hftest/BUILD.gn
+++ b/test/hftest/BUILD.gn
@@ -44,6 +44,7 @@
deps = [
"//src:dlog",
"//src:memiter",
+ "//src:panic",
"//src/arch/${plat_arch}:entry",
"//src/arch/${plat_arch}:std",
"//src/arch/${plat_arch}/hftest:entry",
@@ -110,6 +111,7 @@
]
deps = [
"//src:memiter",
+ "//src:panic",
"//src/arch/${plat_arch}:std",
]
}
diff --git a/test/hftest/hftest_common.c b/test/hftest/hftest_common.c
index 1a48c74..5a3b348 100644
--- a/test/hftest/hftest_common.c
+++ b/test/hftest/hftest_common.c
@@ -125,7 +125,7 @@
/**
* Logs a failure message and shut down.
*/
-static noreturn void abort(void)
+noreturn void abort(void)
{
HFTEST_LOG("FAIL");
arch_power_off();
diff --git a/test/hftest/hftest_service.c b/test/hftest/hftest_service.c
index 98c237b..743e087 100644
--- a/test/hftest/hftest_service.c
+++ b/test/hftest/hftest_service.c
@@ -66,7 +66,7 @@
return NULL;
}
-static noreturn void abort(void)
+noreturn void abort(void)
{
HFTEST_LOG("Service contained failures.");
for (;;) {