Files
wolfssl/linuxkm/linuxkm-fips-hash-wrapper.sh
T
Daniel Pouzzner 29c5b02046 linuxkm/: finish support for stabilization of .rodata_wolfcrypt segment in WC_SYM_RELOC_TABLES (FIPS) kernel module builds:
linuxkm/Makefile: update the GENERATE_RELOC_TAB recipe to generate both wc_linuxkm_pie_text_reloc_tab[] and wc_linuxkm_pie_rodata_reloc_tab.

linuxkm/linuxkm-fips-hash-wrapper.sh: add handling for wc_linuxkm_pie_rodata_reloc_tab.

linuxkm/linuxkm-fips-hash.c: add handling for rodata_reloc_tab.*.

linuxkm/linuxkm_memory.c:
* refactor find_reloc_tab_offset() to be segment-agnostic and tolerate empty reloc tabs.
* refactor wc_reloc_normalize_segment():
  * to be segment-agnostic,
  * identify the src segment dynamically,
  * return BAD_FUNC_ARG where previously returning literal -1,
  * use seg_in_out_len arg to accommodate size skew between input and output (not currently used), and
  * rename working vars for better mnemonicitude.
* update wc_fips_generate_hash() to
  * handle seg_map->rodata_reloc_tab,
  * use new calling convention for wc_reloc_normalize_segment(), and
  * add wc_reloc_normalize_segment() loop for .rodata_wolfcrypt.

linuxkm/linuxkm_memory.h and linuxkm/linuxkm_wc_port.h: rename WOLFSSL_TEXT_SEGMENT_CANONICALIZER* to WOLFSSL_SEGMENT_CANONICALIZER*, with backward-compat provisions.

linuxkm/module_hooks.c:
* add wc_linuxkm_normalize_relocations_noresize() backward-compat wrapper.
* wolfssl_init(): add .rodata_wolfcrypt relocation handling alongside existing .text_wolfcrypt handling, and update for new wc_reloc_normalize_segment() calling convention.
* add seg_map.rodata_reloc_tab initialization.
* update wc_linuxkm_normalize_relocations() to be segment-agnostic and use new wc_reloc_normalize_segment() calling convention.
2026-04-28 12:58:32 -05:00

114 lines
4.2 KiB
Bash
Executable File

#!/bin/bash
# linuxkm-fips-hash-wrapper.sh -- Wrapper for linuxkm-fips-hash -- looks up the
# fencepost values using readelf, and assembles the argument list from them.
#
# Copyright (C) 2006-2026 wolfSSL Inc.
#
# This file is part of wolfSSL.
#
# wolfSSL is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# wolfSSL is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
set -o noclobber -o nounset -o pipefail -o errexit
mod_path=$1
shift
# require Gnu Awk, for strtonum().
if [[ -v AWK ]] && ! "$AWK" --version 2>&1 | grep -F -q 'GNU Awk'; then
unset AWK
fi
if [[ ! -v AWK ]]; then
if command -v gawk >/dev/null; then
AWK='gawk'
else
AWK='awk'
fi
fi
if ! "$AWK" --version 2>&1 | grep -F -q 'GNU Awk'; then
echo "Couldn't find required GNU Awk executable." >&2
exit 1
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_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_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";
}
/^Section Headers:/ {
in_sections = 1;
in_symbols = 0;
next;
}
/^Symbol table / {
if (! in_sections) {
print "symbol table appeared before section headers." >"/dev/stderr";
exit(1);
}
in_sections = 0;
in_symbols = 1;
next;
}
{
if (in_sections) {
if (match($0,
"^[[:space:]]*\\[([^]]+)\\][[:space:]]+\\.([^[:space:].]+)_wolfcrypt[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+([0-9a-f]+)[[:space:]]+([0-9a-f]+)[[:space:]]",
section_line_a)) {
segnum = strtonum(section_line_a[1]);
segname = section_line_a[2];
segstart = section_line_a[3];
segsize = section_line_a[4];
seg_starts_by_id[segnum] = strtonum("0x" segstart);
printf("--%s_start\n0x%x\n--%s_end\n0x%x\n", segname, strtonum("0x" segstart), segname, strtonum("0x" segstart) + strtonum("0x" segsize));
next;
}
}
if (in_symbols) {
if ($7 !~ "^[0-9]+$")
next;
if (($4 != "NOTYPE") && ($4 != "OBJECT") && ($4 != "FUNC"))
next;
if (! ($8 in fips_fenceposts))
next;
if (! ($7 in seg_starts_by_id)) {
print "segment offset missing for segment " $7 " for symbol " $8 "." >"/dev/stderr";
exit(1);
}
printf("--%s\n0x%x\n", fips_fenceposts[$8], seg_starts_by_id[$7] + strtonum("0x" $2));
if ($8 in singleton_ends)
printf("--%s\n0x%x\n", singleton_ends[$8], seg_starts_by_id[$7] + strtonum("0x" $2) + strtonum($3));
}
}')
./linuxkm-fips-hash "${fenceposts[@]}" --mod-path "$mod_path" --in-place "$@"