The major differences since v5 [4]: - one can now tune the number of functions per each section to achieve the preferable vmlinux size or protection level. Default is still as one section per function. This can be handy for storage-constrained systems. 4-8 fps are still strong, but reduce the size of the final vmlinu{x,z} significantly (see the comparison below); - don't use orphan sections anymore. It's not reliable at all / may differ from linker to linker, and also conflicts with CONFIG_LD_ORPHAN_WARN which is great for catching random bugs -> - all the .text.* sections are now being described explicitly in the linker script. A Perl script is used to take the original LDS, the original object file, read a list of input sections from it and generate the resulting LDS. This costs a bit of linking time as LD tends to think hard when processing scripts > 1 Mb (a subject for future BFD and LLD patches). It adds about 60-80 seconds to the whole linking process (BTF step, 2-3 kallsyms steps and the final step), but "better safe than sorry". In addition, that approach allows to reserve some space at the end of text (8-12 Kb, no impact on vmlinux size as THP-aligned (2 Mb) rodata goes right after it) and add some link-time assertions -> - input .text section now must be empty, otherwise the linkage will be stopped. This is implemented by the size assertion in the resulting LD script and is designed to plug the potentional layout leakage. This also means that -> - "regular" ASM functions are now being placed into unique separate functions the same way compiler does this for C functions. This is achieved by hijacking the commonly used macros. The symbol name is now being taken as a base for its new section name. This gives a better opportunity to LTO, DCE and FG-KASLR, as ASM code can now also be randomized or garbage-collected; - it's now fully compatible with ClangLTO, ClangCFI, CONFIG_LD_ORPHAN_WARN and some all the rest stuff landed since the last revision has been published; - `-z unique-symbol` linker flag is now used to ensure livepatching works even with randomized sections. Position-based search is not needed in this case; - kallsyms are now being shuffled and displayed in random order not only when FG-KASLR is enabled, but all the time (for unpriviledged access); - tons of code were improved and deduplicated all over the place. Changes in v5: -------------- * fixed a bug in the code which increases boot heap size for CONFIG_FG_KASLR which prevented the boot heap from being increased for CONFIG_FG_KASLR when using bzip2 compression. Thanks to Andy Lavr for finding the problem and identifying the solution. * changed the adjustment of the orc_unwind_ip table at boot time to disregard relocs associated with this table, and instead inspect the entries separately. Relocs are not able to be used since they are no longer correct once the table is resorted at buildtime. * changed how orc_unwind_ip addresses in randomized sections are identified to include the byte immediately after the end of the section. * updated module code to use kvmalloc/kvfree based on suggestions from Evgenii Shatokhin <eshatokhin@xxxxxxxxxxxxx>. * changed kernel commandline to disable fgkaslr to simply "nofgkaslr" to match the nokaslr option. fgkaslr="X" can be added at a later date if it is needed. * Added a patch to force livepatch to require symbols to be unique if using while fgkaslr either for core or modules. Changes in v4: ------------- * dropped the patch to split out change to STATIC definition in x86/boot/compressed/misc.c and replaced with a patch authored by Kees Cook to avoid the duplicate malloc definitions * Added a section to Documentation/admin-guide/kernel-parameters.txt to document the fgkaslr boot option. * redesigned the patch to hide the new layout when reading /proc/kallsyms. The previous implementation utilized a dynamically allocated linked list to display the kernel and module symbols in alphabetical order. The new implementation uses a randomly shuffled index array to display the kernel and module symbols in a random order. Changes in v3: ------------- * Makefile changes to accommodate CONFIG_LD_DEAD_CODE_DATA_ELIMINATION * removal of extraneous ALIGN_PAGE from _etext changes * changed variable names in x86/tools/relocs to be less confusing * split out change to STATIC definition in x86/boot/compressed/misc.c * Updates to Documentation to make it more clear what is preserved in .text * much more detailed commit message for function granular KASLR patch * minor tweaks and changes that make for more readable code * this cover letter updated slightly to add additional details Changes in v2: -------------- * Fix to address i386 build failure * Allow module reordering patch to be configured separately so that arm (or other non-x86_64 arches) can take advantage of module function reordering. This support has not be tested by me, but smoke tested by Ard Biesheuvel <ardb@xxxxxxxxxx> on arm. * Fix build issue when building on arm as reported by Ard Biesheuvel <ardb@xxxxxxxxxx> The series is also available here: [5] [0] https://dl.acm.org/doi/pdf/10.5555/3049832.3049858 [1] https://lore.kernel.org/linux-hardening/20211223002209.1092165-1-alexandr.lobakin@xxxxxxxxx [2] https://lore.kernel.org/linux-hardening/20211202223214.72888-1-alexandr.lobakin@xxxxxxxxx [3] https://lore.kernel.org/linux-hardening/20210831144114.154-1-alexandr.lobakin@xxxxxxxxx [4] https://lore.kernel.org/kernel-hardening/20200923173905.11219-1-kristen@xxxxxxxxxxxxxxx [5] https://github.com/alobakin/linux/pull/3 Alexander Lobakin (9): modpost: fix removing numeric suffixes livepatch: avoid position-based search if `-z unique-symbol` is available arch: introduce asm function sections x86: support asm function sections x86: decouple ORC table sorting into a separate file FG-KASLR: use a scripted approach to handle .text.* sections x86/boot: allow FG-KASLR to be selected module: use a scripted approach for FG-KASLR maintainers: add MAINTAINERS entry for FG-KASLR Kristen Carlson Accardi (6): kallsyms: randomize /proc/kallsyms output order Makefile: add config options and build scripts for FG-KASLR x86/tools: Add relative relocs for randomized functions x86: Add support for function granular KASLR module: add arch-indep FG-KASLR for randomizing function layout Documentation: add documentation for FG-KASLR .gitignore | 1 + .../admin-guide/kernel-parameters.txt | 6 + Documentation/security/fgkaslr.rst | 172 ++++ Documentation/security/index.rst | 1 + MAINTAINERS | 12 + Makefile | 41 +- arch/Kconfig | 10 + arch/x86/Kconfig | 2 + arch/x86/boot/Makefile | 1 + arch/x86/boot/compressed/.gitignore | 1 + arch/x86/boot/compressed/Makefile | 21 +- arch/x86/boot/compressed/fgkaslr.c | 752 ++++++++++++++++++ arch/x86/boot/compressed/gen-symbols.h | 30 + arch/x86/boot/compressed/head_32.S | 2 +- arch/x86/boot/compressed/head_64.S | 32 +- arch/x86/boot/compressed/misc.c | 144 +++- arch/x86/boot/compressed/misc.h | 28 + arch/x86/boot/compressed/utils.c | 16 + arch/x86/boot/pmjump.S | 2 +- arch/x86/crypto/aesni-intel_asm.S | 4 +- arch/x86/crypto/poly1305-x86_64-cryptogams.pl | 4 + arch/x86/include/asm/boot.h | 13 +- arch/x86/include/asm/orc_types.h | 7 + arch/x86/include/asm/paravirt.h | 2 + arch/x86/include/asm/qspinlock_paravirt.h | 2 + arch/x86/kernel/head_32.S | 4 +- arch/x86/kernel/head_64.S | 4 +- arch/x86/kernel/kprobes/core.c | 2 + arch/x86/kernel/kvm.c | 2 + arch/x86/kernel/relocate_kernel_32.S | 10 +- arch/x86/kernel/relocate_kernel_64.S | 12 +- arch/x86/kernel/unwind_orc.c | 63 +- arch/x86/kernel/vmlinux.lds.S | 8 +- arch/x86/kvm/emulate.c | 7 +- arch/x86/lib/Makefile | 3 + arch/x86/lib/copy_user_64.S | 2 +- arch/x86/lib/error-inject.c | 2 + arch/x86/lib/getuser.S | 5 +- arch/x86/lib/memcpy_64.S | 4 +- arch/x86/lib/memmove_64.S | 5 +- arch/x86/lib/memset_64.S | 5 +- arch/x86/lib/orc.c | 78 ++ arch/x86/lib/putuser.S | 2 +- arch/x86/power/hibernate_asm_32.S | 10 +- arch/x86/power/hibernate_asm_64.S | 10 +- arch/x86/tools/relocs.c | 32 +- arch/x86/tools/relocs.h | 4 +- arch/x86/tools/relocs_common.c | 14 +- include/asm-generic/vmlinux.lds.h | 57 +- include/linux/linkage.h | 121 ++- include/linux/random.h | 16 + include/uapi/linux/elf.h | 1 + init/Kconfig | 69 ++ kernel/kallsyms.c | 94 ++- kernel/livepatch/core.c | 17 +- kernel/module.c | 73 +- scripts/Makefile.modfinal | 20 +- scripts/generate_text_sections.pl | 172 ++++ scripts/link-vmlinux.sh | 30 +- scripts/mod/modpost.c | 48 +- scripts/module.lds.S | 14 +- scripts/sorttable.h | 5 - tools/arch/x86/include/asm/orc_types.h | 7 + 63 files changed, 2122 insertions(+), 216 deletions(-) create mode 100644 Documentation/security/fgkaslr.rst create mode 100644 arch/x86/boot/compressed/fgkaslr.c create mode 100644 arch/x86/boot/compressed/gen-symbols.h create mode 100644 arch/x86/boot/compressed/utils.c create mode 100644 arch/x86/lib/orc.c create mode 100755 scripts/generate_text_sections.pl -- 2.34.1