Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .wolfssl_known_macro_extras
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,7 @@ WC_DILITHIUM_FIXED_ARRAY
WC_DISABLE_RADIX_ZERO_PAD
WC_FLAG_DONT_USE_AESNI
WC_FORCE_LINUXKM_FORTIFY_SOURCE
WC_LINUXKM_SUPPORT_DUMP_TO_FILE
WC_LMS_FULL_HASH
WC_NO_ASYNC_SLEEP
WC_NO_RNG_SIMPLE
Expand Down
2 changes: 1 addition & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ if BUILD_LINUXKM
FIPS_FLAVOR

module:
+$(MAKE) -C linuxkm libwolfssl.ko
+$(MAKE) -C linuxkm module

module-update-fips-hash:
+$(MAKE) -C linuxkm module-update-fips-hash
Expand Down
101 changes: 65 additions & 36 deletions linuxkm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ ifndef LIBWOLFSSL_NAME
LIBWOLFSSL_NAME := libwolfssl
endif

module: $(LIBWOLFSSL_NAME).ko

all: $(LIBWOLFSSL_NAME).ko $(LIBWOLFSSL_NAME).ko.signed

ifndef MODULE_TOP
Expand Down Expand Up @@ -249,6 +251,7 @@ $(LIBWOLFSSL_NAME).ko:
echo 'CPPFLAGS = "$(CPPFLAGS)"';
echo 'AM_CFLAGS = "$(AM_CFLAGS)"';
echo 'CFLAGS = "$(CFLAGS)"';
echo 'HOSTCFLAGS = "$(HOSTCFLAGS)"';
echo 'KERNEL_EXTRA_CFLAGS = "$(KERNEL_EXTRA_CFLAGS)"';
echo 'FIPS_OPTEST = "$(FIPS_OPTEST)"';
echo 'AM_CCASFLAGS = "$(AM_CCASFLAGS)"';
Expand All @@ -261,6 +264,7 @@ $(LIBWOLFSSL_NAME).ko:
echo 'host_triplet = "$(host_triplet)"';
echo 'build_triplet = "$(build_triplet)"';
echo 'CC = "$(CC)"';
echo 'HOSTCC = "$(HOSTCC)"';
echo 'AS = "$(AS)"';
echo 'LD = "$(LD)"';
echo 'READELF = "$(READELF)"';
Expand Down Expand Up @@ -302,21 +306,25 @@ ifeq "$(ENABLED_LINUXKM_PIE)" "yes"
@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=
# --no-silent works around make bug that otherwise leads to "No rule to make target 's'. Stop." (due to a bug around $(MAKEFLAGS)) in --quiet builds.
+$(MAKE) $(QFLAG) --no-print-directory --no-silent 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 [[ ! "$@" -nt "$$RELOC_TMP" ]]; then echo ' Module already up-to-date.'; exit 0; fi
@SECTION_MAP=$$(mktemp)
@trap 'rm "$$RELOC_TMP" "$$SECTION_MAP"' EXIT
@export SECTION_MAP
@$(READELF) --wide --sections --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=
+$(MAKE) $(QFLAG) --no-print-directory --no-silent ARCH='$(KERNEL_ARCH)' $(OVERRIDE_PATHS) $(CROSS_COMPILE) -C '$(KERNEL_ROOT)' M='$(MODULE_TOP)' $(KBUILD_EXTRA_FLAGS) CC_FLAGS_FTRACE=
@$(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)
# --no-silent works around make bug that otherwise leads to "No rule to make target 's'. Stop." (due to a bug around $(MAKEFLAGS)) in --quiet builds.
+$(MAKE) $(QFLAG) --no-print-directory --no-silent ARCH='$(KERNEL_ARCH)' $(OVERRIDE_PATHS) $(CROSS_COMPILE) -C '$(KERNEL_ROOT)' M='$(MODULE_TOP)' $(KBUILD_EXTRA_FLAGS)
endif

