[PW_SID:1163150] [V2] powerpc/kasan: require memintrinsic prefix support for KASAN - #2645
Open
linux-riscv-bot wants to merge 1 commit into
Open
[PW_SID:1163150] [V2] powerpc/kasan: require memintrinsic prefix support for KASAN#2645linux-riscv-bot wants to merge 1 commit into
linux-riscv-bot wants to merge 1 commit into
Conversation
powerpc unconditionally selects GENERIC_ENTRY. The GENERIC_ENTRY
infrastructure relies on the compiler emitting __asan_mem*() calls at
instrumented mem*() sites rather than plain memset/memcpy/memmove, so
that entry/exit paths calling those functions are not instrumented.
This assumption is encoded in two places:
mm/kasan/shadow.c:
#if !defined(CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX) &&
!defined(CONFIG_GENERIC_ENTRY)
include/linux/fortify-string.h:
#if !defined(CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX) &&
!defined(CONFIG_GENERIC_ENTRY)
When GENERIC_ENTRY is set, both guards suppress the C wrappers for
memset/memcpy/memmove and the __underlying_mem*() redirections. This
is only safe when the compiler supports the prefixed __asan_mem*()
intrinsics. On older toolchains (e.g. GCC 9) that lack this support,
plain mem*() calls from instrumented code fall through to the raw
assembly implementations in mem_64.S / copy_32.S, completely bypassing
the KASAN shadow check.
Other arches with GENERIC_ENTRY (x86, s390, loongarch, riscv) do not
hit this because their CI toolchains are always new enough to support
the prefix flag.
Background: the !GENERIC_ENTRY guard was introduced by commit 69d4c0d
("entry, kasan, x86: Disallow overriding mem*() functions", Peter Zijlstra,
Jan 2023). The root problem is that the KASAN C wrappers override the
linker symbol memset/memcpy/memmove globally, so any call from noinstr or
__no_sanitize_address code (e.g. irqentry_enter/irqentry_exit) would still
reach the KASAN shadow-check wrapper -- at a point where KASAN invariants
may not hold. The compiler prefix approach (Marco Elver, Feb 2023,
commit 51287dc) solves this by having the compiler emit __asan_memset
at instrumented call sites and bare memset inside __no_sanitize_address
functions, splitting the decision at code-generation time rather than at
link time.
A manual C-level override cannot replicate this split: a single linker
symbol cannot be made to resolve differently depending on the caller.
x86 also placed its raw memset/memcpy/memmove implementations in
.noinstr.text (same commit, 69d4c0d), which is the other half of
the fix: noinstr callers hit the raw assembly directly, safely bypassing
KASAN. PowerPC has not done this. Placing mem_64.S / memcpy_64.S /
copy_32.S implementations in .noinstr.text would be the complementary
long-term fix that could re-enable KASAN on older toolchains, but it
requires care around linker stub overflow on large PPC64 kernels (the
same reason powerpc uses NOKPROBE_SYMBOL rather than noinstr for its
interrupt handlers -- see the comment in asm/interrupt.h). That work
is left as a follow-up.
For now, introduce PPC_CC_HAS_KASAN_MEMINTRINSIC_PREFIX, an arch-local
compiler probe that mirrors the same check as CC_HAS_KASAN_MEMINTRINSIC_PREFIX
in lib/Kconfig.kasan but lives outside the 'if KASAN' block to avoid a
recursive dependency (CC_HAS_KASAN_MEMINTRINSIC_PREFIX depends on KASAN
which depends on HAVE_ARCH_KASAN). Gate the three HAVE_ARCH_KASAN selects
on this new symbol so that KASAN is not offered as a config option on
toolchains that cannot support it correctly with GENERIC_ENTRY.
Since KASAN on powerpc now unconditionally implies
CC_HAS_KASAN_MEMINTRINSIC_PREFIX, the old !CC_HAS_KASAN_MEMINTRINSIC_PREFIX
code paths in asm/kasan.h and asm/string.h are dead. Clean them up:
- asm/kasan.h: remove the dual-entry-point variant of _GLOBAL_KASAN /
_GLOBAL_TOC_KASAN / EXPORT_SYMBOL_KASAN that emitted both memset and
__memset as entry points to the same assembly. These aliases were only
needed so the C KASAN wrappers in shadow.c could call __memset() to
reach raw memory ops; with the compiler prefix approach those wrappers
are not used for mem* on powerpc.
- asm/string.h: remove the separate __memset/__memcpy/__memmove symbol
declarations and the memset/memcpy/memmove macro redirections for
uninstrumented files that were needed on old toolchains. Simplify the
CONFIG_KASAN block to just the three #define aliases (still used by
shadow.c as raw backends to bypass KASAN checking).
- cputable.c, prom_init.c: the original comments said "use memcpy() so
GCC emits __memcpy() under KASAN". The real reason is that these run
pre-relocation: the destination pointer is PTRRELOC-adjusted to its
current physical address, and the kernel is loaded at a different
address than it was linked at. A struct assignment (*t = *s) may cause
the compiler to emit an implicit memcpy() call that resolves through
the unrelocated virtual symbol address -- before the MMU mapping is set
up -- jumping to garbage. An explicit memcpy(t, ...) uses the already-
corrected pointer and is safe. Update the comments accordingly.
Reported-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
Closes: https://lore.kernel.org/all/96dae110-f79b-4e54-8a9b-514369019b5d@linux.ibm.com
Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
Signed-off-by: Mukesh Kumar Chaurasiya (IBM) <mkchauras@gmail.com>
Signed-off-by: Linux RISC-V bot <linux.riscv.bot@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR for series 1163150 applied to workflow__riscv__fixes
Name: [V2] powerpc/kasan: require memintrinsic prefix support for KASAN
URL: https://patchwork.kernel.org/series/1163150/
Version: 2