mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-01-26 11:32:22 +01:00
linuxkm/Kbuild and linuxkm/module_hooks.c: refactor wc_linuxkm_pie_reloc_tab to include ground truth segment tag from ELF metadata.
tweaks for ARM32: recognize R_ARM_* relocations, and add -fno-unwind-tables to PIE_FLAGS. linuxkm/linuxkm_wc_port.h: * __PIE__: don't declare static pmd_to_page() unless USE_SPLIT_PMD_PTLOCKS. * add wc_lkm_refcount_to_int() helper with -Wnested-externs suppressed. wolfcrypt/src/fe_operations.c: in fe_frombytes() and fe_sq2(), use explicit XMEMSET()s to initialize working vars, rather than implicit, to avoid implicit (unshimmable) memset() calls. wolfcrypt/src/ge_operations.c: fix gate on _wc_curve25519_dummy() to require CURVED25519_ASM.
This commit is contained in:
@@ -127,6 +127,9 @@ ifeq "$(ENABLED_LINUXKM_PIE)" "yes"
|
||||
|
||||
OBJECT_FILES_NON_STANDARD := y
|
||||
endif
|
||||
ifeq "$(KERNEL_ARCH)" "arm"
|
||||
PIE_FLAGS += -fno-unwind-tables
|
||||
endif
|
||||
ifeq "$(KERNEL_ARCH)" "mips"
|
||||
PIE_FLAGS += -mabicalls
|
||||
endif
|
||||
|
||||
195
linuxkm/Makefile
195
linuxkm/Makefile
@@ -73,17 +73,17 @@ OVERRIDE_PATHS :=
|
||||
|
||||
ifdef CC
|
||||
ifneq "$(CC)" "cc"
|
||||
OVERRIDE_PATHS := $(OVERRIDE_PATHS) 'CC=$(CC)'
|
||||
OVERRIDE_PATHS := $(OVERRIDE_PATHS) 'CC=$(CC)'
|
||||
endif
|
||||
endif
|
||||
ifdef AS
|
||||
ifneq "$(AS)" "as"
|
||||
OVERRIDE_PATHS := $(OVERRIDE_PATHS) 'AS=$(AS)'
|
||||
OVERRIDE_PATHS := $(OVERRIDE_PATHS) 'AS=$(AS)'
|
||||
endif
|
||||
endif
|
||||
ifdef LD
|
||||
ifneq "$(LD)" "ld"
|
||||
OVERRIDE_PATHS := $(OVERRIDE_PATHS) 'LD=$(LD)'
|
||||
OVERRIDE_PATHS := $(OVERRIDE_PATHS) 'LD=$(LD)'
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -103,14 +103,39 @@ ifndef MAKE_TMPDIR
|
||||
MAKE_TMPDIR := $(TMPDIR)
|
||||
endif
|
||||
|
||||
GENERATE_RELOC_TAB := $(AWK) 'BEGIN { \
|
||||
GENERATE_SECTION_MAP := $(AWK) 'BEGIN { printf("") >ENVIRON["SECTION_MAP"]; } \
|
||||
{ \
|
||||
if ($$7 !~ "^[0-9]+$$") \
|
||||
next; \
|
||||
if ($$4 == "SECTION") { \
|
||||
sections[$$7] = $$8; \
|
||||
next; \
|
||||
} \
|
||||
if (($$4 == "NOTYPE") || ($$4 == "OBJECT") || ($$4 == "FUNC")) { \
|
||||
if (($$8 == "$$d") || ($$8 == "$$t")) \
|
||||
next; \
|
||||
if ($$7 in sections) { \
|
||||
if (sections[$$7] ~ "_wolfcrypt$$") \
|
||||
print $$8 "\t" sections[$$7] >>ENVIRON["SECTION_MAP"]; \
|
||||
} else \
|
||||
print $$8 " is in section " $$7 " with no name mapping." >"/dev/stderr";\
|
||||
} \
|
||||
}'
|
||||
|
||||
GENERATE_RELOC_TAB := $(AWK) ' \
|
||||
BEGIN { \
|
||||
n=0; \
|
||||
bad_relocs=0; \
|
||||
print "\#include <wolfssl/wolfcrypt/libwolfssl_sources.h>"; \
|
||||
printf("%s\n ", \
|
||||
"WOLFSSL_LOCAL const unsigned int wc_linuxkm_pie_reloc_tab[] = { "); \
|
||||
"WOLFSSL_LOCAL const unsigned int wc_linuxkm_pie_reloc_tab[] = { "); \
|
||||
if ("SECTION_MAP" in ENVIRON) { \
|
||||
while (getline <ENVIRON["SECTION_MAP"] > 0) \
|
||||
section_map[$$1] = $$2; \
|
||||
close(ENVIRON["SECTION_MAP"]); \
|
||||
} \
|
||||
} \
|
||||
/^Relocation section '\''\.rela\.text_wolfcrypt'\''/ { \
|
||||
/^Relocation section '\''\.rela?\.text_wolfcrypt'\''/ { \
|
||||
p=1; \
|
||||
next; \
|
||||
} \
|
||||
@@ -119,19 +144,55 @@ GENERATE_RELOC_TAB := $(AWK) 'BEGIN { \
|
||||
} \
|
||||
/^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 ")); \
|
||||
if ($$3 !~ "^(R_X86_64_PLT32|R_X86_64_PC32|R_AARCH64_.*|R_ARM.*)$$") { \
|
||||
print "Unexpected relocation type:\n" $$0 >"/dev/stderr"; \
|
||||
++bad_relocs; \
|
||||
} \
|
||||
if ($$5 in section_map) \
|
||||
section = section_map[$$5]; \
|
||||
else if ($$5 ~ "^\\.") \
|
||||
section = $$5; \
|
||||
else \
|
||||
section = ""; \
|
||||
if (section) { \
|
||||
switch (section) { \
|
||||
case ".text_wolfcrypt": \
|
||||
section_tag = 0; \
|
||||
break; \
|
||||
case ".rodata_wolfcrypt": \
|
||||
section_tag = 1; \
|
||||
break; \
|
||||
case ".data_wolfcrypt": \
|
||||
section_tag = 2; \
|
||||
break; \
|
||||
case ".bss_wolfcrypt": \
|
||||
section_tag = 3; \
|
||||
break; \
|
||||
default: \
|
||||
print "Unexpected section:\n" $$0 >"/dev/stderr"; \
|
||||
++bad_relocs; \
|
||||
section_tag = 4; \
|
||||
} \
|
||||
} else { \
|
||||
print "Unresolvable symbol reference for relocation:\n" $$0 >"/dev/stderr";\
|
||||
++bad_relocs; \
|
||||
section_tag = 4; \
|
||||
} \
|
||||
if (strtonum("0x" gensub("^0*","",1,$$1)) >= lshift(1, 29)) { \
|
||||
print "Relocation offset overflow:" >"/dev/stderr"; \
|
||||
print >"/dev/stderr"; \
|
||||
exit(1); \
|
||||
} \
|
||||
printf("0x%xU%s", \
|
||||
or(strtonum("0x" gensub("^0*","",1,$$1)), \
|
||||
lshift(section_tag, 29)), \
|
||||
((++n%8) ? ", " : ",\n ")); \
|
||||
} \
|
||||
} \
|
||||
END { \
|
||||
if (bad_relocs) { \
|
||||
print "Found " bad_relocs " unexpected relocations." >"/dev/stderr"; \
|
||||
exit(1); \
|
||||
print "Found " bad_relocs " unresolvable relocations." >"/dev/stderr"; \
|
||||
exit(1); \
|
||||
} \
|
||||
print "~0U };\nWOLFSSL_LOCAL const unsigned long wc_linuxkm_pie_reloc_tab_length = sizeof wc_linuxkm_pie_reloc_tab / sizeof wc_linuxkm_pie_reloc_tab[0];";\
|
||||
}'
|
||||
@@ -140,88 +201,98 @@ ifeq "$(V)" "1"
|
||||
vflag := --verbose
|
||||
endif
|
||||
|
||||
# This rule is .PHONY because it doesn't actually build the module -- Kbuild
|
||||
# does, and we always need to call Kbuild to enforce rebuild for dependencies
|
||||
# and config changes.
|
||||
.PHONY: libwolfssl.ko
|
||||
libwolfssl.ko:
|
||||
@function resolved_link_is_equal() { [[ -L "$$1" && ("$$(readlink -f "$$1")" == "$$(readlink -f "$$2")") ]] }
|
||||
@set -e
|
||||
@function resolved_link_is_equal() { [[ -L "$$1" && "$$(readlink -f "$$1")" == "$$(readlink -f "$$2")" ]]; }
|
||||
@if test -z '$(KERNEL_ROOT)'; then echo '$$KERNEL_ROOT is unset' >&2; exit 1; fi
|
||||
@if test -z '$(AM_CFLAGS)$(CFLAGS)'; then echo '$$AM_CFLAGS and $$CFLAGS are both unset.' >&2; exit 1; fi
|
||||
@if test -z '$(src_libwolfssl_la_OBJECTS)'; then echo '$$src_libwolfssl_la_OBJECTS is unset.' >&2; exit 1; fi
|
||||
# after commit 9a0ebe5011 (6.10), sources must be in $(obj). work around this by making links to all needed sources:
|
||||
# after commit 9a0ebe5011 (6.10), sources must be in $(obj). work around this by making links to all needed sources:
|
||||
@mkdir -p '$(MODULE_TOP)/linuxkm'
|
||||
@resolved_link_is_equal '$(MODULE_TOP)/linuxkm/module_hooks.c' '$(MODULE_TOP)/module_hooks.c' || cp $(vflag) --no-dereference --symbolic-link --no-clobber '$(MODULE_TOP)'/*.[ch] '$(MODULE_TOP)/linuxkm/'
|
||||
@resolved_link_is_equal '$(MODULE_TOP)/wolfcrypt/src/wc_port.c' '$(SRC_TOP)/wolfcrypt/src/wc_port.c' || cp $(vflag) --no-dereference --symbolic-link --no-clobber --recursive '$(SRC_TOP)/wolfcrypt' '$(MODULE_TOP)/'
|
||||
@resolved_link_is_equal '$(MODULE_TOP)/src/wolfio.c' '$(SRC_TOP)/src/wolfio.c' || cp $(vflag) --no-dereference --symbolic-link --no-clobber --recursive '$(SRC_TOP)/src' '$(MODULE_TOP)/'
|
||||
ifeq "$(FIPS_OPTEST)" "1"
|
||||
@resolved_link_is_equal '$(MODULE_TOP)/linuxkm/optest-140-3/linuxkm_optest_wrapper.c' '$(SRC_TOP)/../fips/optest-140-3/linuxkm_optest_wrapper.c' || cp $(vflag) --no-dereference --symbolic-link --no-clobber --recursive '$(SRC_TOP)/../fips/optest-140-3' '$(MODULE_TOP)/linuxkm'
|
||||
@resolved_link_is_equal '$(MODULE_TOP)/linuxkm/optest-140-3/linuxkm_optest_wrapper.c' '$(SRC_TOP)/../fips/optest-140-3/linuxkm_optest_wrapper.c' || cp $(vflag) --no-dereference --symbolic-link --no-clobber --recursive '$(SRC_TOP)/../fips/optest-140-3' '$(MODULE_TOP)/linuxkm/'
|
||||
endif
|
||||
ifeq "$(ENABLED_LINUXKM_PIE)" "yes"
|
||||
@[[ -f '$(MODULE_TOP)/linuxkm/wc_linuxkm_pie_reloc_tab.c' && ! -L '$(MODULE_TOP)/linuxkm/wc_linuxkm_pie_reloc_tab.c' ]] || \
|
||||
{ $(RM) -f '$(MODULE_TOP)/linuxkm/wc_linuxkm_pie_reloc_tab.c' && $(GENERATE_RELOC_TAB) < /dev/null > '$(MODULE_TOP)/linuxkm/wc_linuxkm_pie_reloc_tab.c'; }
|
||||
@$(eval RELOC_TMP := $(shell mktemp "$(MAKE_TMPDIR)/wc_linuxkm_pie_reloc_tab.c.XXXXXX"))
|
||||
@if [[ -f libwolfssl.ko ]]; then touch -r libwolfssl.ko '$(RELOC_TMP)'; fi
|
||||
@RELOC_TMP=$$(mktemp "$(MAKE_TMPDIR)/wc_linuxkm_pie_reloc_tab.c.XXXXXX")
|
||||
@trap 'rm "$$RELOC_TMP"' EXIT
|
||||
@if [[ -f "$@" ]]; then touch -r "$@" "$$RELOC_TMP"; fi
|
||||
+$(MAKE) ARCH='$(KERNEL_ARCH)' $(OVERRIDE_PATHS) $(CROSS_COMPILE) -C '$(KERNEL_ROOT)' M='$(MODULE_TOP)' $(KBUILD_EXTRA_FLAGS) CC_FLAGS_FTRACE=
|
||||
# if the above make didn't build a fresh libwolfssl.ko, then the module is already up to date and we leave it untouched, assuring stability for purposes of module-update-fips-hash.
|
||||
@if [[ ! libwolfssl.ko -nt '$(RELOC_TMP)' ]]; then rm '$(RELOC_TMP)'; echo ' Module already up-to-date.'; exit 0; fi
|
||||
@$(READELF) --wide -r libwolfssl.ko | $(GENERATE_RELOC_TAB) >| '$(MODULE_TOP)/linuxkm/wc_linuxkm_pie_reloc_tab.c'
|
||||
@if [[ ! "$@" -nt "$$RELOC_TMP" ]]; then echo ' Module already up-to-date.'; exit 0; fi
|
||||
@SECTION_MAP=$$(mktemp)
|
||||
@trap 'rm "$$SECTION_MAP"' EXIT
|
||||
@export SECTION_MAP
|
||||
@$(READELF) --wide --symbols "$@" | $(GENERATE_SECTION_MAP)
|
||||
@$(READELF) --wide --relocs "$@" | $(GENERATE_RELOC_TAB) >| '$(MODULE_TOP)/linuxkm/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=
|
||||
@$(READELF) --wide -r libwolfssl.ko | $(GENERATE_RELOC_TAB) >| '$(RELOC_TMP)'
|
||||
@if diff '$(MODULE_TOP)/linuxkm/wc_linuxkm_pie_reloc_tab.c' '$(RELOC_TMP)'; then echo " Relocation table is stable."; else echo "PIE failed: relocation table is unstable." 1>&2; rm '$(RELOC_TMP)'; exit 1; fi
|
||||
@rm '$(RELOC_TMP)'
|
||||
@$(READELF) --wide --relocs "$@" | $(GENERATE_RELOC_TAB) >| "$$RELOC_TMP"
|
||||
@if diff '$(MODULE_TOP)/linuxkm/wc_linuxkm_pie_reloc_tab.c' "$$RELOC_TMP"; then echo " Relocation table is stable."; else echo "PIE failed: relocation table is unstable." 1>&2; exit 1; fi
|
||||
else
|
||||
+$(MAKE) ARCH='$(KERNEL_ARCH)' $(OVERRIDE_PATHS) $(CROSS_COMPILE) -C '$(KERNEL_ROOT)' M='$(MODULE_TOP)' $(KBUILD_EXTRA_FLAGS)
|
||||
endif
|
||||
|
||||
.PHONY: module-update-fips-hash
|
||||
module-update-fips-hash: libwolfssl.ko
|
||||
@if test -z '$(FIPS_HASH)'; then echo ' $$FIPS_HASH is unset' >&2; exit 1; fi
|
||||
@set -e
|
||||
@if test -z '$(FIPS_HASH)'; then echo ' $$FIPS_HASH is unset' >&2; exit 1; fi
|
||||
@if [[ ! '$(FIPS_HASH)' =~ [0-9a-fA-F]{64} ]]; then echo ' $$FIPS_HASH is malformed' >&2; exit 1; fi
|
||||
@readarray -t rodata_segment < <($(READELF) --wide --sections libwolfssl.ko | \
|
||||
@readarray -t rodata_segment < <($(READELF) --wide --sections "$<" | \
|
||||
sed -E -n 's/^[[:space:]]*\[[[:space:]]*([0-9]+)\][[:space:]]+\.rodata_wolfcrypt[[:space:]]+PROGBITS[[:space:]]+[0-9a-fA-F]+[[:space:]]+([0-9a-fA-F]+)[[:space:]].*$$/\1\n\2/p'); \
|
||||
if [[ $${#rodata_segment[@]} != 2 ]]; then echo ' unexpected rodata_segment.' >&2; exit 1; fi; \
|
||||
readarray -t verifyCore_attrs < <($(READELF) --wide --symbols libwolfssl.ko | \
|
||||
readarray -t verifyCore_attrs < <($(READELF) --wide --symbols "$<" | \
|
||||
sed -E -n 's/^[[:space:]]*[0-9]+: ([0-9a-fA-F]+)[[:space:]]+([0-9]+)[[:space:]]+OBJECT[[:space:]]+[A-Z]+[[:space:]]+[A-Z]+[[:space:]]+'"$${rodata_segment[0]}"'[[:space:]]+verifyCore$$/\1\n\2/p'); \
|
||||
if [[ $${#verifyCore_attrs[@]} != 2 ]]; then echo ' unexpected verifyCore_attrs.' >&2; exit 1; fi; \
|
||||
if [[ "$${verifyCore_attrs[1]}" != "65" ]]; then echo " verifyCore has unexpected length $${verifyCore_attrs[1]}." >&2; exit 1; fi; \
|
||||
if [[ "$${verifyCore_attrs[1]}" != "65" ]]; then echo " verifyCore has unexpected length $${verifyCore_attrs[1]}." >&2; exit 1; fi; \
|
||||
verifyCore_offset=$$((0x$${rodata_segment[1]} + 0x$${verifyCore_attrs[0]})); \
|
||||
current_verifyCore=$$(dd bs=1 if=libwolfssl.ko skip=$$verifyCore_offset count=64 status=none); \
|
||||
current_verifyCore=$$(dd bs=1 if="$<" skip=$$verifyCore_offset count=64 status=none); \
|
||||
if [[ ! "$$current_verifyCore" =~ [0-9a-fA-F]{64} ]]; then echo " verifyCore at offset $$verifyCore_offset has unexpected value." >&2; exit 1; fi; \
|
||||
if [[ '$(FIPS_HASH)' == "$$current_verifyCore" ]]; then echo ' Supplied FIPS_HASH matches existing verifyCore -- no update needed.'; exit 0; fi; \
|
||||
echo -n '$(FIPS_HASH)' | dd bs=1 conv=notrunc of=libwolfssl.ko seek=$$verifyCore_offset count=64 status=none && \
|
||||
echo " FIPS verifyCore updated successfully." && \
|
||||
if [[ '$(FIPS_HASH)' == "$$current_verifyCore" ]]; then echo ' Supplied FIPS_HASH matches existing verifyCore -- no update needed.'; exit 0; fi; \
|
||||
echo -n '$(FIPS_HASH)' | dd bs=1 conv=notrunc of="$<" seek=$$verifyCore_offset count=64 status=none && \
|
||||
echo " FIPS verifyCore updated successfully." && \
|
||||
if [[ -f libwolfssl.ko.signed ]]; then $(MAKE) -C . libwolfssl.ko.signed; fi
|
||||
|
||||
libwolfssl.ko.signed: libwolfssl.ko
|
||||
ifdef FORCE_NO_MODULE_SIG
|
||||
@echo 'Skipping module signature operation because FORCE_NO_MODULE_SIG.'
|
||||
else
|
||||
@cd '$(KERNEL_ROOT)' || exit $$?; \
|
||||
while read configline; do \
|
||||
case "$$configline" in \
|
||||
CONFIG_MODULE_SIG*=*) \
|
||||
declare "$${configline%=*}"="$${configline#*=}" \
|
||||
;; \
|
||||
esac; \
|
||||
done < .config || exit $$?; \
|
||||
if [[ "$${CONFIG_MODULE_SIG}" = "y" && -n "$${CONFIG_MODULE_SIG_KEY}" && \
|
||||
-n "$${CONFIG_MODULE_SIG_HASH}" && ( ! -f '$(MODULE_TOP)/$@' || \
|
||||
'$(MODULE_TOP)/$<' -nt '$(MODULE_TOP)/$@' ) ]]; then \
|
||||
CONFIG_MODULE_SIG_KEY="$${CONFIG_MODULE_SIG_KEY#\"}"; \
|
||||
CONFIG_MODULE_SIG_KEY="$${CONFIG_MODULE_SIG_KEY%\"}"; \
|
||||
CONFIG_MODULE_SIG_HASH="$${CONFIG_MODULE_SIG_HASH#\"}"; \
|
||||
CONFIG_MODULE_SIG_HASH="$${CONFIG_MODULE_SIG_HASH%\"}"; \
|
||||
cp -p '$(MODULE_TOP)/$<' '$(MODULE_TOP)/$@' || exit $$?; \
|
||||
./scripts/sign-file "$${CONFIG_MODULE_SIG_HASH}" \
|
||||
"$${CONFIG_MODULE_SIG_KEY}" \
|
||||
"$${CONFIG_MODULE_SIG_KEY/%.pem/.x509}" \
|
||||
'$(MODULE_TOP)/$@'; \
|
||||
sign_file_exitval=$$?; \
|
||||
if [[ $$sign_file_exitval != 0 ]]; then \
|
||||
$(RM) -f '$(MODULE_TOP)/$@'; \
|
||||
exit $$sign_file_exitval; \
|
||||
fi; \
|
||||
if [[ "$(quiet)" != "silent_" ]]; then \
|
||||
echo " Module $@ signed by $${CONFIG_MODULE_SIG_KEY}."; \
|
||||
fi \
|
||||
@set -e
|
||||
@cd '$(KERNEL_ROOT)'
|
||||
while read configline; do
|
||||
case "$$configline" in
|
||||
CONFIG_MODULE_SIG*=*)
|
||||
declare "$${configline%=*}"="$${configline#*=}"
|
||||
;;
|
||||
esac
|
||||
done < .config
|
||||
if [[ "$${CONFIG_MODULE_SIG}" = "y" && -n "$${CONFIG_MODULE_SIG_KEY}" && \
|
||||
-n "$${CONFIG_MODULE_SIG_HASH}" && ( ! -f '$(MODULE_TOP)/$@' || \
|
||||
'$(MODULE_TOP)/$<' -nt '$(MODULE_TOP)/$@' ) ]]; then
|
||||
CONFIG_MODULE_SIG_KEY="$${CONFIG_MODULE_SIG_KEY#\"}"
|
||||
CONFIG_MODULE_SIG_KEY="$${CONFIG_MODULE_SIG_KEY%\"}"
|
||||
CONFIG_MODULE_SIG_HASH="$${CONFIG_MODULE_SIG_HASH#\"}"
|
||||
CONFIG_MODULE_SIG_HASH="$${CONFIG_MODULE_SIG_HASH%\"}"
|
||||
cp -p '$(MODULE_TOP)/$<' '$(MODULE_TOP)/$@' || exit $$?
|
||||
./scripts/sign-file "$${CONFIG_MODULE_SIG_HASH}" \
|
||||
"$${CONFIG_MODULE_SIG_KEY}" \
|
||||
"$${CONFIG_MODULE_SIG_KEY/%.pem/.x509}" \
|
||||
'$(MODULE_TOP)/$@'
|
||||
sign_file_exitval=$$?
|
||||
if [[ $$sign_file_exitval != 0 ]]; then
|
||||
$(RM) -f '$(MODULE_TOP)/$@'
|
||||
exit $$sign_file_exitval
|
||||
fi
|
||||
if [[ "$(quiet)" != "silent_" ]]; then
|
||||
echo " Module $@ signed by $${CONFIG_MODULE_SIG_KEY}."
|
||||
fi
|
||||
fi
|
||||
endif
|
||||
|
||||
@@ -234,10 +305,10 @@ install modules_install:
|
||||
# note, must supply $(MODULE_TOP) as the src value for clean so that Kbuild is included, else
|
||||
# the top Makefile (which is not for the kernel build) would be included here.
|
||||
clean:
|
||||
+$(MAKE) -C $(KERNEL_ROOT) M=$(MODULE_TOP) src=$(MODULE_TOP) clean
|
||||
$(RM) -rf '$(MODULE_TOP)/linuxkm'
|
||||
$(RM) -rf '$(MODULE_TOP)/wolfcrypt'
|
||||
$(RM) -rf '$(MODULE_TOP)/src'
|
||||
+$(MAKE) -C $(KERNEL_ROOT) M=$(MODULE_TOP) src=$(MODULE_TOP) clean
|
||||
|
||||
.PHONY: check
|
||||
check:
|
||||
|
||||
@@ -428,7 +428,9 @@
|
||||
*/
|
||||
#ifdef __PIE__
|
||||
#include <linux/mm_types.h>
|
||||
#if USE_SPLIT_PMD_PTLOCKS
|
||||
static __always_inline struct page *pmd_to_page(pmd_t *pmd);
|
||||
#endif
|
||||
#endif
|
||||
#include <linux/mm.h>
|
||||
#endif
|
||||
@@ -496,10 +498,21 @@
|
||||
#endif /* linux ver >= 6.13 */
|
||||
|
||||
#if defined(_LINUX_REFCOUNT_H) || defined(_LINUX_REFCOUNT_TYPES_H)
|
||||
#define WC_LKM_REFCOUNT_TO_INT(refcount) (atomic_read(&(refcount.refs)))
|
||||
static inline int wc_lkm_refcount_to_int(refcount_t *refcount) {
|
||||
_Pragma("GCC diagnostic push");
|
||||
_Pragma("GCC diagnostic ignored \"-Wnested-externs\"");
|
||||
return atomic_read(&(refcount->refs));
|
||||
_Pragma("GCC diagnostic pop");
|
||||
}
|
||||
#else
|
||||
#define WC_LKM_REFCOUNT_TO_INT(refcount) (atomic_read(&(refcount)))
|
||||
static inline int wc_lkm_refcount_to_int(atomic_t *refcount) {
|
||||
_Pragma("GCC diagnostic push");
|
||||
_Pragma("GCC diagnostic ignored \"-Wnested-externs\"");
|
||||
return atomic_read(&refcount);
|
||||
_Pragma("GCC diagnostic pop");
|
||||
}
|
||||
#endif
|
||||
#define WC_LKM_REFCOUNT_TO_INT(refcount) wc_lkm_refcount_to_int(&(refcount))
|
||||
#endif /* !__PIE__ */
|
||||
#endif /* LINUXKM_LKCAPI_REGISTER */
|
||||
|
||||
@@ -747,7 +760,7 @@
|
||||
__wc_bss_start[],
|
||||
__wc_bss_end[];
|
||||
extern const unsigned int wc_linuxkm_pie_reloc_tab[];
|
||||
extern const size_t wc_linuxkm_pie_reloc_tab_length;
|
||||
extern const unsigned long wc_linuxkm_pie_reloc_tab_length;
|
||||
extern ssize_t wc_linuxkm_normalize_relocations(
|
||||
const u8 *text_in,
|
||||
size_t text_in_len,
|
||||
|
||||
@@ -864,8 +864,18 @@ MODULE_VERSION(LIBWOLFSSL_VERSION_STRING);
|
||||
|
||||
#ifdef WC_PIE_RELOC_TABLES
|
||||
|
||||
static inline int find_reloc_tab_offset(size_t text_in_offset) {
|
||||
int ret, hop;
|
||||
#define WC_TEXT_TAG (0x0 << 29)
|
||||
#define WC_RODATA_TAG (0x1U << 29)
|
||||
#define WC_RWDATA_TAG (0x2U << 29)
|
||||
#define WC_BSS_TAG (0x3U << 29)
|
||||
#define WC_OTHER_TAG (0x4U << 29)
|
||||
|
||||
#define WC_RELOC_TAG_MASK (0x7U << 29)
|
||||
#define WC_RELOC_OFFSET_MASK (~WC_RELOC_TAG_MASK)
|
||||
|
||||
static inline long find_reloc_tab_offset(size_t text_in_offset) {
|
||||
long ret;
|
||||
unsigned long hop;
|
||||
if (wc_linuxkm_pie_reloc_tab_length <= 1) {
|
||||
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
|
||||
pr_err("ERROR: %s failed at L %d.\n", __FUNCTION__, __LINE__);
|
||||
@@ -878,45 +888,40 @@ static inline int find_reloc_tab_offset(size_t text_in_offset) {
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
if (text_in_offset >= (size_t)wc_linuxkm_pie_reloc_tab[wc_linuxkm_pie_reloc_tab_length - 1]) {
|
||||
if (text_in_offset >= (size_t)(wc_linuxkm_pie_reloc_tab[wc_linuxkm_pie_reloc_tab_length - 1] & WC_RELOC_OFFSET_MASK)) {
|
||||
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
|
||||
pr_err("ERROR: %s failed at L %d.\n", __FUNCTION__, __LINE__);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
for (ret = 0,
|
||||
hop = (int)wc_linuxkm_pie_reloc_tab_length / 2;
|
||||
hop = wc_linuxkm_pie_reloc_tab_length >> 1;
|
||||
hop;
|
||||
hop >>= 1)
|
||||
{
|
||||
if (text_in_offset == (size_t)wc_linuxkm_pie_reloc_tab[ret])
|
||||
if (text_in_offset == (size_t)(wc_linuxkm_pie_reloc_tab[ret] & WC_RELOC_OFFSET_MASK))
|
||||
break;
|
||||
else if (text_in_offset > (size_t)wc_linuxkm_pie_reloc_tab[ret])
|
||||
else if (text_in_offset > (size_t)(wc_linuxkm_pie_reloc_tab[ret] & WC_RELOC_OFFSET_MASK))
|
||||
ret += hop;
|
||||
else if (ret)
|
||||
ret -= hop;
|
||||
}
|
||||
|
||||
while ((ret < (int)wc_linuxkm_pie_reloc_tab_length - 1) &&
|
||||
((size_t)wc_linuxkm_pie_reloc_tab[ret] < text_in_offset))
|
||||
while ((ret < (long)wc_linuxkm_pie_reloc_tab_length - 1) &&
|
||||
((size_t)(wc_linuxkm_pie_reloc_tab[ret] & WC_RELOC_OFFSET_MASK) < text_in_offset))
|
||||
++ret;
|
||||
|
||||
while ((ret > 0) &&
|
||||
((size_t)wc_linuxkm_pie_reloc_tab[ret - 1] >= text_in_offset))
|
||||
((size_t)(wc_linuxkm_pie_reloc_tab[ret - 1] & WC_RELOC_OFFSET_MASK) >= text_in_offset))
|
||||
--ret;
|
||||
|
||||
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
|
||||
if (ret < 0)
|
||||
pr_err("ERROR: %s returning %d at L %d.\n", __FUNCTION__, ret, __LINE__);
|
||||
pr_err("ERROR: %s returning %ld at L %d.\n", __FUNCTION__, ret, __LINE__);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define WC_RODATA_TAG (0x1U << 29)
|
||||
#define WC_RWDATA_TAG (0x2U << 29)
|
||||
#define WC_BSS_TAG (0x3U << 29)
|
||||
#define WC_OTHER_TAG (0x4U << 29)
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)
|
||||
#include <linux/unaligned.h>
|
||||
#else
|
||||
@@ -941,7 +946,12 @@ ssize_t wc_linuxkm_normalize_relocations(
|
||||
((uintptr_t)(text_in + text_in_len) > (uintptr_t)__wc_text_end))
|
||||
{
|
||||
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
|
||||
pr_err("ERROR: %s returning -1 at L %d with span %x-%x versus segment %x-%x.\n", __FUNCTION__, __LINE__, (unsigned)(uintptr_t)text_in, (unsigned)(uintptr_t)(text_in + text_in_len), (unsigned)(uintptr_t)__wc_text_start, (unsigned)(uintptr_t)__wc_text_end);
|
||||
pr_err("ERROR: %s returning -1 at L %d with span %x-%x versus segment %x-%x.\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
(unsigned)(uintptr_t)text_in,
|
||||
(unsigned)(uintptr_t)(text_in + text_in_len),
|
||||
(unsigned)(uintptr_t)__wc_text_start,
|
||||
(unsigned)(uintptr_t)__wc_text_end);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
@@ -969,16 +979,21 @@ ssize_t wc_linuxkm_normalize_relocations(
|
||||
++i)
|
||||
{
|
||||
size_t next_reloc = wc_linuxkm_pie_reloc_tab[i];
|
||||
unsigned int reloc_tag;
|
||||
int reloc_buf;
|
||||
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
|
||||
uintptr_t abs_ptr;
|
||||
#endif
|
||||
|
||||
if (last_reloc > next_reloc) {
|
||||
if ((last_reloc & WC_RELOC_OFFSET_MASK) > (next_reloc & WC_RELOC_OFFSET_MASK)) {
|
||||
pr_err("BUG: out-of-order offset found at wc_linuxkm_pie_reloc_tab[%zd]: %zu > %zu\n",
|
||||
i, last_reloc, next_reloc);
|
||||
i, last_reloc & WC_RELOC_OFFSET_MASK, next_reloc & WC_RELOC_OFFSET_MASK);
|
||||
return -1;
|
||||
}
|
||||
last_reloc = next_reloc;
|
||||
|
||||
reloc_tag = next_reloc & WC_RELOC_TAG_MASK;
|
||||
next_reloc &= WC_RELOC_OFFSET_MASK;
|
||||
next_reloc -= text_in_offset;
|
||||
|
||||
if (next_reloc >= text_in_len) {
|
||||
@@ -996,7 +1011,14 @@ ssize_t wc_linuxkm_normalize_relocations(
|
||||
/* set reloc_buf to the relative address from the live text segment. */
|
||||
reloc_buf = (int)get_unaligned((int32_t *)&text_out[next_reloc]);
|
||||
|
||||
/* abs_ptr is the absolute address referred to by the relocation. we
|
||||
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
|
||||
/* when debugging runtime segment consistency, for the various data
|
||||
* segments, recognize dest addrs a few bytes outside the segment -- the
|
||||
* compiler occasionally generates these, e.g. __wc_rwdata_start - 1 in
|
||||
* DoInCoreCheck() in kernel 6.1 build of FIPS v5, __wc_bss_start - 4 in
|
||||
* kernel 4.4, and __wc_rodata_end + 26 in kernel 6.18.
|
||||
*
|
||||
* abs_ptr is the absolute address referred to by the relocation. we
|
||||
* need this in order to identify the target segment of the relocation,
|
||||
* thereby allowing us to use the correct normalization tag and
|
||||
* corrective offset for the relocation.
|
||||
@@ -1009,59 +1031,66 @@ ssize_t wc_linuxkm_normalize_relocations(
|
||||
* the +4 accounts for the disp32 field size, as RIP points to the next
|
||||
* instruction byte per the x86_64 ABI.
|
||||
*/
|
||||
abs_ptr = (uintptr_t)text_in + next_reloc + 4 + reloc_buf;
|
||||
#ifndef LINUXKM_PIE_DATA_SLOP_MARGIN
|
||||
#define LINUXKM_PIE_DATA_SLOP_MARGIN 0x20
|
||||
#endif
|
||||
|
||||
if ((abs_ptr >= (uintptr_t)__wc_text_start) &&
|
||||
(abs_ptr <= (uintptr_t)__wc_text_end))
|
||||
{
|
||||
abs_ptr = (uintptr_t)text_in + next_reloc + 4 + reloc_buf;
|
||||
#endif /* DEBUG_LINUXKM_PIE_SUPPORT */
|
||||
|
||||
switch (reloc_tag) {
|
||||
case WC_TEXT_TAG:
|
||||
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
|
||||
if ((abs_ptr >= (uintptr_t)__wc_text_start) &&
|
||||
(abs_ptr <= (uintptr_t)__wc_text_end))
|
||||
++n_text_r;
|
||||
else {
|
||||
reloc_tag = WC_OTHER_TAG;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
/* internal references in the .wolfcrypt.text segment don't need
|
||||
* normalization.
|
||||
*/
|
||||
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
|
||||
++n_text_r;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
/* for the various data segments, recognize dest addrs a few bytes
|
||||
* outside the segment -- the compiler occasionally generates these,
|
||||
* e.g. __wc_rwdata_start - 1 in DoInCoreCheck() in kernel 6.1 build of
|
||||
* FIPS v5, __wc_bss_start - 4 in kernel 4.4, and __wc_rodata_end + 26
|
||||
* in kernel 6.18.
|
||||
*/
|
||||
#ifndef LINUXKM_PIE_DATA_SLOP_MARGIN
|
||||
#define LINUXKM_PIE_DATA_SLOP_MARGIN 0x20
|
||||
#endif
|
||||
else if ((abs_ptr >= (uintptr_t)__wc_rodata_start - LINUXKM_PIE_DATA_SLOP_MARGIN) &&
|
||||
(abs_ptr <= (uintptr_t)__wc_rodata_end + LINUXKM_PIE_DATA_SLOP_MARGIN))
|
||||
{
|
||||
case WC_RODATA_TAG:
|
||||
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
|
||||
++n_rodata_r;
|
||||
if ((abs_ptr >= (uintptr_t)__wc_rodata_start - LINUXKM_PIE_DATA_SLOP_MARGIN) &&
|
||||
(abs_ptr <= (uintptr_t)__wc_rodata_end + LINUXKM_PIE_DATA_SLOP_MARGIN))
|
||||
++n_rodata_r;
|
||||
else
|
||||
reloc_tag = WC_OTHER_TAG;
|
||||
#endif
|
||||
reloc_buf -= (int)((uintptr_t)__wc_rodata_start - 1 -
|
||||
(uintptr_t)__wc_text_start);
|
||||
reloc_buf ^= WC_RODATA_TAG;
|
||||
}
|
||||
else if ((abs_ptr >= (uintptr_t)__wc_rwdata_start - LINUXKM_PIE_DATA_SLOP_MARGIN) &&
|
||||
(abs_ptr <= (uintptr_t)__wc_rwdata_end + LINUXKM_PIE_DATA_SLOP_MARGIN))
|
||||
{
|
||||
break;
|
||||
case WC_RWDATA_TAG:
|
||||
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
|
||||
++n_rwdata_r;
|
||||
if ((abs_ptr >= (uintptr_t)__wc_rwdata_start - LINUXKM_PIE_DATA_SLOP_MARGIN) &&
|
||||
(abs_ptr <= (uintptr_t)__wc_rwdata_end + LINUXKM_PIE_DATA_SLOP_MARGIN))
|
||||
++n_rwdata_r;
|
||||
else
|
||||
reloc_tag = WC_OTHER_TAG;
|
||||
#endif
|
||||
reloc_buf -= (int)((uintptr_t)__wc_rwdata_start - 1 -
|
||||
(uintptr_t)__wc_text_start);
|
||||
reloc_buf ^= WC_RWDATA_TAG;
|
||||
}
|
||||
else if ((abs_ptr >= (uintptr_t)__wc_bss_start - LINUXKM_PIE_DATA_SLOP_MARGIN) &&
|
||||
(abs_ptr <= (uintptr_t)__wc_bss_end + LINUXKM_PIE_DATA_SLOP_MARGIN))
|
||||
{
|
||||
break;
|
||||
case WC_BSS_TAG:
|
||||
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
|
||||
++n_bss_r;
|
||||
if ((abs_ptr >= (uintptr_t)__wc_bss_start - LINUXKM_PIE_DATA_SLOP_MARGIN) &&
|
||||
(abs_ptr <= (uintptr_t)__wc_bss_end + LINUXKM_PIE_DATA_SLOP_MARGIN))
|
||||
++n_bss_r;
|
||||
else
|
||||
reloc_tag = WC_OTHER_TAG;
|
||||
#endif
|
||||
reloc_buf -= (int)((uintptr_t)__wc_bss_start - 1 -
|
||||
(uintptr_t)__wc_text_start);
|
||||
reloc_buf ^= WC_BSS_TAG;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if (reloc_tag == WC_OTHER_TAG) {
|
||||
/* relocation referring to non-wolfcrypt segment -- these can only
|
||||
* be stabilized by zeroing them.
|
||||
*/
|
||||
@@ -1075,7 +1104,7 @@ ssize_t wc_linuxkm_normalize_relocations(
|
||||
pr_notice("found non-wolfcrypt relocation at text offset 0x%x to "
|
||||
"addr 0x%x, text=%x-%x, rodata=%x-%x, "
|
||||
"rwdata=%x-%x, bss=%x-%x\n",
|
||||
wc_linuxkm_pie_reloc_tab[i],
|
||||
wc_linuxkm_pie_reloc_tab[i] & WC_RELOC_OFFSET_MASK,
|
||||
(unsigned)(uintptr_t)abs_ptr,
|
||||
(unsigned)(uintptr_t)__wc_text_start,
|
||||
(unsigned)(uintptr_t)__wc_text_end,
|
||||
@@ -1467,8 +1496,8 @@ static int set_up_wolfssl_linuxkm_pie_redirect_table(void) {
|
||||
++i)
|
||||
if (*i == 0) {
|
||||
pr_err("ERROR: wolfCrypt container redirect table initialization was "
|
||||
"incomplete [%lu].\n",
|
||||
i-(unsigned long *)&wolfssl_linuxkm_pie_redirect_table);
|
||||
"incomplete [%u].\n",
|
||||
(unsigned)(i-(unsigned long *)&wolfssl_linuxkm_pie_redirect_table));
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -710,12 +710,17 @@ void fe_frombytes(fe h,const unsigned char *s)
|
||||
|
||||
void fe_invert(fe out,const fe z)
|
||||
{
|
||||
fe t0 = {0};
|
||||
fe t1 = {0};
|
||||
fe t2 = {0};
|
||||
fe t3 = {0};
|
||||
fe t0;
|
||||
fe t1;
|
||||
fe t2;
|
||||
fe t3;
|
||||
int i = 0;
|
||||
|
||||
XMEMSET(&t0, 0, sizeof(t0));
|
||||
XMEMSET(&t1, 0, sizeof(t1));
|
||||
XMEMSET(&t2, 0, sizeof(t2));
|
||||
XMEMSET(&t3, 0, sizeof(t3));
|
||||
|
||||
/* pow225521 */
|
||||
fe_sq(t0,z);
|
||||
fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1);
|
||||
@@ -1328,11 +1333,15 @@ void fe_sq2(fe h,const fe f)
|
||||
|
||||
void fe_pow22523(fe out,const fe z)
|
||||
{
|
||||
fe t0 = {0};
|
||||
fe t1 = {0};
|
||||
fe t2 = {0};
|
||||
fe t0;
|
||||
fe t1;
|
||||
fe t2;
|
||||
int i = 0;
|
||||
|
||||
XMEMSET(&t0, 0, sizeof(t0));
|
||||
XMEMSET(&t1, 0, sizeof(t1));
|
||||
XMEMSET(&t2, 0, sizeof(t2));
|
||||
|
||||
fe_sq(t0,z);
|
||||
fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1);
|
||||
fe_mul(t1,z,t1);
|
||||
|
||||
@@ -9824,8 +9824,8 @@ void ge_tobytes(unsigned char *s,const ge_p2 *h)
|
||||
* then curve25519() won't get its WOLFSSL_LOCAL attribute unless we dummy-call
|
||||
* it here.
|
||||
*/
|
||||
#if defined(WOLFSSL_API_PREFIX_MAP) && !defined(HAVE_CURVE25519) && \
|
||||
!defined(FREESCALE_LTC_ECC)
|
||||
#if defined(CURVED25519_ASM) && defined(WOLFSSL_API_PREFIX_MAP) && \
|
||||
!defined(HAVE_CURVE25519) && !defined(FREESCALE_LTC_ECC)
|
||||
WOLFSSL_LOCAL void _wc_curve25519_dummy(void);
|
||||
WOLFSSL_LOCAL void _wc_curve25519_dummy(void) {
|
||||
(void)curve25519((byte *)0, (byte *)0, (const byte *)0);
|
||||
|
||||
Reference in New Issue
Block a user