$(MODULE_TOP)/$(LIBWOLFSSL_NAME).ko: $(LIBWOLFSSL_NAME).ko

.PHONY: module-update-fips-hash
module-update-fips-hash: $(LIBWOLFSSL_NAME).ko
@set -e
Expand All @@ -335,7 +343,7 @@ module-update-fips-hash: $(LIBWOLFSSL_NAME).ko
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_NAME).ko.signed' ]]; then $(MAKE) -C . '$(LIBWOLFSSL_NAME).ko.signed'; fi
if [[ -f '$(LIBWOLFSSL_NAME).ko.signed' ]]; then $(MAKE) $(QFLAG) --no-print-directory --no-silent -C . '$(LIBWOLFSSL_NAME).ko.signed'; fi


# linuxkm-fips-hash implements offline (no-load) FIPS hash calculation and graft-in.
Expand All @@ -348,45 +356,61 @@ module-update-fips-hash: $(LIBWOLFSSL_NAME).ko
# depending on changes/config in the source directory. Also, aside from
# FIPS_FLAVOR, inherited configuration settings in the environment are cleansed.

libwolfssl-user-build/src/.libs/libwolfssl.so:
@set -e
@$(RM) -rf '$(MODULE_TOP)/libwolfssl-user-build'
@mkdir '$(MODULE_TOP)/libwolfssl-user-build'
FRESH_MAKEFLAGS := $(patsubst -j%,-j %,$(filter -%,$(filter-out -- --jobserver-auth=%,$(MAKEFLAGS))))
FRESH_ENV := env -i HOME="$$HOME" PATH="/usr/local/bin:/usr/bin:/bin:$$PATH" LANG="$${LANG-C.UTF-8}" LC_ALL="$${LC_ALL-C.UTF-8}" TERM="$${TERM-dumb}"

