From f49e5837212a869df3fadba5d2bba85915d3a0f9 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Thu, 10 Jul 2025 00:57:51 -0500 Subject: [PATCH] linuxkm/Kbuild: skip "section(s) missed by containerization" test unless KERNEL_ARCH_X86; linuxkm/linuxkm_wc_port.h: fixes for legacy kernels, particularly: when building TLS stack (!WOLFCRYPT_ONLY), use the best heap with a functioning realloc(), else use kvmalloc() and friends if available, even if kvrealloc() is unavailable. also, provide for XMALLOC_USER and XMALLOC_OVERRIDE; linuxkm/lkcapi_glue.c: recognize the new CONFIG_CRYPTO_SELFTESTS_FULL alongside the old CONFIG_CRYPTO_MANAGER_EXTRA_TESTS; linuxkm/linuxkm_memory.c: restore my__show_free_areas() in case it's still needed. --- .wolfssl_known_macro_extras | 2 +- linuxkm/Kbuild | 1 + linuxkm/linuxkm_memory.c | 16 ++++ linuxkm/linuxkm_wc_port.h | 166 +++++++++++++++++++++++------------- linuxkm/lkcapi_glue.c | 9 +- 5 files changed, 129 insertions(+), 65 deletions(-) diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index 941708511..2eb737945 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -65,6 +65,7 @@ CONFIG_CRYPTO_GCM CONFIG_CRYPTO_HMAC CONFIG_CRYPTO_MANAGER CONFIG_CRYPTO_RSA +CONFIG_CRYPTO_SELFTESTS_FULL CONFIG_CRYPTO_SHA1 CONFIG_CRYPTO_SHA256 CONFIG_CRYPTO_SHA3 @@ -774,7 +775,6 @@ WOLFSSL_NO_KCAPI_SHA224 WOLFSSL_NO_OCSP_DATE_CHECK WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK WOLFSSL_NO_OCSP_OPTIONAL_CERTS -WOLFSSL_NO_PUBLIC_FFDHE WOLFSSL_NO_RSA_KEY_CHECK WOLFSSL_NO_SERVER_GROUPS_EXT WOLFSSL_NO_SESSION_STATS diff --git a/linuxkm/Kbuild b/linuxkm/Kbuild index 89d2199d1..e26818082 100644 --- a/linuxkm/Kbuild +++ b/linuxkm/Kbuild @@ -197,6 +197,7 @@ endif --rename-section .data.rel.local=.data.wolfcrypt \ --rename-section .bss=.bss.wolfcrypt "$$file" || exit $$? done + [ "$(KERNEL_ARCH_X86)" != "yes" ] || \ { $(READELF) --syms $(WOLFCRYPT_PIE_FILES) | \ $(AWK) -v obj="$(obj)" ' \ /File:/ { \ diff --git a/linuxkm/linuxkm_memory.c b/linuxkm/linuxkm_memory.c index b447e9843..f760eb239 100644 --- a/linuxkm/linuxkm_memory.c +++ b/linuxkm/linuxkm_memory.c @@ -21,6 +21,22 @@ /* included by wolfcrypt/src/memory.c */ +#if defined(__PIE__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)) +/* needed in 6.1+ because show_free_areas() static definition in mm.h calls + * __show_free_areas(), which isn't exported (neither was show_free_areas()). + */ +void my__show_free_areas( + unsigned int flags, + nodemask_t *nodemask, + int max_zone_idx) +{ + (void)flags; + (void)nodemask; + (void)max_zone_idx; + return; +} +#endif + #if defined(__PIE__) && defined(CONFIG_FORTIFY_SOURCE) /* needed because FORTIFY_SOURCE inline implementations call fortify_panic(). */ void __my_fortify_panic(const char *name) { diff --git a/linuxkm/linuxkm_wc_port.h b/linuxkm/linuxkm_wc_port.h index b1fbbe3bf..add45a080 100644 --- a/linuxkm/linuxkm_wc_port.h +++ b/linuxkm/linuxkm_wc_port.h @@ -91,6 +91,21 @@ #define HAVE_KVREALLOC #endif + #ifdef WOLFCRYPT_ONLY + #ifdef HAVE_KVMALLOC + #define USE_KVMALLOC + #endif + #ifdef HAVE_KVREALLOC + #define USE_KVREALLOC + #endif + #else + /* functioning realloc() is needed for the TLS stack. */ + #if defined(HAVE_KVMALLOC) && defined(HAVE_KVREALLOC) + #define USE_KVMALLOC + #define USE_KVREALLOC + #endif + #endif + /* kernel printf doesn't implement fp. */ #ifndef WOLFSSL_NO_FLOAT_FMT #define WOLFSSL_NO_FLOAT_FMT @@ -273,6 +288,52 @@ #endif /* !CONFIG_FORTIFY_SOURCE */ +#if defined(__PIE__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)) && \ + defined(CONFIG_X86) + /* linux/slab.h will recursively bring in linux/page-flags.h, polluting the + * wolfCrypt container objects with static functions const_folio_flags() and + * folio_flags(), unless we kludge it off thusly. + */ + #define PAGE_FLAGS_H +#endif + + #include + #include + #include + + #ifdef __PIE__ + /* without this, mm.h brings in static, but not inline, pmd_to_page(), + * with direct references to global vmem variables. + */ + #undef USE_SPLIT_PMD_PTLOCKS + #define USE_SPLIT_PMD_PTLOCKS 0 + + #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) + /* without this, static show_free_areas() mm.h brings in direct + * reference to unexported __show_free_areas(). + */ + #define __show_free_areas my__show_free_areas + void my__show_free_areas( + unsigned int flags, + nodemask_t *nodemask, + int max_zone_idx); + #endif + #endif + +#if !defined(__PIE__) || (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)) + #include +#endif + + #ifndef SINGLE_THREADED + #include + #endif +#ifndef __PIE__ + #include +#endif + #include + #include + #include + #ifdef LINUXKM_LKCAPI_REGISTER /* the LKCAPI assumes that expanded encrypt and decrypt keys will stay * loaded simultaneously, and the Linux in-tree implementations have two @@ -290,58 +351,32 @@ #ifndef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS #define WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS #endif + + #ifndef __PIE__ + #include + #include + #include + #include + #include + #include + #include + #include + #include + #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0) + #include + #endif /* linux ver >= 6.13 */ + #ifdef WOLFSSL_LINUXKM_USE_GET_RANDOM_KPROBES + #include + #endif + + #if defined(_LINUX_REFCOUNT_H) || defined(_LINUX_REFCOUNT_TYPES_H) + #define WC_LKM_REFCOUNT_TO_INT(refcount) (atomic_read(&(refcount.refs))) + #else + #define WC_LKM_REFCOUNT_TO_INT(refcount) (atomic_read(&(refcount))) + #endif + #endif /* !__PIE__ */ #endif /* LINUXKM_LKCAPI_REGISTER */ - #include -#ifndef __PIE__ - #include - #include -#endif - -#ifdef __PIE__ - /* linux/slab.h will recursively bring in linux/page-flags.h, polluting the - * wolfCrypt container objects with static functions const_folio_flags() and - * folio_flags(), unless we kludge it off thusly. - */ - #define PAGE_FLAGS_H -#else - #include -#endif - - #include - #include - -#ifndef __PIE__ - #ifndef SINGLE_THREADED - #include - #endif - #include - - #ifdef LINUXKM_LKCAPI_REGISTER - #include - #include - #include - #include - #include - #include - #include - #include - #include - #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0) - #include - #endif /* linux ver >= 6.13 */ - #ifdef WOLFSSL_LINUXKM_USE_GET_RANDOM_KPROBES - #include - #endif - - #if defined(_LINUX_REFCOUNT_H) || defined(_LINUX_REFCOUNT_TYPES_H) - #define WC_LKM_REFCOUNT_TO_INT(refcount) (atomic_read(&(refcount.refs))) - #else - #define WC_LKM_REFCOUNT_TO_INT(refcount) (atomic_read(&(refcount))) - #endif - #endif -#endif /* !__PIE__ */ - #if defined(WOLFSSL_AESNI) || defined(USE_INTEL_SPEEDUP) || \ defined(WOLFSSL_SP_X86_64_ASM) #ifndef CONFIG_X86 @@ -1171,6 +1206,13 @@ */ #define _MM_MALLOC_H_INCLUDED + #ifndef BUILDING_WOLFSSL + #include + #if defined(USE_KVMALLOC) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)) + #include + #endif + #endif + /* fun fact: since linux commit 59bb47985c, kmalloc with power-of-2 size is * aligned to the size. */ @@ -1182,10 +1224,10 @@ ((sizeof(_alloc_sz) * 8UL) - __builtin_clzl(_alloc_sz - 1)); \ _alloc_sz; \ }) - #ifdef HAVE_KVMALLOC + #ifdef USE_KVMALLOC #define malloc(size) kvmalloc_node(WC_LINUXKM_ROUND_UP_P_OF_2(size), (preempt_count() == 0 ? GFP_KERNEL : GFP_ATOMIC), NUMA_NO_NODE) #define free(ptr) kvfree(ptr) - #ifdef HAVE_KVREALLOC + #ifdef USE_KVREALLOC #define realloc(ptr, newsize) kvrealloc(ptr, WC_LINUXKM_ROUND_UP_P_OF_2(newsize), (preempt_count() == 0 ? GFP_KERNEL : GFP_ATOMIC)) #else #define realloc(ptr, newsize) ((void)(ptr), (void)(newsize), NULL) @@ -1212,15 +1254,17 @@ #endif #define XREALLOC(p, n, h, t) ({(void)(h); (void)(t); wolfSSL_Realloc(p, n);}) #else - #define XMALLOC(s, h, t) ({(void)(h); (void)(t); malloc(s);}) - #ifdef WOLFSSL_XFREE_NO_NULLNESS_CHECK - #define XFREE(p, h, t) ({(void)(h); (void)(t); free(p);}) - #else - #define XFREE(p, h, t) ({void* _xp; (void)(h); (void)(t); _xp = (p); if(_xp) free(_xp);}) - #endif - #if defined(HAVE_KVREALLOC) || !defined(HAVE_KVMALLOC) - #define XREALLOC(p, n, h, t) ({(void)(h); (void)(t); realloc(p, n);}) - #endif + #if !defined(XMALLOC_USER) && !defined(XMALLOC_OVERRIDE) + #define XMALLOC(s, h, t) ({(void)(h); (void)(t); malloc(s);}) + #ifdef WOLFSSL_XFREE_NO_NULLNESS_CHECK + #define XFREE(p, h, t) ({(void)(h); (void)(t); free(p);}) + #else + #define XFREE(p, h, t) ({void* _xp; (void)(h); (void)(t); _xp = (p); if(_xp) free(_xp);}) + #endif + #if defined(USE_KVREALLOC) || !defined(USE_KVMALLOC) + #define XREALLOC(p, n, h, t) ({(void)(h); (void)(t); realloc(p, n);}) + #endif + #endif /* !XMALLOC_USER && !XMALLOC_OVERRIDE */ #endif #include diff --git a/linuxkm/lkcapi_glue.c b/linuxkm/lkcapi_glue.c index 00609ed50..ea1880933 100644 --- a/linuxkm/lkcapi_glue.c +++ b/linuxkm/lkcapi_glue.c @@ -64,7 +64,8 @@ #define WOLFSSL_LINUXKM_LKCAPI_PRIORITY 100000 #endif -#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS +#if defined(CONFIG_CRYPTO_MANAGER_EXTRA_TESTS) || \ + defined(CONFIG_CRYPTO_SELFTESTS_FULL) static int disable_setkey_warnings = 0; #else #define disable_setkey_warnings 0 @@ -321,7 +322,8 @@ static int linuxkm_lkcapi_register(void) if (ret) return ret; -#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS +#if defined(CONFIG_CRYPTO_MANAGER_EXTRA_TESTS) || \ + defined(CONFIG_CRYPTO_SELFTESTS_FULL) /* temporarily disable warnings around setkey failures, which are expected * from the crypto fuzzer in FIPS configs, and potentially in others. * unexpected setkey failures are fatal errors returned by the fuzzer. @@ -692,7 +694,8 @@ static int linuxkm_lkcapi_register(void) #undef REGISTER_ALG #undef REGISTER_ALG_OPTIONAL -#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS +#if defined(CONFIG_CRYPTO_MANAGER_EXTRA_TESTS) || \ + defined(CONFIG_CRYPTO_SELFTESTS_FULL) disable_setkey_warnings = 0; #endif