From 6ee22de9991a6dfebc7f6861f6e1a7a211b2b43f Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 16 Jul 2024 14:24:37 -0500 Subject: [PATCH] linuxkm: initial support for cross-compilation. also, additional backward-compatibility measures around cp and clean recipe in linuxkm/Makefile. also, in sp_int.c, tweak DECL_DYN_SP_INT_ARRAY() to use an explicit XMEMSET() to clear n[], to avoid unshimmable implicit memset() from gcc on aarch64. --- Makefile.am | 3 ++- linuxkm/Kbuild | 24 +++++++++++++++------- linuxkm/Makefile | 46 ++++++++++++++++++++++++++++++++---------- wolfcrypt/src/sp_int.c | 8 +++++--- 4 files changed, 59 insertions(+), 22 deletions(-) diff --git a/Makefile.am b/Makefile.am index 50a072c31..1d4f26c6b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -207,7 +207,8 @@ if BUILD_LINUXKM SUBDIRS_OPT += linuxkm DIST_SUBDIRS_OPT += linuxkm - export KERNEL_ROOT KERNEL_ARCH KERNEL_EXTRA_CFLAGS \ + export build_triplet host_triplet CC AS LD \ + KERNEL_ROOT KERNEL_ARCH KERNEL_EXTRA_CFLAGS \ EXTRA_CFLAGS EXTRA_CPPFLAGS EXTRA_CCASFLAGS EXTRA_LDFLAGS \ AM_CPPFLAGS CPPFLAGS AM_CFLAGS CFLAGS \ AM_CCASFLAGS CCASFLAGS \ diff --git a/linuxkm/Kbuild b/linuxkm/Kbuild index fe677a29d..f29690481 100644 --- a/linuxkm/Kbuild +++ b/linuxkm/Kbuild @@ -18,7 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA -SHELL=/bin/bash +SHELL=bash ifeq "$(WOLFSSL_OBJ_FILES)" "" $(error $$WOLFSSL_OBJ_FILES is unset.) @@ -48,9 +48,17 @@ endif $(obj)/linuxkm/module_exports.o: $(WOLFSSL_OBJ_TARGETS) +ifndef KERNEL_THREAD_STACK_SIZE + ifdef CROSS_COMPILE + KERNEL_THREAD_STACK_SIZE=16384 + endif +endif + # this mechanism only works in kernel 5.x+ (fallback to hardcoded value) -hostprogs := linuxkm/get_thread_size -always-y := $(hostprogs) +ifndef KERNEL_THREAD_STACK_SIZE + hostprogs := linuxkm/get_thread_size + always-y := $(hostprogs) +endif HOST_EXTRACFLAGS += $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(KBUILD_CFLAGS) -static -fno-omit-frame-pointer @@ -63,8 +71,10 @@ endif # this rule is needed to get build to succeed in 4.x (get_thread_size still doesn't get built) $(obj)/linuxkm/get_thread_size: $(src)/linuxkm/get_thread_size.c -$(WOLFSSL_OBJ_TARGETS): | $(obj)/linuxkm/get_thread_size -KERNEL_THREAD_STACK_SIZE=$(shell test -x $(obj)/linuxkm/get_thread_size && $(obj)/linuxkm/get_thread_size || echo 16384) +ifndef KERNEL_THREAD_STACK_SIZE + $(WOLFSSL_OBJ_TARGETS): | $(obj)/linuxkm/get_thread_size + KERNEL_THREAD_STACK_SIZE=$(shell test -x $(obj)/linuxkm/get_thread_size && $(obj)/linuxkm/get_thread_size || echo 16384) +endif MAX_STACK_FRAME_SIZE=$(shell echo $$(( $(KERNEL_THREAD_STACK_SIZE) / 4))) libwolfssl-y := $(WOLFSSL_OBJ_FILES) linuxkm/module_hooks.o linuxkm/module_exports.o @@ -181,8 +191,8 @@ endif # exclude symbols that don't match wc_* or wolf*. $(obj)/linuxkm/module_exports.c: $(src)/module_exports.c.template $(WOLFSSL_OBJ_TARGETS) @cp $< $@ - @readelf --symbols --wide $(WOLFSSL_OBJ_TARGETS) | \ - awk '/^ *[0-9]+: / { \ + @$(READELF) --symbols --wide $(WOLFSSL_OBJ_TARGETS) | \ + $(AWK) '/^ *[0-9]+: / { \ if ($$8 !~ /^(wc_|wolf|WOLF|TLSX_)/){next;} \ if (($$4 == "FUNC") && ($$5 == "GLOBAL") && ($$6 == "DEFAULT")) { \ print "EXPORT_SYMBOL_NS_GPL(" $$8 ", WOLFSSL);"; \ diff --git a/linuxkm/Makefile b/linuxkm/Makefile index 2294d3412..a4adad90d 100644 --- a/linuxkm/Makefile +++ b/linuxkm/Makefile @@ -18,7 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA -SHELL=/bin/bash +SHELL=bash all: libwolfssl.ko libwolfssl.ko.signed @@ -58,20 +58,41 @@ endif export WOLFSSL_CFLAGS WOLFSSL_ASFLAGS WOLFSSL_OBJ_FILES WOLFCRYPT_PIE_FILES +ifneq "$(host_triplet)" "$(build_triplet)" + CROSS_COMPILE := 'CROSS_COMPILE=$(host_triplet)-' +endif + +OVERRIDE_PATHS := + +ifdef CC + ifneq "$(CC)" "cc" + OVERRIDE_PATHS := $(OVERRIDE_PATHS) 'CC=$(CC)' + endif +endif +ifdef AS + ifneq "$(AS)" "as" + OVERRIDE_PATHS := $(OVERRIDE_PATHS) 'AS=$(AS)' + endif +endif +ifdef LD + ifneq "$(LD)" "ld" + OVERRIDE_PATHS := $(OVERRIDE_PATHS) 'LD=$(LD)' + endif +endif + libwolfssl.ko: - @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 - @if test ! -h $(SRC_TOP)/Kbuild; then ln -s $(MODULE_TOP)/Kbuild $(SRC_TOP)/Kbuild; fi + @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: - @mkdir -p linuxkm - @cp --no-dereference --symbolic-link --no-clobber '$(MODULE_TOP)'/*.[ch] '$(MODULE_TOP)'/linuxkm/ - @cp --no-dereference --symbolic-link --no-clobber --recursive '$(SRC_TOP)'/wolfcrypt '$(MODULE_TOP)'/ - @cp --no-dereference --symbolic-link --no-clobber --recursive '$(SRC_TOP)'/src '$(MODULE_TOP)'/ + @mkdir -p '$(MODULE_TOP)/linuxkm' + @test '$(MODULE_TOP)/module_hooks.c' -ef '$(MODULE_TOP)/linuxkm/module_hooks.c' || cp --no-dereference --symbolic-link --no-clobber '$(MODULE_TOP)'/*.[ch] '$(MODULE_TOP)/linuxkm/' + @test '$(SRC_TOP)/wolfcrypt/src/wc_port.c' -ef '$(MODULE_TOP)/wolfcrypt/src/wc_port.c' || cp --no-dereference --symbolic-link --no-clobber --recursive '$(SRC_TOP)/wolfcrypt' '$(MODULE_TOP)/' + @test '$(SRC_TOP)/src/wolfio.c' -ef '$(MODULE_TOP)/src/wolfio.c' || cp --no-dereference --symbolic-link --no-clobber --recursive '$(SRC_TOP)/src' '$(MODULE_TOP)/' ifeq "$(ENABLED_LINUXKM_PIE)" "yes" - +$(MAKE) -C $(KERNEL_ROOT) M=$(MODULE_TOP) $(KBUILD_EXTRA_FLAGS) CC_FLAGS_FTRACE= + +$(MAKE) ARCH='$(KERNEL_ARCH)' $(OVERRIDE_PATHS) $(CROSS_COMPILE) -C '$(KERNEL_ROOT)' M='$(MODULE_TOP)' $(KBUILD_EXTRA_FLAGS) CC_FLAGS_FTRACE= else - +$(MAKE) -C $(KERNEL_ROOT) M=$(MODULE_TOP) $(KBUILD_EXTRA_FLAGS) + +$(MAKE) ARCH='$(KERNEL_ARCH)' $(OVERRIDE_PATHS) $(CROSS_COMPILE) -C '$(KERNEL_ROOT)' M='$(MODULE_TOP)' $(KBUILD_EXTRA_FLAGS) endif libwolfssl.ko.signed: libwolfssl.ko @@ -114,6 +135,9 @@ 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: + $(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 diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index b3ecab0ed..b1d18d554 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -210,9 +210,10 @@ This library provides single precision (SP) integer math functions. /* Declare a variable that will be assigned a value on XMALLOC. */ -#define DECL_DYN_SP_INT_ARRAY(n, s, c) \ - sp_int* n##d = NULL; \ - sp_int* (n)[c] = { NULL, } +#define DECL_DYN_SP_INT_ARRAY(n, s, c) \ + sp_int* n##d = NULL; \ + sp_int* (n)[c]; \ + void *n ## _dummy_var = XMEMSET(n, 0, sizeof(n)) /* DECL_SP_INT_ARRAY: Declare array of 'sp_int'. */ #if (defined(WOLFSSL_SMALL_STACK) || defined(SP_ALLOC)) && \ @@ -240,6 +241,7 @@ This library provides single precision (SP) integer math functions. */ #define ALLOC_DYN_SP_INT_ARRAY(n, s, c, err, h) \ do { \ + (void)n ## _dummy_var; \ if (((err) == MP_OKAY) && ((s) > SP_INT_DIGITS)) { \ (err) = MP_VAL; \ } \