},
{
"id": "SAF-13-safe",
+ "analyser": {
+ "eclair": "MC3A2.R8.4"
+ },
+ "name": "Rule 8.4: compiler-called function",
+ "text": "A function, all invocations of which are compiler generated, does not need to have a visible declaration prior to its definition."
+ },
+ {
+ "id": "SAF-14-safe",
"analyser": {},
"name": "Sentinel",
"text": "Next ID to be used"
CFLAGS_UBSAN :=
endif
+ifeq ($(CONFIG_STACK_PROTECTOR),y)
+CFLAGS += -fstack-protector
+else
CFLAGS += -fno-stack-protector
+endif
ifeq ($(CONFIG_LTO),y)
CFLAGS += -flto
config HAS_SCHED_GRANULARITY
bool
+config HAS_STACK_PROTECTOR
+ bool
+
config HAS_UBSAN
bool
endmenu
+menu "Other hardening"
+
+config STACK_PROTECTOR
+ bool "Stack protector"
+ depends on HAS_STACK_PROTECTOR
+ help
+ Enable the Stack Protector compiler hardening option. This inserts a
+ canary value in the stack frame of functions, and performs an integrity
+ check on function exit.
+
+endmenu
+
config DIT_DEFAULT
bool "Data Independent Timing default"
depends on HAS_DIT
obj-y += softirq.o
obj-y += smp.o
obj-y += spinlock.o
+obj-$(CONFIG_STACK_PROTECTOR) += stack-protector.o
obj-y += stop_machine.o
obj-y += symbols.o
obj-y += tasklet.o
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0-only */
+#include <xen/init.h>
+#include <xen/lib.h>
+#include <xen/random.h>
+#include <xen/time.h>
+
+/*
+ * Initial value is chosen by a fair dice roll.
+ * It will be updated during boot process.
+ */
+#if BITS_PER_LONG == 32
+unsigned long __ro_after_init __stack_chk_guard = 0xdd2cc927UL;
+#else
+unsigned long __ro_after_init __stack_chk_guard = 0x2d853605a4d9a09cUL;
+#endif
+
+/* SAF-13-safe compiler-called function */
+void noreturn __stack_chk_fail(void)
+{
+ dump_execution_state();
+ panic("Stack Protector integrity violation identified\n");
+}
--- /dev/null
+#ifndef __XEN_STACK_PROTECTOR_H__
+#define __XEN_STACK_PROTECTOR_H__
+
+extern unsigned long __stack_chk_guard;
+
+/*
+ * This function should be called from a C function that escapes stack
+ * canary tracking (by calling reset_stack_and_jump() for example).
+ */
+static always_inline void boot_stack_chk_guard_setup(void)
+{
+#ifdef CONFIG_STACK_PROTECTOR
+
+ /*
+ * Linear congruent generator (X_n+1 = X_n * a + c).
+ *
+ * Constant is taken from "Tables Of Linear Congruential
+ * Generators Of Different Sizes And Good Lattice Structure" by
+ * Pierre L’Ecuyer.
+ */
+#if BITS_PER_LONG == 32
+ const unsigned long a = 2891336453UL;
+#else
+ const unsigned long a = 2862933555777941757UL;
+#endif
+ const unsigned long c = 1;
+
+ unsigned long cycles = get_cycles();
+
+ /* Use the initial value if we can't generate random one */
+ if ( !cycles )
+ return;
+
+ __stack_chk_guard = cycles * a + c;
+
+#endif /* CONFIG_STACK_PROTECTOR */
+}
+
+#endif /* __XEN_STACK_PROTECTOR_H__ */