diff --git a/arch/x86/extables.c b/arch/x86/extables.c index 5f09d479..69d4c61d 100644 --- a/arch/x86/extables.c +++ b/arch/x86/extables.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 Amazon.com, Inc. or its affiliates. + * Copyright (c) 2021 Open Source Security, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,5 +24,12 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -void init_extables(void) { /* no-op */ +#include + +void init_extables(void) { + for (extable_entry_t *cur = __start_extables; cur < __stop_extables; ++cur) { + if (!cur->fixup && !cur->cb) + panic("extable entry #%d for addr 0x%lx lacks fixup and callback!\n", + cur - __start_extables, cur->fault_addr); + } } diff --git a/arch/x86/link.ld b/arch/x86/link.ld index c61663a0..7860e79d 100644 --- a/arch/x86/link.ld +++ b/arch/x86/link.ld @@ -176,6 +176,7 @@ SECTIONS { __start_extables = .; *(.extables) + __stop_extables = .; . = ALIGN(4K); __end_extables = .; } :kernel diff --git a/arch/x86/traps.c b/arch/x86/traps.c index f9a60c3c..5791a6c0 100644 --- a/arch/x86/traps.c +++ b/arch/x86/traps.c @@ -289,29 +289,27 @@ void print_callstack(const void *sp, const void *ip) { printk("\n"); } -static inline void use_extables(struct cpu_regs *regs) { - for (extable_entry_t *cur = __start_extables; cur < __end_extables; ++cur) { - if (regs->_ASM_IP == cur->fault_addr) { - if (cur->fixup) { - regs->_ASM_IP = cur->fixup; - } - if (cur->cb) { - cur->cb(regs); - } - if (cur->fixup || cur->cb) { - return; - } - else { - panic("fixup or cb must be set in the extable_entry\n"); - } - } +static bool extables_fixup(struct cpu_regs *regs) { + for (extable_entry_t *cur = __start_extables; cur < __stop_extables; ++cur) { + if (regs->_ASM_IP != cur->fault_addr) + continue; + + if (cur->fixup) + regs->_ASM_IP = cur->fixup; + else if (cur->cb) + cur->cb(regs); + + return true; } + + return false; } void do_exception(struct cpu_regs *regs) { static char ec_str[32], panic_str[128]; - use_extables(regs); + if (extables_fixup(regs)) + return; dump_regs(regs); print_callstack(_ptr(regs->_ASM_SP), _ptr(regs->_ASM_IP)); diff --git a/include/arch/x86/processor.h b/include/arch/x86/processor.h index 6f756cc8..9f33376c 100644 --- a/include/arch/x86/processor.h +++ b/include/arch/x86/processor.h @@ -173,6 +173,9 @@ #define X86_EX_SEL_TLB_IDT2 0x11 #ifndef __ASSEMBLY__ +#include +#include + union x86_ex_error_code { uint32_t error_code; struct __packed { diff --git a/include/cmdline.h b/include/cmdline.h index f36204ce..f7473807 100644 --- a/include/cmdline.h +++ b/include/cmdline.h @@ -26,6 +26,7 @@ #define KTF_CMDLINE_H #ifndef __ASSEMBLY__ +#include #define PARAM_MAX_LENGTH 32 @@ -52,4 +53,4 @@ struct __packed ktf_param { #endif /* __ASSEMBLY__ */ -#endif /* KTF_CMDLINE_H */ \ No newline at end of file +#endif /* KTF_CMDLINE_H */ diff --git a/include/compiler.h b/include/compiler.h index dade0e95..44991fd3 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -49,6 +49,8 @@ #define GHZ(x) (MHZ(x) * 1000) #ifndef __ASSEMBLY__ +#include + typedef uint64_t off_t; #define _ptr(val) ((void *) (unsigned long) (val)) #define _ul(val) ((unsigned long) (val)) diff --git a/include/mm/regions.h b/include/mm/regions.h index 65ef701f..df860ff0 100644 --- a/include/mm/regions.h +++ b/include/mm/regions.h @@ -42,27 +42,28 @@ #include #include -extern unsigned long __start_text[], __end_text[]; -extern unsigned long __start_data[], __end_data[]; -extern unsigned long __start_bss[], __end_bss[]; -extern unsigned long __start_rodata[], __end_rodata[]; +extern unsigned char __start_text[], __end_text[]; +extern unsigned char __start_data[], __end_data[]; +extern unsigned char __start_bss[], __end_bss[]; +extern unsigned char __start_rodata[], __end_rodata[]; -extern unsigned long __start_text_user[], __end_text_user[]; -extern unsigned long __start_data_user[], __end_data_user[]; -extern unsigned long __start_bss_user[], __end_bss_user[]; +extern unsigned char __start_text_user[], __end_text_user[]; +extern unsigned char __start_data_user[], __end_data_user[]; +extern unsigned char __start_bss_user[], __end_bss_user[]; -extern unsigned long __start_text_init[], __end_text_init[]; -extern unsigned long __start_data_init[], __end_data_init[]; -extern unsigned long __start_bss_init[], __end_bss_init[]; +extern unsigned char __start_text_init[], __end_text_init[]; +extern unsigned char __start_data_init[], __end_data_init[]; +extern unsigned char __start_bss_init[], __end_bss_init[]; -extern unsigned long __start_text_rmode[], __end_text_rmode[]; -extern unsigned long __start_data_rmode[], __end_data_rmode[]; -extern struct extable_entry __start_extables[], __end_extables[]; -extern unsigned long __start_bss_rmode[], __end_bss_rmode[]; +extern unsigned char __start_text_rmode[], __end_text_rmode[]; +extern unsigned char __start_data_rmode[], __end_data_rmode[]; +extern struct extable_entry __start_extables[], __stop_extables[]; +extern unsigned char __end_extables[]; +extern unsigned char __start_bss_rmode[], __end_bss_rmode[]; extern struct ktf_param __start_cmdline[], __end_cmdline[]; -extern unsigned long __weak __start_symbols[], __end_symbols[]; +extern unsigned char __weak __start_symbols[], __end_symbols[]; struct addr_range { const char *name;