Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102639154
D33079.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D33079.diff
View Options
diff --git a/sys/arm64/arm64/exception.S b/sys/arm64/arm64/exception.S
--- a/sys/arm64/arm64/exception.S
+++ b/sys/arm64/arm64/exception.S
@@ -66,6 +66,13 @@
mrs x18, tpidr_el1
add x29, sp, #(TF_SIZE)
.if \el == 0
+#if defined(PERTHREAD_SSP)
+ /* Load the SSP canary to sp_el0 */
+ ldr x1, [x18, #(PC_CURTHREAD)]
+ add x1, x1, #(TD_MD_CANARY)
+ msr sp_el0, x1
+#endif
+
/* Apply the SSBD (CVE-2018-3639) workaround if needed */
ldr x1, [x18, #PC_SSBD]
cbz x1, 1f
diff --git a/sys/arm64/arm64/genassym.c b/sys/arm64/arm64/genassym.c
--- a/sys/arm64/arm64/genassym.c
+++ b/sys/arm64/arm64/genassym.c
@@ -73,6 +73,7 @@
ASSYM(TD_FLAGS, offsetof(struct thread, td_flags));
ASSYM(TD_FRAME, offsetof(struct thread, td_frame));
ASSYM(TD_LOCK, offsetof(struct thread, td_lock));
+ASSYM(TD_MD_CANARY, offsetof(struct thread, td_md.md_canary));
ASSYM(TF_SIZE, sizeof(struct trapframe));
ASSYM(TF_SP, offsetof(struct trapframe, tf_sp));
diff --git a/sys/arm64/arm64/locore.S b/sys/arm64/arm64/locore.S
--- a/sys/arm64/arm64/locore.S
+++ b/sys/arm64/arm64/locore.S
@@ -116,6 +116,13 @@
cmp x15, x14
b.lo 1b
+#if defined(PERTHREAD_SSP)
+ /* Set sp_el0 to the boot canary for early per-thread SSP to work */
+ adrp x15, boot_canary
+ add x15, x15, :lo12:boot_canary
+ msr sp_el0, x15
+#endif
+
/* Backup the module pointer */
mov x1, x0
@@ -200,6 +207,13 @@
ldr x4, [x4]
mov sp, x4
+#if defined(PERTHREAD_SSP)
+ /* Set sp_el0 to the boot canary for early per-thread SSP to work */
+ adrp x15, boot_canary
+ add x15, x15, :lo12:boot_canary
+ msr sp_el0, x15
+#endif
+
/* Load the kernel ttbr0 pagetable */
msr ttbr0_el1, x27
isb
diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c
--- a/sys/arm64/arm64/machdep.c
+++ b/sys/arm64/arm64/machdep.c
@@ -109,6 +109,14 @@
*/
struct pcpu pcpu0;
+#if defined(PERTHREAD_SSP)
+/*
+ * The boot SSP canary. Will be replaced with a per-thread canary when
+ * scheduling has started.
+ */
+uintptr_t boot_canary = 0x49a2d892bc05a0b1ul;
+#endif
+
static struct trapframe proc0_tf;
int early_boot = 1;
@@ -136,6 +144,16 @@
int (*apei_nmi)(void);
+#if defined(PERTHREAD_SSP_WARNING)
+static void
+print_ssp_warning(void *data __unused)
+{
+ printf("WARNING: Per-thread SSP is enabled but the compiler is too old to support it\n");
+}
+SYSINIT(ssp_warn, SI_SUB_COPYRIGHT, SI_ORDER_ANY, print_ssp_warning, NULL);
+SYSINIT(ssp_warn2, SI_SUB_LAST, SI_ORDER_ANY, print_ssp_warning, NULL);
+#endif
+
static void
pan_setup(void)
{
@@ -347,6 +365,9 @@
proc_linkup0(&proc0, &thread0);
thread0.td_kstack = kstack;
thread0.td_kstack_pages = KSTACK_PAGES;
+#if defined(PERTHREAD_SSP)
+ thread0.td_md.md_canary = boot_canary;
+#endif
thread0.td_pcb = (struct pcb *)(thread0.td_kstack +
thread0.td_kstack_pages * PAGE_SIZE) - 1;
thread0.td_pcb->pcb_fpflags = 0;
@@ -781,6 +802,7 @@
"mov x18, %0 \n"
"msr tpidr_el1, %0" :: "r"(pcpup));
+ /* locore.S sets sp_el0 to &thread0 so no need to set it here. */
PCPU_SET(curthread, &thread0);
PCPU_SET(midr, get_midr());
diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -6619,6 +6619,10 @@
/* Store the new curthread */
PCPU_SET(curthread, new);
+#if defined(PERTHREAD_SSP)
+ /* Set the new threads SSP canary */
+ __asm("msr sp_el0, %0" :: "r"(&new->td_md.md_canary));
+#endif
/* And the new pcb */
pcb = new->td_pcb;
diff --git a/sys/arm64/arm64/vm_machdep.c b/sys/arm64/arm64/vm_machdep.c
--- a/sys/arm64/arm64/vm_machdep.c
+++ b/sys/arm64/arm64/vm_machdep.c
@@ -113,6 +113,11 @@
/* Setup to release spin count in fork_exit(). */
td2->td_md.md_spinlock_count = 1;
td2->td_md.md_saved_daif = PSR_DAIF_DEFAULT;
+
+#if defined(PERTHREAD_SSP)
+ /* Set the new canary */
+ arc4random_buf(&td2->td_md.md_canary, sizeof(td2->td_md.md_canary));
+#endif
}
void
@@ -187,6 +192,11 @@
/* Setup to release spin count in fork_exit(). */
td->td_md.md_spinlock_count = 1;
td->td_md.md_saved_daif = PSR_DAIF_DEFAULT;
+
+#if defined(PERTHREAD_SSP)
+ /* Set the new canary */
+ arc4random_buf(&td->td_md.md_canary, sizeof(td->td_md.md_canary));
+#endif
}
/*
diff --git a/sys/arm64/conf/std.arm64 b/sys/arm64/conf/std.arm64
--- a/sys/arm64/conf/std.arm64
+++ b/sys/arm64/conf/std.arm64
@@ -67,6 +67,7 @@
options RCTL # Resource limits
options INTRNG
options LINUX_BOOT_ABI # Boot using booti command from U-Boot
+options PERTHREAD_SSP # Per-thread SSP canary
# Debugging support. Always need this:
options KDB # Enable kernel debugger support.
diff --git a/sys/arm64/include/proc.h b/sys/arm64/include/proc.h
--- a/sys/arm64/include/proc.h
+++ b/sys/arm64/include/proc.h
@@ -37,6 +37,7 @@
struct mdthread {
int md_spinlock_count; /* (k) */
register_t md_saved_daif; /* (k) */
+ uintptr_t md_canary;
};
struct mdproc {
diff --git a/sys/conf/Makefile.arm64 b/sys/conf/Makefile.arm64
--- a/sys/conf/Makefile.arm64
+++ b/sys/conf/Makefile.arm64
@@ -30,6 +30,20 @@
LINUX_DTS_VERSION!= awk '/freebsd,dts-version/ { sub(/;$$/,"", $$NF); print $$NF }' $S/dts/freebsd-compatible.dts
CFLAGS += -DLINUX_DTS_VERSION=\"${LINUX_DTS_VERSION}\"
+PERTHREAD_SSP_ENABLED!= grep PERTHREAD_SSP opt_global.h || true ; echo
+.if !empty(PERTHREAD_SSP_ENABLED)
+. if ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} >= 130000
+ARM64_SSP_CFLAGS = -mstack-protector-guard=sysreg
+ARM64_SSP_CFLAGS += -mstack-protector-guard-reg=sp_el0
+ARM64_SSP_CFLAGS += -mstack-protector-guard-offset=0
+. else
+ARM64_SSP_CFLAGS += -DPERTHREAD_SSP_WARNING
+. warning "Compiler is too old to support PERTHREAD_SSP"
+. endif
+CFLAGS += ${ARM64_SSP_CFLAGS}
+ARCH_FLAGS += ${ARM64_SSP_CFLAGS}
+.endif
+
# Use a custom SYSTEM_LD command to generate the elf kernel, so we can
# set the text segment start address, and also strip the "arm mapping
# symbols" which have names like $a.0 and $d.2; see the document
diff --git a/sys/conf/options.arm64 b/sys/conf/options.arm64
--- a/sys/conf/options.arm64
+++ b/sys/conf/options.arm64
@@ -8,6 +8,10 @@
LINUX_BOOT_ABI opt_global.h
LSE_ATOMICS opt_global.h
+# Per-thread stack smashing protection support
+# Needs clang >= 13
+PERTHREAD_SSP opt_global.h
+
# Binary compatibility
COMPAT_FREEBSD32 opt_global.h
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 16, 4:47 AM (21 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14653334
Default Alt Text
D33079.diff (6 KB)
Attached To
Mode
D33079: Per-thread stack canary on arm64
Attached
Detach File
Event Timeline
Log In to Comment