.PHONY: $(MODULE_TOP)/libwolfssl-user-build/src/.libs/libwolfssl.so
$(MODULE_TOP)/libwolfssl-user-build/src/.libs/libwolfssl.so: $(LIBWOLFSSL_NAME).ko
@set -o errexit -o pipefail
@if [[ '$(SRC_TOP)/configure' -nt '$@' ]]; then
@ echo 'Purging stale libwolfssl-user-build tree.'
@ $(RM) -rf '$(MODULE_TOP)/libwolfssl-user-build'
@fi
@mkdir -p '$(MODULE_TOP)/libwolfssl-user-build'
@cd '$(MODULE_TOP)/libwolfssl-user-build'
@pushd '$(SRC_TOP)' >/dev/null
@echo -n 'Populating tree of symlinks...'
@readarray -d '' -t srcfiles < <(find examples src support tests testsuite wolfcrypt wolfssl configure *.in build-aux debian rpm scripts certs doc mcapi cmake linuxkm/*.[ch] \( -name options.h -o -name user_settings\* \) -prune -o \( ! -type d \) \( -name '*.[chsSi]' -o -name configure -o -name '*.in' -o -name \*.sh -o -path support/\* -o -path build-aux/\* -o -path debian/\* -o -path rpm/\* -o -path scripts/\* -o -path certs/\* -o -path doc/\* -o -path mcapi/\* -o -path cmake/\* \) -print0)
@popd >/dev/null
@for file in "$${srcfiles[@]}"; do if [[ ! -e "$$file" ]]; then mkdir -p "$$(dirname "$$file")" && cp --no-dereference --symbolic-link --no-clobber '$(SRC_TOP)'/"$$file" "$$file"; fi; done
@echo ' done.'
@echo '__attribute__ ((visibility("default"))) extern const char coreKey[];' > user_settings.h
@echo > user_settings_asm.h
@echo -n 'Configuring libwolfssl.so...'
@unset WOLFSSL_CFLAGS WOLFCRYPT_PIE_FILES ASFLAGS_FPUSIMD_ENABLE ASFLAGS_FPU_DISABLE_SIMD_ENABLE src_libwolfssl_la_OBJECTS WOLFSSL_ASFLAGS AM_CFLAGS WOLFSSL_OBJ_FILES ENABLED_LINUXKM_LKCAPI_REGISTER EXTRA_LDFLAGS CC LD
@./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 [[ ! -e '$(MODULE_TOP)/libwolfssl-user-build/configure' ]]; then
@ pushd '$(SRC_TOP)' >/dev/null
@ echo -n 'Populating tree of symlinks for user libwolfssl.so build...'
@ readarray -t srcfiles < <(find examples src support tests testsuite wolfcrypt wolfssl configure *.in build-aux debian rpm scripts certs doc mcapi cmake linuxkm/*.[ch] \( -name options.h -o -name user_settings\* \) -prune -o \( ! -type d \) \( -name '*.[chsSi]' -o -name configure -o -name '*.in' -o -name \*.sh -o -path support/\* -o -path build-aux/\* -o -path debian/\* -o -path rpm/\* -o -path scripts/\* -o -path certs/\* -o -path doc/\* -o -path mcapi/\* -o -path cmake/\* \) -print)
@ popd >/dev/null
@ for file in "$${srcfiles[@]}"; do if [[ ! -e "$$file" ]]; then mkdir -p "$$(dirname "$$file")" && cp --no-dereference --symbolic-link --no-clobber '$(SRC_TOP)'/"$$file" "$$file"; fi; done
@ echo ' done.'
@fi
@if [[ ! -f user_settings.h ]]; then
@ echo '__attribute__ ((visibility("default"))) extern const char coreKey[];' > user_settings.h
@ echo > user_settings_asm.h
@fi
@if [[ -f Makefile ]]; then
@ 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))'
@ echo ' done.'
@fi
@echo -n 'Building user libwolfssl.so...'
@$(FRESH_ENV) $(MAKE) $(QFLAG) $(FRESH_MAKEFLAGS) >/dev/null
@echo ' done.'
@echo -n 'Compiling and linking libwolfssl.so...'
+$(MAKE) $(QFLAG) >/dev/null
@echo ' done.'
@echo -n 'Fixing FIPS hash...'
@userhash=$$(wolfcrypt/test/testwolfcrypt 2>&1 | sed -n -E 's/^hash = (.+)$$/\1/p')
@if [[ -z "$$userhash" ]]; then echo ' FIPS hash not found!' >&2; exit 1; fi
@find wolfcrypt/src -name '*fips_test*o' -delete
+$(MAKE) $(QFLAG) EXTRA_CFLAGS=-DWOLFCRYPT_FIPS_CORE_HASH_VALUE="$$userhash"
@echo ' done.'

linuxkm-fips-hash: libwolfssl-user-build/src/.libs/libwolfssl.so linuxkm-fips-hash.c
@echo -n 'Fixing FIPS hash in user libwolfssl.so...'
@if ! userhash=$$(wolfcrypt/test/testwolfcrypt 2>&1 | sed -n -E 's/^hash = (.+)$$/\1/p'); then
@ if [[ -z "$$userhash" ]]; then echo ' FIPS hash not found!' >&2; exit 1; fi
@ find wolfcrypt/src -name '*fips_test*o' -delete
@ $(FRESH_ENV) $(MAKE) $(QFLAG) $(FRESH_MAKEFLAGS) EXTRA_CFLAGS=-DWOLFCRYPT_FIPS_CORE_HASH_VALUE="$$userhash" >/dev/null
@ echo ' done.'
@else
@ @echo ' already matches (no update needed).'
@fi

linuxkm-fips-hash: $(MODULE_TOP)/libwolfssl-user-build/src/.libs/libwolfssl.so linuxkm-fips-hash.c
@set -e
@echo -n 'Compiling linuxkm-fips-hash...'
# note direct invocation of cc -- we are compiling for the build host, not the target host.
@cc -Wall -Wextra -O2 -I'$(MODULE_TOP)/libwolfssl-user-build' -o linuxkm-fips-hash linuxkm/linuxkm-fips-hash.c -L '$(MODULE_TOP)/libwolfssl-user-build/src/.libs' -Wl,-rpath-link='$(MODULE_TOP)/libwolfssl-user-build/src/.libs' -Wl,-rpath='$(MODULE_TOP)/libwolfssl-user-build/src/.libs' -lwolfssl
@$(or $(HOSTCC),cc) $(or $(HOSTCFLAGS),-Wall -Wextra -O2) -I'$(MODULE_TOP)/libwolfssl-user-build' -o linuxkm-fips-hash linuxkm/linuxkm-fips-hash.c -L '$(MODULE_TOP)/libwolfssl-user-build/src/.libs' -Wl,-rpath-link='$(MODULE_TOP)/libwolfssl-user-build/src/.libs' -Wl,-rpath='$(MODULE_TOP)/libwolfssl-user-build/src/.libs' -lwolfssl
@echo ' done.'

.PHONY: module-with-matching-fips-hash
module-with-matching-fips-hash: $(LIBWOLFSSL_NAME).ko linuxkm-fips-hash
@set -e
@./linuxkm-fips-hash-wrapper.sh "$<" $(QFLAG) $(VFLAG)
+$(MAKE) $(QFLAG) -C . '$(LIBWOLFSSL_NAME).ko.signed'
+$(MAKE) $(QFLAG) --no-print-directory --no-silent -C . '$(LIBWOLFSSL_NAME).ko.signed'

.PHONY: module-with-matching-fips-hash-no-sign
module-with-matching-fips-hash-no-sign: $(LIBWOLFSSL_NAME).ko linuxkm-fips-hash
Expand All @@ -406,7 +430,9 @@ else
;;
esac
done < .config
if [[ "$${CONFIG_MODULE_SIG}" = "y" && -n "$${CONFIG_MODULE_SIG_KEY}" && \
if [[ "$${CONFIG_MODULE_SIG}" != "y" ]]; then
echo ' [skipping $@ -- CONFIG_MODULE_SIG is unset in target kernel]'
elif [[ -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#\"}"
Expand All @@ -426,19 +452,22 @@ else
if [[ "$(quiet)" != "silent_" ]]; then
echo " Module $@ signed by $${CONFIG_MODULE_SIG_KEY}."
fi
elif [[ ! -f '$(MODULE_TOP)/$@' || '$(MODULE_TOP)/$<' -nt '$(MODULE_TOP)/$@' ]]; then
echo 'Unable to generate $@ from $<: CONFIG_MODULE_SIG_KEY and/or CONFIG_MODULE_SIG_HASH is missing.' >&2
exit 1
fi
endif


.PHONY: install modules_install
install modules_install:
+$(MAKE) -C $(KERNEL_ROOT) M=$(MODULE_TOP) src=$(SRC_TOP) INSTALL_MOD_DIR=wolfssl modules_install
+$(MAKE) $(QFLAG) --no-silent -C $(KERNEL_ROOT) M=$(MODULE_TOP) src=$(SRC_TOP) INSTALL_MOD_DIR=wolfssl modules_install

.PHONY: clean
# 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
+$(MAKE) $(QFLAG) --no-silent -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'
Expand Down
4 changes: 2 additions & 2 deletions linuxkm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@ libwolfssl: kernel global random_bytes handlers installed.
```

Additionally, `/proc/crypto` will advertise that the FIPS DRBG is installed at
highest priority "-with-global-replace":
highest priority, with "-wolfentropy" and/or "-rdseed", and "-with-global-replace":
```ini
name : stdrng
driver : sha2-256-drbg-nopr-wolfcrypt-fips-140-3-with-global-replace
driver : sha2-256-drbg-nopr-wolfentropy-wolfcrypt-fips-140-3-with-global-replace
module : libwolfssl
priority : 100000
refcnt : 2
Expand Down
26 changes: 13 additions & 13 deletions linuxkm/linuxkm_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,23 +354,23 @@ ssize_t wc_reloc_normalize_text(
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
if (reloc_buf >= seg_end - seg_beg) {
++n_oob_r;
RELOC_DEBUG_PRINTF("WARNING: normalized value is out of bounds (%s0x%lx) at index %ld, text offset 0x%x, reloc type %s, "
"dest seg .%s_wolfcrypt, offset from text to dest segment %s0x%lx, raw dest addr %s0x%lx, "
"seg span 0x%lx - 0x%lx, seg size 0x%lx, text base 0x%lx\n",
(sword64)reloc_buf < 0 ? "-" : "",
(sword64)reloc_buf < 0 ? -reloc_buf : reloc_buf,
i,
RELOC_DEBUG_PRINTF("WARNING: normalized value is out of bounds (%s0x%llx) at index %lld, text offset 0x%x, reloc type %s, "
"dest seg .%s_wolfcrypt, offset from text to dest segment %s0x%llx, raw dest addr %s0x%llx, "
"seg span 0x%llx - 0x%llx, seg size 0x%llx, text base 0x%llx\n",
(long long)reloc_buf < 0 ? "-" : "",
(long long)reloc_buf < 0 ? -(long long)reloc_buf : (long long)reloc_buf,
(long long)i,
next_reloc->offset,
layout->name,
seg_name,
seg_beg < seg_map->text_start ? "-" : "+",
seg_beg < seg_map->text_start ? (word64)seg_map->text_start - seg_beg : seg_beg - (word64)seg_map->text_start,
(layout->is_signed && ((sword64)raw_dest_addr < 0)) ? "-" : "",
(layout->is_signed && ((sword64)raw_dest_addr < 0)) ? (word64)-(sword64)raw_dest_addr : raw_dest_addr,
(word64)seg_beg,
(word64)seg_end,
(word64)(seg_end - seg_beg),
(word64)seg_map->text_start);
seg_beg < seg_map->text_start ? (unsigned long long)seg_map->text_start - seg_beg : seg_beg - (unsigned long long)seg_map->text_start,
(layout->is_signed && ((long long)raw_dest_addr < 0)) ? "-" : "",
(layout->is_signed && ((long long)raw_dest_addr < 0)) ? (unsigned long long)-(long long)raw_dest_addr : raw_dest_addr,
(unsigned long long)seg_beg,
(unsigned long long)seg_end,
(unsigned long long)(seg_end - seg_beg),
(unsigned long long)seg_map->text_start);
}
#endif
}
Expand Down
5 changes: 5 additions & 0 deletions linuxkm/linuxkm_wc_port.h
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@
#ifndef WC_CONTAINERIZE_THIS
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/delay.h>
#endif

Expand Down Expand Up @@ -508,6 +509,10 @@
#endif /* !WOLFCRYPT_ONLY */
#endif /* !WC_CONTAINERIZE_THIS */

#ifdef WC_LINUXKM_SUPPORT_DUMP_TO_FILE
#include <linux/fs.h>
#include <linux/uaccess.h>
#endif
#include <linux/slab.h>
#include <linux/sched.h>
#if __has_include(<linux/sched/task_stack.h>)
Expand Down
89 changes: 89 additions & 0 deletions linuxkm/module_hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,74 @@ WC_MAYBE_UNUSED static int linuxkm_lkcapi_sysfs_deinstall_node(struct kobj_attri
return 0;
}

#ifdef WC_LINUXKM_SUPPORT_DUMP_TO_FILE
static ssize_t dump_to_file(const char *path, const u8 *buf, size_t buf_len)
{
loff_t pos = 0;
struct file *fp;
ssize_t ret;
char tmp;

if (buf_len == 0) {
pr_info("libwolfssl: dump_to_file() called with buf_len == 0. Not dumping.\n");
return 0;
}

WC_SANITIZE_DISABLE();
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,8,0)
ret = probe_kernel_read(&tmp, buf, 1);
if (ret == 0)
ret = probe_kernel_read(&tmp, buf + buf_len - 1, 1);
#else
ret = copy_from_kernel_nofault(&tmp, buf, 1);
if (ret == 0)
ret = copy_from_kernel_nofault(&tmp, buf + buf_len - 1, 1);
#endif
WC_SANITIZE_ENABLE();
if (ret != 0) {
pr_err("libwolfssl: cannot safely read from buffer %px: %d\n", buf, (int)ret);
return ret;
}

fp = filp_open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (IS_ERR(fp)) {
pr_err("libwolfssl: cannot open %s: %ld\n", path, PTR_ERR(fp));
return PTR_ERR(fp);
}

WC_SANITIZE_DISABLE();
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
/* kernel_write() exported by 7bb307e894d51 */
ret = kernel_write(fp, buf, buf_len, &pos);
#else
ret = vfs_write(fp, buf, buf_len, &pos);
#endif
WC_SANITIZE_ENABLE();

filp_close(fp, NULL);

if (ret < 0)
pr_err("libwolfssl: write to %s failed: %zd\n", path, ret);
else if ((size_t)ret != buf_len)
pr_warn("libwolfssl: short write to %s: %zd of %zu bytes\n", path, ret, buf_len);

return ret;
}

