diff --git a/configure.ac b/configure.ac index d9ba4f809e..51c614a4f9 100644 --- a/configure.ac +++ b/configure.ac @@ -1293,7 +1293,6 @@ then test "$enable_certext" = "" && enable_certext=yes test "$enable_sep" = "" && enable_sep=yes test "$enable_hkdf" = "" && enable_hkdf=yes - test "$enable_fpecc" = "" && test "$enable_ecc" != "no" && enable_fpecc=yes test "$enable_eccencrypt" = "" && test "$enable_ecc" != "no" && enable_eccencrypt=yes test "$enable_psk" = "" && enable_psk=yes test "$enable_cmac" = "" && enable_cmac=yes @@ -1323,6 +1322,13 @@ then test "$enable_anon" = "" && enable_anon=yes test "$enable_ssh" = "" && test "$enable_hmac" != "no" && enable_ssh=yes + # the compiler optimizer generates a weird out-of-bounds bss reference for + # find_hole() in the FP_ECC implementation. + if test "$ENABLED_LINUXKM_PIE" != yes + then + test "$enable_fpecc" = "" && test "$enable_ecc" != "no" && enable_fpecc=yes + fi + if test "x$FIPS_VERSION" != "xv1" then test "$enable_rsapss" = "" && enable_rsapss=yes diff --git a/linuxkm/Makefile b/linuxkm/Makefile index 3674140cff..366dcc9b79 100644 --- a/linuxkm/Makefile +++ b/linuxkm/Makefile @@ -105,8 +105,9 @@ ifeq "$(ENABLED_LINUXKM_PIE)" "yes" @$(READELF) --wide -r libwolfssl.ko | \ $(AWK) 'BEGIN { \ n=0; \ + bad_relocs=0; \ printf("%s\n ", \ - "const unsigned int wc_linuxkm_pie_reloc_tab[] = { "); \ + "const unsigned int wc_linuxkm_pie_reloc_tab[] = { "); \ } \ /^Relocation section '\''\.rela\.text\.wolfcrypt'\''/ { \ p=1; \ @@ -117,12 +118,20 @@ ifeq "$(ENABLED_LINUXKM_PIE)" "yes" } \ /^0/ { \ if (p) { \ + if ($$3 !~ "^(R_X86_64_PLT32|R_X86_64_PC32|R_AARCH64_.*)$$") { \ + print "Unexpected relocation type:\n" $$0 >"/dev/stderr"; \ + ++bad_relocs; \ + } \ printf("0x%s%s", \ gensub("^0*","",1,$$1), \ ((++n%8) ? ", " : ",\n ")); \ } \ } \ END { \ + if (bad_relocs) { \ + print "Found " bad_relocs " unexpected relocations." >"/dev/stderr"; \ + exit(1); \ + } \ print "~0U };\nconst size_t wc_linuxkm_pie_reloc_tab_length = sizeof wc_linuxkm_pie_reloc_tab / sizeof wc_linuxkm_pie_reloc_tab[0];";\ }' > wc_linuxkm_pie_reloc_tab.c +$(MAKE) ARCH='$(KERNEL_ARCH)' $(OVERRIDE_PATHS) $(CROSS_COMPILE) -C '$(KERNEL_ROOT)' M='$(MODULE_TOP)' $(KBUILD_EXTRA_FLAGS) CC_FLAGS_FTRACE= diff --git a/linuxkm/module_hooks.c b/linuxkm/module_hooks.c index aedd1a04c6..3a1dadcc71 100644 --- a/linuxkm/module_hooks.c +++ b/linuxkm/module_hooks.c @@ -710,8 +710,9 @@ ssize_t wc_linuxkm_normalize_relocations( int n_text_r = 0, n_rodata_r = 0, n_rwdata_r = 0, n_bss_r = 0, n_other_r = 0; #endif - if ((text_in < __wc_text_start) || - (text_in >= __wc_text_end)) + if ((text_in_len == 0) || + (text_in < __wc_text_start) || + (text_in + text_in_len >= __wc_text_end)) { return -1; } @@ -762,7 +763,7 @@ ssize_t wc_linuxkm_normalize_relocations( abs_ptr = (uintptr_t)text_in + next_reloc + 4 + reloc_buf; if ((abs_ptr >= (uintptr_t)__wc_text_start) && - (abs_ptr < (uintptr_t)__wc_text_end)) + (abs_ptr <= (uintptr_t)__wc_text_end)) { /* internal references in the .wolfcrypt.text segment don't need * normalization. @@ -773,7 +774,7 @@ ssize_t wc_linuxkm_normalize_relocations( continue; } else if ((abs_ptr >= (uintptr_t)__wc_rodata_start) && - (abs_ptr < (uintptr_t)__wc_rodata_end)) + (abs_ptr <= (uintptr_t)__wc_rodata_end)) { #ifdef DEBUG_LINUXKM_PIE_SUPPORT ++n_rodata_r; @@ -783,7 +784,7 @@ ssize_t wc_linuxkm_normalize_relocations( reloc_buf |= WC_RODATA_TAG; } else if ((abs_ptr >= (uintptr_t)__wc_rwdata_start) && - (abs_ptr < (uintptr_t)__wc_rwdata_end)) + (abs_ptr <= (uintptr_t)__wc_rwdata_end)) { #ifdef DEBUG_LINUXKM_PIE_SUPPORT ++n_rwdata_r; @@ -793,7 +794,7 @@ ssize_t wc_linuxkm_normalize_relocations( reloc_buf |= WC_RWDATA_TAG; } else if ((abs_ptr >= (uintptr_t)__wc_bss_start) && - (abs_ptr < (uintptr_t)__wc_bss_end)) + (abs_ptr <= (uintptr_t)__wc_bss_end)) { #ifdef DEBUG_LINUXKM_PIE_SUPPORT ++n_bss_r; @@ -809,19 +810,23 @@ ssize_t wc_linuxkm_normalize_relocations( reloc_buf = WC_OTHER_TAG; #ifdef DEBUG_LINUXKM_PIE_SUPPORT ++n_other_r; + /* we're currently only handling 32 bit relocations (R_X86_64_PLT32 + * and R_X86_64_PC32) so the top half of the word64 is padding we + * can lop off for rendering. + */ pr_notice("found non-wolfcrypt relocation at text offset 0x%x to " - "addr 0x%lx, text=%px-%px, rodata=%px-%px, " - "rwdata=%px-%px, bss=%px-%px\n", + "addr 0x%x, text=%x-%x, rodata=%x-%x, " + "rwdata=%x-%x, bss=%x-%x\n", wc_linuxkm_pie_reloc_tab[i], - abs_ptr, - __wc_text_start, - __wc_text_end, - __wc_rodata_start, - __wc_rodata_end, - __wc_rwdata_start, - __wc_rwdata_end, - __wc_bss_start, - __wc_bss_end); + (unsigned)(uintptr_t)abs_ptr, + (unsigned)(uintptr_t)__wc_text_start, + (unsigned)(uintptr_t)__wc_text_end, + (unsigned)(uintptr_t)__wc_rodata_start, + (unsigned)(uintptr_t)__wc_rodata_end, + (unsigned)(uintptr_t)__wc_rwdata_start, + (unsigned)(uintptr_t)__wc_rwdata_end, + (unsigned)(uintptr_t)__wc_bss_start, + (unsigned)(uintptr_t)__wc_bss_end); #endif } put_unaligned((u32)reloc_buf, (int32_t *)&text_out[next_reloc]); @@ -829,8 +834,9 @@ ssize_t wc_linuxkm_normalize_relocations( #ifdef DEBUG_LINUXKM_PIE_SUPPORT if (n_other_r > 0) - pr_notice("text_in=%px relocs=%d/%d/%d/%d/%d ret = %zu\n", - text_in, n_text_r, n_rodata_r, n_rwdata_r, n_bss_r, n_other_r, + pr_notice("text_in=%x relocs=%d/%d/%d/%d/%d ret = %zu\n", + (unsigned)(uintptr_t)text_in, n_text_r, n_rodata_r, + n_rwdata_r, n_bss_r, n_other_r, text_in_len); #endif diff --git a/linuxkm/wolfcrypt.lds b/linuxkm/wolfcrypt.lds index 55a5a78f70..6399a0c263 100644 --- a/linuxkm/wolfcrypt.lds +++ b/linuxkm/wolfcrypt.lds @@ -3,24 +3,28 @@ SECTIONS { .text.wolfcrypt : { __wc_text_start = .; *(.text.wolfcrypt) + . = ALIGN(4096); __wc_text_end = .; } . = ALIGN(4096); .rodata.wolfcrypt : { __wc_rodata_start = .; *(.rodata.wolfcrypt) + . = ALIGN(4096); __wc_rodata_end = .; } . = ALIGN(4096); .data.wolfcrypt : { __wc_rwdata_start = .; *(.data.wolfcrypt) + . = ALIGN(4096); __wc_rwdata_end = .; } . = ALIGN(4096); .bss.wolfcrypt : { __wc_bss_start = .; *(.bss.wolfcrypt) + . = ALIGN(4096); __wc_bss_end = .; } . = ALIGN(4096);