Skip to content

Commit 29c5b02

Browse files
committed
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.
1 parent 8b98f7f commit 29c5b02

7 files changed

Lines changed: 412 additions & 148 deletions

File tree

linuxkm/Makefile

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -157,30 +157,48 @@ GENERATE_SECTION_MAP := $(AWK) 'BEGIN { printf("") >ENVIRON["SECTION_MAP"]; } \
157157
}'
158158

159159
GENERATE_RELOC_TAB := $(AWK) ' \
160-
BEGIN { \
161-
n=0; \
160+
function open_seg(seg) { \
161+
seen_seg[seg] = 1; \
162+
printf("%s\n ", \
163+
"WOLFSSL_LOCAL const struct wc_reloc_table_ent wc_linuxkm_pie_" seg "_reloc_tab[] = { "); \
164+
cur_seg = seg; \
165+
} \
166+
function close_cur_seg() { \
167+
print " { .offset = ~0U, .dest_offset = ~0U, .dest_addend = 0, .dest_segment = WC_R_SEG_NONE, .reloc_type = WC_R_NONE } };"; \
168+
print "WOLFSSL_LOCAL const unsigned int wc_linuxkm_pie_" cur_seg "_reloc_tab_length = (unsigned int)(sizeof wc_linuxkm_pie_" cur_seg "_reloc_tab / sizeof wc_linuxkm_pie_" cur_seg "_reloc_tab[0]);"; \
169+
cur_seg = ""; \
170+
} \
171+
BEGIN { \
162172
bad_relocs=0; \
163173
print "\#include <wolfssl/wolfcrypt/libwolfssl_sources.h>"; \
164174
print "\#include <wolfssl/wolfcrypt/memory.h>"; \
165-
printf("%s\n ", \
166-
"WOLFSSL_LOCAL const struct wc_reloc_table_ent wc_linuxkm_pie_text_reloc_tab[] = { "); \
175+
print ""; \
167176
if ("SECTION_MAP" in ENVIRON) { \
168177
while (getline <ENVIRON["SECTION_MAP"] > 0) \
169178
section_map[$$1] = $$2; \
170179
close(ENVIRON["SECTION_MAP"]); \
171180
} \
172181
} \
173-
/^Relocation section '\''\.rela?\.text_wolfcrypt'\''/ { \
174-
p=1; \
175-
next; \
176-
} \
182+
\
177183
/^Relocation section/ { \
178-
p=0; \
184+
if (cur_seg) { \
185+
close_cur_seg(); \
186+
} \
187+
{ \
188+
if (match($$0, "^Relocation section '\''\\.rela?\\.(text|rodata)_wolfcrypt'\''", a)) {\
189+
open_seg(a[1]); \
190+
next; \
191+
} \
192+
} \
193+
} \
194+
\
195+
{ \
196+
if (! cur_seg) \
197+
next; \
179198
} \
180199
/^0/ { \
181-
if (p) { \
182-
if ($$3 !~ "^(R_X86_64_PLT32|R_X86_64_PC32|R_AARCH64_.*|R_ARM.*)$$") { \
183-
print "Unexpected relocation type:\n" $$0 >"/dev/stderr"; \
200+
if ($$3 !~ "^(R_X86_.*|R_AARCH64_.*|R_ARM.*)$$") { \
201+
print "Unexpected relocation type in " cur_seg ":\n" $$0 >"/dev/stderr"; \
184202
++bad_relocs; \
185203
} \
186204
if ($$5 in section_map) \
@@ -224,15 +242,22 @@ GENERATE_RELOC_TAB := $(AWK) ' \
224242
strtonum("0x" $$4), \
225243
$$6 strtonum("0x" $$7), \
226244
section_tag, reloc_type); \
227-
} \
228245
} \
229246
END { \
247+
if (cur_seg) { \
248+
close_cur_seg(); \
249+
} \
250+
n = split("text rodata", segs, " "); \
251+
for (i = 1; i <= n; ++i) { \
252+
if (! (segs[i] in seen_seg)) { \
253+
open_seg(segs[i]); \
254+
close_cur_seg(); \
255+
} \
256+
} \
230257
if (bad_relocs) { \
231258
print "Found " bad_relocs " unresolvable relocations." >"/dev/stderr"; \
232259
exit(1); \
233260
} \
234-
print " { .offset = ~0U, .dest_offset = ~0U, .dest_addend = 0, .dest_segment = WC_R_SEG_NONE, .reloc_type = WC_R_NONE } };"; \
235-
print "WOLFSSL_LOCAL const unsigned int wc_linuxkm_pie_text_reloc_tab_length = (unsigned int)(sizeof wc_linuxkm_pie_text_reloc_tab / sizeof wc_linuxkm_pie_text_reloc_tab[0]);"; \
236261
}'
237262

238263
ifeq "$(V)" "1"
@@ -384,7 +409,7 @@ $(MODULE_TOP)/libwolfssl-user-build/src/.libs/libwolfssl.so: $(LIBWOLFSSL_NAME).
384409
@ echo 'Using existing Makefile for libwolfssl.so.'
385410
@else
386411
@ echo -n 'Configuring user libwolfssl.so...'
387-
@ $(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)')
412+
@ $(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 -DDEBUG_LINUXKM_PIE_SUPPORT' $(if $(HOSTCC),CC='$(HOSTCC)')
388413
@ echo ' done.'
389414
@fi
390415
@echo -n 'Building user libwolfssl.so...'

linuxkm/linuxkm-fips-hash-wrapper.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,17 @@ readarray -t fenceposts < <(readelf --wide --sections --symbols "$mod_path" | "$
5050
BEGIN {
5151
fips_fenceposts["wc_linuxkm_pie_text_reloc_tab"] = "text_reloc_tab.start";
5252
fips_fenceposts["wc_linuxkm_pie_text_reloc_tab_length"] = "text_reloc_tab.len_start";
53+
fips_fenceposts["wc_linuxkm_pie_rodata_reloc_tab"] = "rodata_reloc_tab.start";
54+
fips_fenceposts["wc_linuxkm_pie_rodata_reloc_tab_length"] = "rodata_reloc_tab.len_start";
5355
fips_fenceposts["verifyCore"] = "verifyCore_start";
5456
fips_fenceposts["wolfCrypt_FIPS_first"] = "fips_text_start";
5557
fips_fenceposts["wolfCrypt_FIPS_last"] = "fips_text_end";
5658
fips_fenceposts["wolfCrypt_FIPS_ro_start"] = "fips_rodata_start";
5759
fips_fenceposts["wolfCrypt_FIPS_ro_end"] = "fips_rodata_end";
5860
singleton_ends["wc_linuxkm_pie_text_reloc_tab"] = "text_reloc_tab.end";
5961
singleton_ends["wc_linuxkm_pie_text_reloc_tab_length"] = "text_reloc_tab.len_end";
62+
singleton_ends["wc_linuxkm_pie_rodata_reloc_tab"] = "rodata_reloc_tab.end";
63+
singleton_ends["wc_linuxkm_pie_rodata_reloc_tab_length"] = "rodata_reloc_tab.len_end";
6064
singleton_ends["verifyCore"] = "verifyCore_end";
6165
}
6266

linuxkm/linuxkm-fips-hash.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ int main(int argc, char **argv)
108108
FENCEPOST_OPT(text_reloc_tab.end),
109109
FENCEPOST_OPT(text_reloc_tab.len_start),
110110
FENCEPOST_OPT(text_reloc_tab.len_end),
111+
FENCEPOST_OPT(rodata_reloc_tab.start),
112+
FENCEPOST_OPT(rodata_reloc_tab.end),
113+
FENCEPOST_OPT(rodata_reloc_tab.len_start),
114+
FENCEPOST_OPT(rodata_reloc_tab.len_end),
111115
FENCEPOST_OPT(fips_text_start),
112116
FENCEPOST_OPT(fips_text_end),
113117
FENCEPOST_OPT(rodata_start),
@@ -232,6 +236,10 @@ int main(int argc, char **argv)
232236
(seg_map.text_reloc_tab.end == ~0UL) ||
233237
(seg_map.text_reloc_tab.len_start == ~0UL) ||
234238
(seg_map.text_reloc_tab.len_end == ~0UL) ||
239+
(seg_map.rodata_reloc_tab.start == ~0UL) ||
240+
(seg_map.rodata_reloc_tab.end == ~0UL) ||
241+
(seg_map.rodata_reloc_tab.len_start == ~0UL) ||
242+
(seg_map.rodata_reloc_tab.len_end == ~0UL) ||
235243
(seg_map.fips_text_start == ~0UL) ||
236244
(seg_map.fips_text_end == ~0UL) ||
237245
(seg_map.rodata_start == ~0UL) ||
@@ -278,6 +286,17 @@ int main(int argc, char **argv)
278286
exit(1);
279287
}
280288

289+
if ((seg_map.rodata_reloc_tab.start >= seg_map.rodata_reloc_tab.end) ||
290+
(seg_map.rodata_reloc_tab.end >= (unsigned long)st.st_size) ||
291+
(seg_map.rodata_reloc_tab.len_start >= seg_map.rodata_reloc_tab.len_end) ||
292+
(seg_map.rodata_reloc_tab.len_end >= (unsigned long)st.st_size))
293+
{
294+
fprintf(stderr, "%s: supplied rodata_reloc_tab fencepost(s) are out of bounds "
295+
"for supplied module %s with length %lu.\n",
296+
progname, mod_path, (unsigned long)st.st_size);
297+
exit(1);
298+
}
299+
281300
mod_map = (byte *)mmap(NULL, st.st_size,
282301
inplace ? PROT_READ | PROT_WRITE : PROT_READ,
283302
(inplace ? MAP_SHARED : MAP_PRIVATE) | MAP_POPULATE,
@@ -296,6 +315,11 @@ int main(int argc, char **argv)
296315
seg_map.text_reloc_tab.len_start += (unsigned long)mod_map;
297316
seg_map.text_reloc_tab.len_end += (unsigned long)mod_map;
298317

318+
seg_map.rodata_reloc_tab.start += (unsigned long)mod_map;
319+
seg_map.rodata_reloc_tab.end += (unsigned long)mod_map;
320+
seg_map.rodata_reloc_tab.len_start += (unsigned long)mod_map;
321+
seg_map.rodata_reloc_tab.len_end += (unsigned long)mod_map;
322+
299323
seg_map.verifyCore_start += (unsigned long)mod_map;
300324
seg_map.verifyCore_end += (unsigned long)mod_map;
301325
seg_map.fips_text_start += (unsigned long)mod_map;

0 commit comments

Comments
 (0)