Skip to content
Open
4 changes: 2 additions & 2 deletions linuxkm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,11 @@ ifeq "$(ENABLED_LINUXKM_PIE)" "yes"
ifndef NO_PIE_FLAG
ifeq ($(KERNEL_ARCH),arm)
ifeq ($(intcmp $(VERSION),5,1,0,0),1)
NO_PIE_FLAG :=
NO_PIE_FLAG := 1
$(info Note: disabling -fPIE to avoid R_ARM_REL32 on pre-5.11 target kernel.)
else
ifeq ($(intcmp $(VERSION),5,0,1,0)-$(intcmp $(PATCHLEVEL),11,1,0,0),1-1)
NO_PIE_FLAG :=
NO_PIE_FLAG := 1
$(info Note: disabling -fPIE to avoid R_ARM_REL32 on pre-5.11 target kernel.)
endif
endif
Expand Down
57 changes: 41 additions & 16 deletions linuxkm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -157,30 +157,48 @@ GENERATE_SECTION_MAP := $(AWK) 'BEGIN { printf("") >ENVIRON["SECTION_MAP"]; } \
}'

GENERATE_RELOC_TAB := $(AWK) ' \
BEGIN { \
n=0; \
function open_seg(seg) { \
seen_seg[seg] = 1; \
printf("%s\n ", \
"WOLFSSL_LOCAL const struct wc_reloc_table_ent wc_linuxkm_pie_" seg "_reloc_tab[] = { "); \
cur_seg = seg; \
} \
function close_cur_seg() { \
print " { .offset = ~0U, .dest_offset = ~0U, .dest_addend = 0, .dest_segment = WC_R_SEG_NONE, .reloc_type = WC_R_NONE } };"; \
print "WOLFSSL_LOCAL const unsigned int wc_linuxkm_pie_" cur_seg "_reloc_tab_length = (unsigned int)(sizeof wc_linuxkm_pie_" cur_seg "_reloc_tab / sizeof wc_linuxkm_pie_" cur_seg "_reloc_tab[0]);"; \
cur_seg = ""; \
} \
BEGIN { \
bad_relocs=0; \
print "\#include <wolfssl/wolfcrypt/libwolfssl_sources.h>"; \
print "\#include <wolfssl/wolfcrypt/memory.h>"; \
printf("%s\n ", \
"WOLFSSL_LOCAL const struct wc_reloc_table_ent wc_linuxkm_pie_reloc_tab[] = { "); \
print ""; \
if ("SECTION_MAP" in ENVIRON) { \
while (getline <ENVIRON["SECTION_MAP"] > 0) \
section_map[$$1] = $$2; \
close(ENVIRON["SECTION_MAP"]); \
} \
} \
/^Relocation section '\''\.rela?\.text_wolfcrypt'\''/ { \
p=1; \
next; \
} \
\
/^Relocation section/ { \
p=0; \
if (cur_seg) { \
close_cur_seg(); \
} \
{ \
if (match($$0, "^Relocation section '\''\\.rela?\\.(text|rodata)_wolfcrypt'\''", a)) {\
open_seg(a[1]); \
next; \
} \
} \
} \
\
{ \
if (! cur_seg) \
next; \
} \
/^0/ { \
if (p) { \
if ($$3 !~ "^(R_X86_64_PLT32|R_X86_64_PC32|R_AARCH64_.*|R_ARM.*)$$") { \
print "Unexpected relocation type:\n" $$0 >"/dev/stderr"; \
if ($$3 !~ "^(R_X86_.*|R_AARCH64_.*|R_ARM.*)$$") { \
print "Unexpected relocation type in " cur_seg ":\n" $$0 >"/dev/stderr"; \
++bad_relocs; \
} \
if ($$5 in section_map) \
Expand Down Expand Up @@ -224,15 +242,22 @@ GENERATE_RELOC_TAB := $(AWK) ' \
strtonum("0x" $$4), \
$$6 strtonum("0x" $$7), \
section_tag, reloc_type); \
} \
} \
END { \
if (cur_seg) { \
close_cur_seg(); \
} \
n = split("text rodata", segs, " "); \
for (i = 1; i <= n; ++i) { \
if (! (segs[i] in seen_seg)) { \
open_seg(segs[i]); \
close_cur_seg(); \
} \
} \
if (bad_relocs) { \
print "Found " bad_relocs " unresolvable relocations." >"/dev/stderr"; \
exit(1); \
} \
print " { .offset = ~0U, .dest_offset = ~0U, .dest_addend = 0, .dest_segment = WC_R_SEG_NONE, .reloc_type = WC_R_NONE } };"; \
print "WOLFSSL_LOCAL const unsigned int wc_linuxkm_pie_reloc_tab_length = (unsigned int)(sizeof wc_linuxkm_pie_reloc_tab / sizeof wc_linuxkm_pie_reloc_tab[0]);"; \
}'

ifeq "$(V)" "1"
Expand Down Expand Up @@ -384,7 +409,7 @@ $(MODULE_TOP)/libwolfssl-user-build/src/.libs/libwolfssl.so: $(LIBWOLFSSL_NAME).
@ echo 'Using existing Makefile for libwolfssl.so.'
@else
@ echo -n 'Configuring user libwolfssl.so...'
@ $(FRESH_ENV) ./configure $(QFLAG) $(VFLAG) --disable-jobserver --enable-cryptonly --enable-fips="$$FIPS_FLAVOR" CFLAGS='-DWC_SYM_RELOC_TABLES_SUPPORT -DWOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE -DWOLFSSL_USER_SETTINGS -DWOLFSSL_USER_SETTINGS_ASM' $(if $(HOSTCC),CC='$(HOSTCC)')
@ $(FRESH_ENV) ./configure $(QFLAG) $(VFLAG) --disable-jobserver --enable-cryptonly --enable-fips="$$FIPS_FLAVOR" CFLAGS='-DWC_SYM_RELOC_TABLES_SUPPORT -DWOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE -DWOLFSSL_USER_SETTINGS -DWOLFSSL_USER_SETTINGS_ASM -DDEBUG_LINUXKM_PIE_SUPPORT' $(if $(HOSTCC),CC='$(HOSTCC)')
@ echo ' done.'
@fi
@echo -n 'Building user libwolfssl.so...'
Expand Down
12 changes: 8 additions & 4 deletions linuxkm/linuxkm-fips-hash-wrapper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,19 @@ fi
# shellcheck disable=SC2016 # using $AWK instead of awk confuses shellcheck.
readarray -t fenceposts < <(readelf --wide --sections --symbols "$mod_path" | "$AWK" '
BEGIN {
fips_fenceposts["wc_linuxkm_pie_reloc_tab"] = "reloc_tab_start";
fips_fenceposts["wc_linuxkm_pie_reloc_tab_length"] = "reloc_tab_len_start";
fips_fenceposts["wc_linuxkm_pie_text_reloc_tab"] = "text_reloc_tab.start";
fips_fenceposts["wc_linuxkm_pie_text_reloc_tab_length"] = "text_reloc_tab.len_start";
fips_fenceposts["wc_linuxkm_pie_rodata_reloc_tab"] = "rodata_reloc_tab.start";
fips_fenceposts["wc_linuxkm_pie_rodata_reloc_tab_length"] = "rodata_reloc_tab.len_start";
fips_fenceposts["verifyCore"] = "verifyCore_start";
fips_fenceposts["wolfCrypt_FIPS_first"] = "fips_text_start";
fips_fenceposts["wolfCrypt_FIPS_last"] = "fips_text_end";
fips_fenceposts["wolfCrypt_FIPS_ro_start"] = "fips_rodata_start";
fips_fenceposts["wolfCrypt_FIPS_ro_end"] = "fips_rodata_end";
singleton_ends["wc_linuxkm_pie_reloc_tab"] = "reloc_tab_end";
singleton_ends["wc_linuxkm_pie_reloc_tab_length"] = "reloc_tab_len_end";
singleton_ends["wc_linuxkm_pie_text_reloc_tab"] = "text_reloc_tab.end";
singleton_ends["wc_linuxkm_pie_text_reloc_tab_length"] = "text_reloc_tab.len_end";
singleton_ends["wc_linuxkm_pie_rodata_reloc_tab"] = "rodata_reloc_tab.end";
singleton_ends["wc_linuxkm_pie_rodata_reloc_tab_length"] = "rodata_reloc_tab.len_end";
singleton_ends["verifyCore"] = "verifyCore_end";
}

Expand Down
58 changes: 41 additions & 17 deletions linuxkm/linuxkm-fips-hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,14 @@ int main(int argc, char **argv)
.val = FENCEPOST_OPT_FLAG | offsetof(typeof(seg_map), x) }
FENCEPOST_OPT(text_start),
FENCEPOST_OPT(text_end),
FENCEPOST_OPT(reloc_tab_start),
FENCEPOST_OPT(reloc_tab_end),
FENCEPOST_OPT(reloc_tab_len_start),
FENCEPOST_OPT(reloc_tab_len_end),
FENCEPOST_OPT(text_reloc_tab.start),
FENCEPOST_OPT(text_reloc_tab.end),
FENCEPOST_OPT(text_reloc_tab.len_start),
FENCEPOST_OPT(text_reloc_tab.len_end),
FENCEPOST_OPT(rodata_reloc_tab.start),
FENCEPOST_OPT(rodata_reloc_tab.end),
FENCEPOST_OPT(rodata_reloc_tab.len_start),
FENCEPOST_OPT(rodata_reloc_tab.len_end),
FENCEPOST_OPT(fips_text_start),
FENCEPOST_OPT(fips_text_end),
FENCEPOST_OPT(rodata_start),
Expand Down Expand Up @@ -228,10 +232,14 @@ int main(int argc, char **argv)

if ((seg_map.text_start == ~0UL) ||
(seg_map.text_end == ~0UL) ||
(seg_map.reloc_tab_start == ~0UL) ||
(seg_map.reloc_tab_end == ~0UL) ||
(seg_map.reloc_tab_len_start == ~0UL) ||
(seg_map.reloc_tab_len_end == ~0UL) ||
(seg_map.text_reloc_tab.start == ~0UL) ||
(seg_map.text_reloc_tab.end == ~0UL) ||
(seg_map.text_reloc_tab.len_start == ~0UL) ||
(seg_map.text_reloc_tab.len_end == ~0UL) ||
(seg_map.rodata_reloc_tab.start == ~0UL) ||
(seg_map.rodata_reloc_tab.end == ~0UL) ||
(seg_map.rodata_reloc_tab.len_start == ~0UL) ||
(seg_map.rodata_reloc_tab.len_end == ~0UL) ||
(seg_map.fips_text_start == ~0UL) ||
(seg_map.fips_text_end == ~0UL) ||
(seg_map.rodata_start == ~0UL) ||
Expand Down Expand Up @@ -267,12 +275,23 @@ int main(int argc, char **argv)
exit(1);
}

if ((seg_map.reloc_tab_start >= seg_map.reloc_tab_end) ||
(seg_map.reloc_tab_end >= (unsigned long)st.st_size) ||
(seg_map.reloc_tab_len_start >= seg_map.reloc_tab_len_end) ||
(seg_map.reloc_tab_len_end >= (unsigned long)st.st_size))
if ((seg_map.text_reloc_tab.start >= seg_map.text_reloc_tab.end) ||
(seg_map.text_reloc_tab.end >= (unsigned long)st.st_size) ||
(seg_map.text_reloc_tab.len_start >= seg_map.text_reloc_tab.len_end) ||
(seg_map.text_reloc_tab.len_end >= (unsigned long)st.st_size))
{
fprintf(stderr, "%s: supplied reloc_tab fencepost(s) are out of bounds "
fprintf(stderr, "%s: supplied text_reloc_tab fencepost(s) are out of bounds "
"for supplied module %s with length %lu.\n",
progname, mod_path, (unsigned long)st.st_size);
exit(1);
}

if ((seg_map.rodata_reloc_tab.start >= seg_map.rodata_reloc_tab.end) ||
(seg_map.rodata_reloc_tab.end >= (unsigned long)st.st_size) ||
(seg_map.rodata_reloc_tab.len_start >= seg_map.rodata_reloc_tab.len_end) ||
(seg_map.rodata_reloc_tab.len_end >= (unsigned long)st.st_size))
{
fprintf(stderr, "%s: supplied rodata_reloc_tab fencepost(s) are out of bounds "
"for supplied module %s with length %lu.\n",
progname, mod_path, (unsigned long)st.st_size);
exit(1);
Expand All @@ -291,10 +310,15 @@ int main(int argc, char **argv)
seg_map.start = (unsigned long)mod_map;
seg_map.end = (unsigned long)mod_map + st.st_size;

seg_map.reloc_tab_start += (unsigned long)mod_map;
seg_map.reloc_tab_end += (unsigned long)mod_map;
seg_map.reloc_tab_len_start += (unsigned long)mod_map;
seg_map.reloc_tab_len_end += (unsigned long)mod_map;
seg_map.text_reloc_tab.start += (unsigned long)mod_map;
seg_map.text_reloc_tab.end += (unsigned long)mod_map;
seg_map.text_reloc_tab.len_start += (unsigned long)mod_map;
seg_map.text_reloc_tab.len_end += (unsigned long)mod_map;

seg_map.rodata_reloc_tab.start += (unsigned long)mod_map;
seg_map.rodata_reloc_tab.end += (unsigned long)mod_map;
seg_map.rodata_reloc_tab.len_start += (unsigned long)mod_map;
seg_map.rodata_reloc_tab.len_end += (unsigned long)mod_map;

seg_map.verifyCore_start += (unsigned long)mod_map;
seg_map.verifyCore_end += (unsigned long)mod_map;
Expand Down
Loading
Loading