static char *text_dump_path;
static char *rodata_dump_path;

/* indent these so they don't look like flush-left function calls. */
module_param(text_dump_path, charp, 0444);
module_param(rodata_dump_path, charp, 0444);

MODULE_PARM_DESC(text_dump_path,
"Path to dump live .wolfcrypt_text section to (e.g. /tmp/wc_text.bin)");
MODULE_PARM_DESC(rodata_dump_path,
"Path to dump live .wolfcrypt_rodata section to (e.g. /tmp/wc_rodata.bin)");

#endif /* WC_LINUXKM_SUPPORT_DUMP_TO_FILE */

#ifdef HAVE_FIPS
static ssize_t FIPS_rerun_self_test_handler(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t count);
Expand Down Expand Up @@ -503,6 +571,27 @@ static int wolfssl_init(void)
return ret;
#endif

#ifdef WC_LINUXKM_SUPPORT_DUMP_TO_FILE

#ifdef WC_SYM_RELOC_TABLES
if (text_dump_path) {
if (dump_to_file(text_dump_path, (u8 *)__wc_text_start, (size_t)((uintptr_t)__wc_text_end - (uintptr_t)__wc_text_start)) == 0)
pr_info("libwolfssl: dumped .wolfcrypt_text (%zu bytes) to %s.\n", (size_t)((uintptr_t)__wc_text_end - (uintptr_t)__wc_text_start), text_dump_path);
}
if (rodata_dump_path) {
if (dump_to_file(rodata_dump_path, (u8 *)__wc_rodata_start, (size_t)(__wc_rodata_end - __wc_rodata_start)) == 0)
pr_info("libwolfssl: dumped .wolfcrypt_rodata (%zu bytes) to %s.\n", (size_t)((uintptr_t)__wc_rodata_end - (uintptr_t)__wc_rodata_start), text_dump_path);
}
#else
if ((text_dump_path != NULL) ||
(rodata_dump_path != NULL))
{
pr_info("libwolfssl: ignoring module dump path argument(s) -- module lacks WC_SYM_RELOC_TABLES.\n");
}
#endif

#endif /* WC_LINUXKM_SUPPORT_DUMP_TO_FILE */

#ifdef WC_LINUXKM_TEST_INET_PTON
{
const char *src;
Expand Down
Loading