From nobody Thu Apr 2 00:13:50 2026 Received: from mail-24416.protonmail.ch (mail-24416.protonmail.ch [109.224.244.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 71C572E6CC7 for ; Mon, 30 Mar 2026 14:33:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=109.224.244.16 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881200; cv=none; b=aejFkUnl9PoYa3avfTi+PGZ0+Kg0U5CI+hm+jZqVDf/Sc8e7NS1+si/tBwKvtWLQmptwOdbt8GR8I2VaZRP5hX8t8sQrw5E9AAXKQHIZQGQ8wzSTwU0VHTB6AeEOfOksHatp5m0+G0D29WcVnKaweygSxUrALOZUJES6iIGeWIw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881200; c=relaxed/simple; bh=lIPHP5gY0fAKE4GTdM35WsqbG+6mf2fmxNaBrU5gygw=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=kXr55C4EW9FQr22xCUBNSUYYlVCS7d7uMC66vAUZn+EUitmSC5wyVxM+Cv9hdwxfl94v6G8ZIR/EdSGdzdJjyhHutFhB9cvPnGHUtPBmoYjh/3C1G9HRDdBvbJa5MlsiQBRzTDcq/XeUYa6ojACSooFDDSH0HBmyTKMtozmRlNY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me; spf=pass smtp.mailfrom=pm.me; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b=kt1RTrdd; arc=none smtp.client-ip=109.224.244.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pm.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b="kt1RTrdd" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1774881190; x=1775140390; bh=jVsC+rspioS0w86d9U8mtCfZpTXD4fMS7/g1bcI2b7A=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=kt1RTrddpYQQJdv+yx0oYChQW4qrPJGn0+wGIYJd4Ympw8DhOcXUHy2/DcL7cSY3w 6aExOe+pEz7KcRIegYu0F0ySYtAuuuM36x7MImGqiX+dWF13bmQhzWtlLWsuw0KXMU e2QM28Ad0tteuGY1T5+N//Sj3WnQezxGmYemOSsaEQYoCXa8aNxOi/+OTVyNZSDuiU GvhkWvy4e75STELDNz9jwUeuIxCfPe0LmH12ne1DCi+T/jPRXD6ei2aCmg1yADrCv3 W/cjar+ReN+0QMxZlgZ5YGDQ/u1xBKxF3xzETujpLMSRrgeUvbd2CRual9sMUApHqH aV2LhSE3XgxDQ== Date: Mon, 30 Mar 2026 14:33:05 +0000 To: Catalin Marinas , Will Deacon , Jonathan Corbet , Shuah Khan , Andrey Ryabinin , Alexander Potapenko , Andrey Konovalov , Dmitry Vyukov , Vincenzo Frascino , Andrew Morton , Jan Kiszka , Kieran Bingham , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt From: Maciej Wieczor-Retman Cc: m.wieczorretman@pm.me, Samuel Holland , Maciej Wieczor-Retman , linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, kasan-dev@googlegroups.com, workflows@vger.kernel.org, linux-mm@kvack.org, llvm@lists.linux.dev Subject: [PATCH v12 01/15] kasan: sw_tags: Use arithmetic shift for shadow computation Message-ID: In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: a0e6649a43bc470d0d645b061def5e8973771c8d Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Samuel Holland Currently, kasan_mem_to_shadow() uses a logical right shift, which turns canonical kernel addresses into non-canonical addresses by clearing the high KASAN_SHADOW_SCALE_SHIFT bits. The value of KASAN_SHADOW_OFFSET is then chosen so that the addition results in a canonical address for the shadow memory. For KASAN_GENERIC, this shift/add combination is ABI with the compiler, because KASAN_SHADOW_OFFSET is used in compiler-generated inline tag checks[1], which must only attempt to dereference canonical addresses. However, for KASAN_SW_TAGS there is some freedom to change the algorithm without breaking the ABI. Because TBI is enabled for kernel addresses, the top bits of shadow memory addresses computed during tag checks are irrelevant, and so likewise are the top bits of KASAN_SHADOW_OFFSET. This is demonstrated by the fact that LLVM uses a logical right shift in the tag check fast path[2] but a sbfx (signed bitfield extract) instruction in the slow path[3] without causing any issues. Use an arithmetic shift in kasan_mem_to_shadow() as it provides a number of benefits: 1) The memory layout doesn't change but is easier to understand. KASAN_SHADOW_OFFSET becomes a canonical memory address, and the shifted pointer becomes a negative offset, so KASAN_SHADOW_OFFSET =3D=3D KASAN_SHADOW_END regardless of the shift amount or the size of the virtual address space. 2) KASAN_SHADOW_OFFSET becomes a simpler constant, requiring only one instruction to load instead of two. Since it must be loaded in each function with a tag check, this decreases kernel text size by 0.5%. 3) This shift and the sign extension from kasan_reset_tag() can be combined into a single sbfx instruction. When this same algorithm change is applied to the compiler, it removes an instruction from each inline tag check, further reducing kernel text size by an additional 4.6%. These benefits extend to other architectures as well. On RISC-V, where the baseline ISA does not shifted addition or have an equivalent to the sbfx instruction, loading KASAN_SHADOW_OFFSET is reduced from 3 to 2 instructions, and kasan_mem_to_shadow(kasan_reset_tag(addr)) similarly combines two consecutive right shifts. Link: https://github.com/llvm/llvm-project/blob/llvmorg-20-init/llvm/lib/Tr= ansforms/Instrumentation/AddressSanitizer.cpp#L1316 [1] Link: https://github.com/llvm/llvm-project/blob/llvmorg-20-init/llvm/lib/Tr= ansforms/Instrumentation/HWAddressSanitizer.cpp#L895 [2] Link: https://github.com/llvm/llvm-project/blob/llvmorg-20-init/llvm/lib/Ta= rget/AArch64/AArch64AsmPrinter.cpp#L669 [3] Signed-off-by: Samuel Holland Co-developed-by: Maciej Wieczor-Retman Signed-off-by: Maciej Wieczor-Retman --- Changelog v11: (Maciej) - Remove the arch_kasan_non_canonical_hook() scheme in favor of Andrey Ryabinin's much nicer simple implementation. Changelog v10: (Maciej) - Update the Documentation/dev-tools/kasan.rst file with the changed kasan_mem_to_shadow(). Changelog v9: (Maciej) - Take out the arm64 related code from mm/kasan/report.c and put it in the arch specific directory in a new file so the kasan_mem_to_shadow() function can be included. - Reset addr tag bits in arm64's arch_kasan_non_canonical_hook() so the inline mode can also work with that function (Andrey Ryabinin). - Fix incorrect number of zeros in a comment in mm/kasan/report.c. - Remove Catalin's acked-by since changes were made. Changelog v7: (Maciej) - Change UL to ULL in report.c to fix some compilation warnings. Changelog v6: (Maciej) - Add Catalin's acked-by. - Move x86 gdb snippet here from the last patch. Changelog v5: (Maciej) - (u64) -> (unsigned long) in report.c Changelog v4: (Maciej) - Revert x86 to signed mem_to_shadow mapping. - Remove last two paragraphs since they were just poorer duplication of the comments in kasan_non_canonical_hook(). Changelog v3: (Maciej) - Fix scripts/gdb/linux/kasan.py so the new signed mem_to_shadow() is reflected there. - Fix Documentation/arch/arm64/kasan-offsets.sh to take new offsets into account. - Made changes to the kasan_non_canonical_hook() according to upstream discussion. Settled on overflow on both ranges and separate checks for x86 and arm. Changelog v2: (Maciej) - Correct address range that's checked in kasan_non_canonical_hook(). Adjust the comment inside. - Remove part of comment from arch/arm64/include/asm/memory.h. - Append patch message paragraph about the overflow in kasan_non_canonical_hook(). Documentation/arch/arm64/kasan-offsets.sh | 8 ++++++-- Documentation/dev-tools/kasan.rst | 18 ++++++++++++------ arch/arm64/Kconfig | 10 +++++----- arch/arm64/include/asm/memory.h | 14 +++++++++++++- arch/arm64/mm/kasan_init.c | 7 +++++-- include/linux/kasan.h | 10 ++++++++-- mm/kasan/report.c | 16 ++++++++++++---- scripts/gdb/linux/kasan.py | 5 ++++- scripts/gdb/linux/mm.py | 5 +++-- 9 files changed, 68 insertions(+), 25 deletions(-) diff --git a/Documentation/arch/arm64/kasan-offsets.sh b/Documentation/arch= /arm64/kasan-offsets.sh index 2dc5f9e18039..ce777c7c7804 100644 --- a/Documentation/arch/arm64/kasan-offsets.sh +++ b/Documentation/arch/arm64/kasan-offsets.sh @@ -5,8 +5,12 @@ =20 print_kasan_offset () { printf "%02d\t" $1 - printf "0x%08x00000000\n" $(( (0xffffffff & (-1 << ($1 - 1 - 32))) \ - - (1 << (64 - 32 - $2)) )) + if [[ $2 -ne 4 ]] then + printf "0x%08x00000000\n" $(( (0xffffffff & (-1 << ($1 - 1 - 32))) \ + - (1 << (64 - 32 - $2)) )) + else + printf "0x%08x00000000\n" $(( (0xffffffff & (-1 << ($1 - 1 - 32))) )) + fi } =20 echo KASAN_SHADOW_SCALE_SHIFT =3D 3 diff --git a/Documentation/dev-tools/kasan.rst b/Documentation/dev-tools/ka= san.rst index 4968b2aa60c8..b11c1be8dff4 100644 --- a/Documentation/dev-tools/kasan.rst +++ b/Documentation/dev-tools/kasan.rst @@ -315,13 +315,19 @@ translate a memory address to its corresponding shado= w address. Here is the function which translates an address to its corresponding shad= ow address:: =20 - static inline void *kasan_mem_to_shadow(const void *addr) - { - return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT) - + KASAN_SHADOW_OFFSET; - } + static inline void *kasan_mem_to_shadow(const void *addr) + { + void *scaled; =20 -where ``KASAN_SHADOW_SCALE_SHIFT =3D 3``. + if (IS_ENABLED(CONFIG_KASAN_GENERIC)) + scaled =3D (void *)((unsigned long)addr >> KASAN_S= HADOW_SCALE_SHIFT); + else + scaled =3D (void *)((long)addr >> KASAN_SHADOW_SCA= LE_SHIFT); + + return KASAN_SHADOW_OFFSET + scaled; + } + +where for Generic KASAN ``KASAN_SHADOW_SCALE_SHIFT =3D 3``. =20 Compile-time instrumentation is used to insert memory access checks. Compi= ler inserts function calls (``__asan_load*(addr)``, ``__asan_store*(addr)``) b= efore diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index bcd9f5bc66e2..87239396ed23 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -434,11 +434,11 @@ config KASAN_SHADOW_OFFSET default 0xdffffe0000000000 if ARM64_VA_BITS_42 && !KASAN_SW_TAGS default 0xdfffffc000000000 if ARM64_VA_BITS_39 && !KASAN_SW_TAGS default 0xdffffff800000000 if ARM64_VA_BITS_36 && !KASAN_SW_TAGS - default 0xefff800000000000 if (ARM64_VA_BITS_48 || (ARM64_VA_BITS_52 && != ARM64_16K_PAGES)) && KASAN_SW_TAGS - default 0xefffc00000000000 if (ARM64_VA_BITS_47 || ARM64_VA_BITS_52) && A= RM64_16K_PAGES && KASAN_SW_TAGS - default 0xeffffe0000000000 if ARM64_VA_BITS_42 && KASAN_SW_TAGS - default 0xefffffc000000000 if ARM64_VA_BITS_39 && KASAN_SW_TAGS - default 0xeffffff800000000 if ARM64_VA_BITS_36 && KASAN_SW_TAGS + default 0xffff800000000000 if (ARM64_VA_BITS_48 || (ARM64_VA_BITS_52 && != ARM64_16K_PAGES)) && KASAN_SW_TAGS + default 0xffffc00000000000 if (ARM64_VA_BITS_47 || ARM64_VA_BITS_52) && A= RM64_16K_PAGES && KASAN_SW_TAGS + default 0xfffffe0000000000 if ARM64_VA_BITS_42 && KASAN_SW_TAGS + default 0xffffffc000000000 if ARM64_VA_BITS_39 && KASAN_SW_TAGS + default 0xfffffff800000000 if ARM64_VA_BITS_36 && KASAN_SW_TAGS default 0xffffffffffffffff =20 config UNWIND_TABLES diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memor= y.h index a2b7a33966ff..875c0bd0d85a 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -89,7 +89,15 @@ * * KASAN_SHADOW_END is defined first as the shadow address that correspond= s to * the upper bound of possible virtual kernel memory addresses UL(1) << 64 - * according to the mapping formula. + * according to the mapping formula. For Generic KASAN, the address in the + * mapping formula is treated as unsigned (part of the compiler's ABI), so= the + * end of the shadow memory region is at a large positive offset from + * KASAN_SHADOW_OFFSET. For Software Tag-Based KASAN, the address in the + * formula is treated as signed. Since all kernel addresses are negative, = they + * map to shadow memory below KASAN_SHADOW_OFFSET, making KASAN_SHADOW_OFF= SET + * itself the end of the shadow memory region. (User pointers are positive= and + * would map to shadow memory above KASAN_SHADOW_OFFSET, but shadow memory= is + * not allocated for them.) * * KASAN_SHADOW_START is defined second based on KASAN_SHADOW_END. The sha= dow * memory start must map to the lowest possible kernel virtual memory addr= ess @@ -100,7 +108,11 @@ */ #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) #define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL) +#ifdef CONFIG_KASAN_GENERIC #define KASAN_SHADOW_END ((UL(1) << (64 - KASAN_SHADOW_SCALE_SHIFT)) + KAS= AN_SHADOW_OFFSET) +#else +#define KASAN_SHADOW_END KASAN_SHADOW_OFFSET +#endif #define _KASAN_SHADOW_START(va) (KASAN_SHADOW_END - (UL(1) << ((va) - KASA= N_SHADOW_SCALE_SHIFT))) #define KASAN_SHADOW_START _KASAN_SHADOW_START(vabits_actual) #define PAGE_END KASAN_SHADOW_START diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c index abeb81bf6ebd..937f6eb8115b 100644 --- a/arch/arm64/mm/kasan_init.c +++ b/arch/arm64/mm/kasan_init.c @@ -198,8 +198,11 @@ static bool __init root_level_aligned(u64 addr) /* The early shadow maps everything to a single page of zeroes */ asmlinkage void __init kasan_early_init(void) { - BUILD_BUG_ON(KASAN_SHADOW_OFFSET !=3D - KASAN_SHADOW_END - (1UL << (64 - KASAN_SHADOW_SCALE_SHIFT))); + if (IS_ENABLED(CONFIG_KASAN_GENERIC)) + BUILD_BUG_ON(KASAN_SHADOW_OFFSET !=3D + KASAN_SHADOW_END - (1UL << (64 - KASAN_SHADOW_SCALE_SHIFT))); + else + BUILD_BUG_ON(KASAN_SHADOW_OFFSET !=3D KASAN_SHADOW_END); BUILD_BUG_ON(!IS_ALIGNED(_KASAN_SHADOW_START(VA_BITS), SHADOW_ALIGN)); BUILD_BUG_ON(!IS_ALIGNED(_KASAN_SHADOW_START(VA_BITS_MIN), SHADOW_ALIGN)); BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, SHADOW_ALIGN)); diff --git a/include/linux/kasan.h b/include/linux/kasan.h index bf233bde68c7..fbff1b759c85 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h @@ -62,8 +62,14 @@ int kasan_populate_early_shadow(const void *shadow_start, #ifndef kasan_mem_to_shadow static inline void *kasan_mem_to_shadow(const void *addr) { - return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT) - + KASAN_SHADOW_OFFSET; + void *scaled; + + if (IS_ENABLED(CONFIG_KASAN_GENERIC)) + scaled =3D (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT); + else + scaled =3D (void *)((long)addr >> KASAN_SHADOW_SCALE_SHIFT); + + return KASAN_SHADOW_OFFSET + scaled; } #endif =20 diff --git a/mm/kasan/report.c b/mm/kasan/report.c index e804b1e1f886..1e4521b5ef14 100644 --- a/mm/kasan/report.c +++ b/mm/kasan/report.c @@ -640,12 +640,20 @@ void kasan_non_canonical_hook(unsigned long addr) { unsigned long orig_addr, user_orig_addr; const char *bug_type; + void *tagged_null =3D set_tag(NULL, KASAN_TAG_KERNEL); + void *tagged_addr =3D set_tag((void *)addr, KASAN_TAG_KERNEL); =20 /* - * All addresses that came as a result of the memory-to-shadow mapping - * (even for bogus pointers) must be >=3D KASAN_SHADOW_OFFSET. + * Filter out addresses that cannot be shadow memory accesses generated + * by the compiler. + * + * In SW_TAGS mode, when computing a shadow address, the compiler always + * sets the kernel tag (some top bits) on the pointer *before* computing + * the memory-to-shadow mapping. As a result, valid shadow addresses + * are derived from tagged kernel pointers. */ - if (addr < KASAN_SHADOW_OFFSET) + if (tagged_addr < kasan_mem_to_shadow(tagged_null) || + tagged_addr > kasan_mem_to_shadow((void *)(~0ULL))) return; =20 orig_addr =3D (unsigned long)kasan_shadow_to_mem((void *)addr); @@ -670,7 +678,7 @@ void kasan_non_canonical_hook(unsigned long addr) } else if (user_orig_addr < TASK_SIZE) { bug_type =3D "probably user-memory-access"; orig_addr =3D user_orig_addr; - } else if (addr_in_shadow((void *)addr)) + } else if (addr_in_shadow(tagged_addr)) bug_type =3D "probably wild-memory-access"; else bug_type =3D "maybe wild-memory-access"; diff --git a/scripts/gdb/linux/kasan.py b/scripts/gdb/linux/kasan.py index 56730b3fde0b..4b86202b155f 100644 --- a/scripts/gdb/linux/kasan.py +++ b/scripts/gdb/linux/kasan.py @@ -7,7 +7,8 @@ # =20 import gdb -from linux import constants, mm +from linux import constants, utils, mm +from ctypes import c_int64 as s64 =20 def help(): t =3D """Usage: lx-kasan_mem_to_shadow [Hex memory addr] @@ -39,6 +40,8 @@ class KasanMemToShadow(gdb.Command): else: help() def kasan_mem_to_shadow(self, addr): + if constants.CONFIG_KASAN_SW_TAGS and not utils.is_target_arch('x8= 6'): + addr =3D s64(addr) return (addr >> self.p_ops.KASAN_SHADOW_SCALE_SHIFT) + self.p_ops.= KASAN_SHADOW_OFFSET =20 KasanMemToShadow() diff --git a/scripts/gdb/linux/mm.py b/scripts/gdb/linux/mm.py index d78908f6664d..d4ab341d89c5 100644 --- a/scripts/gdb/linux/mm.py +++ b/scripts/gdb/linux/mm.py @@ -281,12 +281,13 @@ class aarch64_page_ops(): self.KERNEL_END =3D gdb.parse_and_eval("_end") =20 if constants.LX_CONFIG_KASAN_GENERIC or constants.LX_CONFIG_KASAN_= SW_TAGS: + self.KASAN_SHADOW_OFFSET =3D constants.LX_CONFIG_KASAN_SHADOW_= OFFSET if constants.LX_CONFIG_KASAN_GENERIC: self.KASAN_SHADOW_SCALE_SHIFT =3D 3 + self.KASAN_SHADOW_END =3D (1 << (64 - self.KASAN_SHADOW_SC= ALE_SHIFT)) + self.KASAN_SHADOW_OFFSET else: self.KASAN_SHADOW_SCALE_SHIFT =3D 4 - self.KASAN_SHADOW_OFFSET =3D constants.LX_CONFIG_KASAN_SHADOW_= OFFSET - self.KASAN_SHADOW_END =3D (1 << (64 - self.KASAN_SHADOW_SCALE_= SHIFT)) + self.KASAN_SHADOW_OFFSET + self.KASAN_SHADOW_END =3D self.KASAN_SHADOW_OFFSET self.PAGE_END =3D self.KASAN_SHADOW_END - (1 << (self.vabits_a= ctual - self.KASAN_SHADOW_SCALE_SHIFT)) else: self.PAGE_END =3D self._PAGE_END(self.VA_BITS_MIN) --=20 2.53.0 From nobody Thu Apr 2 00:13:50 2026 Received: from mail-24418.protonmail.ch (mail-24418.protonmail.ch [109.224.244.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3CEFA2EACF2 for ; Mon, 30 Mar 2026 14:33:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=109.224.244.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881205; cv=none; b=e71Xh4+gK9C1R05qhAWp4hrQW7g9MfRM/Je4wbdO96e0BkAT9AHUTEPMFbLmuuzU3ywnDY2IpQjTuryeDOv4W61hky5LWcgvuy11GeOfiB1QNWPblgsGQWcvU0AZxKzTojvnlne0dWBitGL0aKCSFeFpW97dmMX7gqiCc3/cT+Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881205; c=relaxed/simple; bh=fZO8AL7K0FxGd4ROb7TxMN4qL/lNTujVpCbN7BisJ/Q=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Js/QluZ5Q9f9QWAE5fysrJ+z2u1iEEhvDfmZMC02l9EznDSHPza5hZQ3e4KvIMZ4Ah1S71nowk+NYGuCrBZN68I4koHevMjzYTRtoLe1vwDFsir++iuqOkFvsNNNjHcaPIDaDga9eze1hR3X698G2rZis+DVFGbnrgOfxOhc218= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me; spf=pass smtp.mailfrom=pm.me; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b=CRGzF8JZ; arc=none smtp.client-ip=109.224.244.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pm.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b="CRGzF8JZ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1774881200; x=1775140400; bh=C6RPAE+IMjAOmkl7tc8DZi3umBRg/ZmgJ/efKnqWEoc=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=CRGzF8JZycNd3OpbKU8omrgqB8xu8NCxoq5VTplJozAziqnZGGS9uVmkE6/WhDVjb 55FDa21vBc1qB9w2GttFaUQ/hAvhTU4vFtugCVBsn/WmQEtl7O7yljs093gv0ys55s 1tTUUnRVHu1P6ae3QIi70DA1P+vlUbyyHIaw44q+0Tdl7nsXMSLFALYMk5SjQ38bYq HiHi2/QOTkQzHpkgS1rvrniaVt6dJYZcsDx1xIQmNUmb1BHHlqdEHGWfhVHX43iqL+ f+/7APqDjR8ZMqsReRqYKgxLCO75ehGM3Sfl1efLuitfGo5EfnZui9o6PchOP5Uh1V YhqGrbAtNT2rg== Date: Mon, 30 Mar 2026 14:33:16 +0000 To: Andrey Ryabinin , Alexander Potapenko , Andrey Konovalov , Dmitry Vyukov , Vincenzo Frascino , Catalin Marinas , Will Deacon , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko From: Maciej Wieczor-Retman Cc: m.wieczorretman@pm.me, Samuel Holland , Maciej Wieczor-Retman , linux-kernel@vger.kernel.org, kasan-dev@googlegroups.com, linux-arm-kernel@lists.infradead.org, linux-mm@kvack.org Subject: [PATCH v12 02/15] kasan: arm64: x86: Make special tags arch specific Message-ID: <6080be7964fc726327186d5bf7979e16ddd282bb.1774872838.git.m.wieczorretman@pm.me> In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: 0ce3648d813dbd335bc37a151748b3b43270f6c0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Samuel Holland KASAN's tag-based mode defines multiple special tag values. They're reserved for: - Native kernel value. On arm64 it's 0xFF and it causes an early return in the tag checking function. - Invalid value. 0xFE marks an area as freed / unallocated. It's also the value that is used to initialize regions of shadow memory. - Min and max values. 0xFD is the highest value that can be randomly generated for a new tag. 0 is the minimal value with the exception of arm64's hardware mode where it is equal to 0xF0. Metadata macro is also defined: - Tag width equal to 8. Tag-based mode on x86 is going to use 4 bit wide tags so all the above values need to be changed accordingly. Make tag width and native kernel tag arch specific for x86 and arm64. Base the invalid tag value and the max value on the native kernel tag since they follow the same pattern on both mentioned architectures. Also generalize KASAN_SHADOW_INIT and 0xff used in various page_kasan_tag* helpers. Give KASAN_TAG_MIN the default value of zero, and move the special value for hw_tags arm64 to its arch specific kasan-tags.h. Signed-off-by: Samuel Holland Co-developed-by: Maciej Wieczor-Retman Signed-off-by: Maciej Wieczor-Retman Acked-by: Will Deacon (for the arm part) Reviewed-by: Andrey Konovalov Reviewed-by: Andrey Ryabinin --- Changelog v9: - Add Andrey Ryabinin's Reviewed-by tag. - Add Andrey Konovalov's Reviewed-by tag. Changelog v8: - Add Will's Acked-by tag. Changelog v7: - Reorder defines of arm64 tag width to prevent redefinition warnings. - Remove KASAN_TAG_MASK so it's only defined in mmzone.h (Andrey Konovalov) - Merge the 'support tag widths less than 8 bits' with this patch since they do similar things and overwrite each other. (Alexander) Changelog v6: - Add hardware tags KASAN_TAG_WIDTH value to the arm64 arch file. - Keep KASAN_TAG_MASK in the mmzone.h. - Remove ifndef from KASAN_SHADOW_INIT. Changelog v5: - Move KASAN_TAG_MIN to the arm64 kasan-tags.h for the hardware KASAN mode case. Changelog v4: - Move KASAN_TAG_MASK to kasan-tags.h. Changelog v2: - Remove risc-v from the patch. MAINTAINERS | 2 +- arch/arm64/include/asm/kasan-tags.h | 14 ++++++++++++++ arch/arm64/include/asm/kasan.h | 2 -- arch/arm64/include/asm/uaccess.h | 1 + arch/x86/include/asm/kasan-tags.h | 9 +++++++++ include/linux/kasan-tags.h | 19 ++++++++++++++----- include/linux/kasan.h | 3 +-- include/linux/mm.h | 6 +++--- include/linux/page-flags-layout.h | 9 +-------- 9 files changed, 44 insertions(+), 21 deletions(-) create mode 100644 arch/arm64/include/asm/kasan-tags.h create mode 100644 arch/x86/include/asm/kasan-tags.h diff --git a/MAINTAINERS b/MAINTAINERS index 16874c32e288..897210732d30 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13735,7 +13735,7 @@ L: kasan-dev@googlegroups.com S: Maintained B: https://bugzilla.kernel.org/buglist.cgi?component=3DSanitizers&product= =3DMemory%20Management F: Documentation/dev-tools/kasan.rst -F: arch/*/include/asm/*kasan.h +F: arch/*/include/asm/*kasan*.h F: arch/*/mm/kasan_init* F: include/linux/kasan*.h F: lib/Kconfig.kasan diff --git a/arch/arm64/include/asm/kasan-tags.h b/arch/arm64/include/asm/k= asan-tags.h new file mode 100644 index 000000000000..259952677443 --- /dev/null +++ b/arch/arm64/include/asm/kasan-tags.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ASM_KASAN_TAGS_H +#define __ASM_KASAN_TAGS_H + +#define KASAN_TAG_KERNEL 0xFF /* native kernel pointers tag */ + +#ifdef CONFIG_KASAN_HW_TAGS +#define KASAN_TAG_MIN 0xF0 /* minimum value for random tags */ +#define KASAN_TAG_WIDTH 4 +#else +#define KASAN_TAG_WIDTH 8 +#endif + +#endif /* ASM_KASAN_TAGS_H */ diff --git a/arch/arm64/include/asm/kasan.h b/arch/arm64/include/asm/kasan.h index b167e9d3da91..fd4a8557d736 100644 --- a/arch/arm64/include/asm/kasan.h +++ b/arch/arm64/include/asm/kasan.h @@ -6,8 +6,6 @@ =20 #include #include -#include -#include =20 #define arch_kasan_set_tag(addr, tag) __tag_set(addr, tag) #define arch_kasan_reset_tag(addr) __tag_reset(addr) diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uacc= ess.h index 9810106a3f66..5465bc97ccdd 100644 --- a/arch/arm64/include/asm/uaccess.h +++ b/arch/arm64/include/asm/uaccess.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/include/asm/kasan-tags.h b/arch/x86/include/asm/kasan= -tags.h new file mode 100644 index 000000000000..68ba385bc75c --- /dev/null +++ b/arch/x86/include/asm/kasan-tags.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ASM_KASAN_TAGS_H +#define __ASM_KASAN_TAGS_H + +#define KASAN_TAG_KERNEL 0xF /* native kernel pointers tag */ + +#define KASAN_TAG_WIDTH 4 + +#endif /* ASM_KASAN_TAGS_H */ diff --git a/include/linux/kasan-tags.h b/include/linux/kasan-tags.h index 4f85f562512c..ad5c11950233 100644 --- a/include/linux/kasan-tags.h +++ b/include/linux/kasan-tags.h @@ -2,13 +2,22 @@ #ifndef _LINUX_KASAN_TAGS_H #define _LINUX_KASAN_TAGS_H =20 +#if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS) +#include +#endif + +#ifndef KASAN_TAG_WIDTH +#define KASAN_TAG_WIDTH 0 +#endif + +#ifndef KASAN_TAG_KERNEL #define KASAN_TAG_KERNEL 0xFF /* native kernel pointers tag */ -#define KASAN_TAG_INVALID 0xFE /* inaccessible memory tag */ -#define KASAN_TAG_MAX 0xFD /* maximum value for random tags */ +#endif + +#define KASAN_TAG_INVALID (KASAN_TAG_KERNEL - 1) /* inaccessible memory ta= g */ +#define KASAN_TAG_MAX (KASAN_TAG_KERNEL - 2) /* maximum value for random = tags */ =20 -#ifdef CONFIG_KASAN_HW_TAGS -#define KASAN_TAG_MIN 0xF0 /* minimum value for random tags */ -#else +#ifndef KASAN_TAG_MIN #define KASAN_TAG_MIN 0x00 /* minimum value for random tags */ #endif =20 diff --git a/include/linux/kasan.h b/include/linux/kasan.h index fbff1b759c85..e18908f3ad6e 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h @@ -40,8 +40,7 @@ typedef unsigned int __bitwise kasan_vmalloc_flags_t; /* Software KASAN implementations use shadow memory. */ =20 #ifdef CONFIG_KASAN_SW_TAGS -/* This matches KASAN_TAG_INVALID. */ -#define KASAN_SHADOW_INIT 0xFE +#define KASAN_SHADOW_INIT KASAN_TAG_INVALID #else #define KASAN_SHADOW_INIT 0 #endif diff --git a/include/linux/mm.h b/include/linux/mm.h index 633bbf9a184a..09044934dda8 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2440,7 +2440,7 @@ static inline u8 page_kasan_tag(const struct page *pa= ge) =20 if (kasan_enabled()) { tag =3D (page->flags.f >> KASAN_TAG_PGSHIFT) & KASAN_TAG_MASK; - tag ^=3D 0xff; + tag ^=3D KASAN_TAG_KERNEL; } =20 return tag; @@ -2453,7 +2453,7 @@ static inline void page_kasan_tag_set(struct page *pa= ge, u8 tag) if (!kasan_enabled()) return; =20 - tag ^=3D 0xff; + tag ^=3D KASAN_TAG_KERNEL; old_flags =3D READ_ONCE(page->flags.f); do { flags =3D old_flags; @@ -2472,7 +2472,7 @@ static inline void page_kasan_tag_reset(struct page *= page) =20 static inline u8 page_kasan_tag(const struct page *page) { - return 0xff; + return KASAN_TAG_KERNEL; } =20 static inline void page_kasan_tag_set(struct page *page, u8 tag) { } diff --git a/include/linux/page-flags-layout.h b/include/linux/page-flags-l= ayout.h index 760006b1c480..b2cc4cb870e0 100644 --- a/include/linux/page-flags-layout.h +++ b/include/linux/page-flags-layout.h @@ -3,6 +3,7 @@ #define PAGE_FLAGS_LAYOUT_H =20 #include +#include #include =20 /* @@ -72,14 +73,6 @@ #define NODE_NOT_IN_PAGE_FLAGS 1 #endif =20 -#if defined(CONFIG_KASAN_SW_TAGS) -#define KASAN_TAG_WIDTH 8 -#elif defined(CONFIG_KASAN_HW_TAGS) -#define KASAN_TAG_WIDTH 4 -#else -#define KASAN_TAG_WIDTH 0 -#endif - #ifdef CONFIG_NUMA_BALANCING #define LAST__PID_SHIFT 8 #define LAST__PID_MASK ((1 << LAST__PID_SHIFT)-1) --=20 2.53.0 From nobody Thu Apr 2 00:13:50 2026 Received: from mail-06.mail-europe.com (mail-06.mail-europe.com [85.9.210.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6E0A72E7F3A; Mon, 30 Mar 2026 14:33:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=85.9.210.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881219; cv=none; b=ISpyWE86YS3sy1gO37VZtGkn275Ba7vd8jomNua97q728m3J+0n0gFg7rrA01y+BZtjgLHblypAtURCwloHeGsm7j0knamF4D+1RZwTbjyN0dB5YVgftgCuKhz+A2oRIMr+224P+IX8Lt2V5IWJwd2f76xywkQbwx12AOfleX5c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881219; c=relaxed/simple; bh=dx/n2ZSnVbr5KLV93z31YExmyUZ4EQEgGgGeMkJk0wo=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=OtPccxKPRc/a69/jTM7wg0VnD78IPHqZgvIiJMtChCD9nlQ89xb97oBNIjbQ1JQj8x4idrZVGoLf/UB05QuPf3WW/6P1AQIf21p/LhgYjF1KbqxWPk3K9acts0c+OsVCjiT6dOa2ospkeb/ZFqs03SMT59mdIG9SwXYKo4Nxerc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me; spf=pass smtp.mailfrom=pm.me; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b=LC80pBPy; arc=none smtp.client-ip=85.9.210.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pm.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b="LC80pBPy" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1774881208; x=1775140408; bh=xt/M6F0af0Aewj/HTy9bWBamZzfKiE3bbOG01o2uFtM=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=LC80pBPy4BmziJKHqKEqiLF6xF18Cp63k0+InoceeharrEBZgIYnFP/wjH/77cIqm lwXQcpYXekzSNvRP4YIWh4PhFgPbspUKx7GSMKBh/bMT2uOWplWw1+kvvXJdyo9W1w 57IIQZ8Sxzoc+rL7PO3pLhR0WxpaTZMPQNsIf7xa+GQgTrk3/LPbsyfwEekjDarONY L5rqdCHFhc55hhiWTv5+qj0IojpCkkDHyssUgOzCheFbnVSxeKKJJbK8K7qi4Agl0r uGQO66IQ0p+OdxcaGatVn5afuMoWZHDJLRFv7WtNhxMMhqBFCmxZKszapfxjznrZlG rccoEPcuUs4GA== Date: Mon, 30 Mar 2026 14:33:23 +0000 To: Nathan Chancellor , Nicolas Schier , Andrey Ryabinin , Alexander Potapenko , Andrey Konovalov , Dmitry Vyukov , Vincenzo Frascino , Nick Desaulniers , Bill Wendling , Justin Stitt From: Maciej Wieczor-Retman Cc: m.wieczorretman@pm.me, Maciej Wieczor-Retman , kasan-dev@googlegroups.com, linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev Subject: [PATCH v12 03/15] kasan: Fix inline mode for x86 tag-based mode Message-ID: In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: 8d210f735811de14587def33e98946c0bddc794f Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Maciej Wieczor-Retman The LLVM compiler uses hwasan-instrument-with-calls parameter to setup inline or outline mode in tag-based KASAN. If zeroed, it means the instrumentation implementation will be pasted into each relevant location along with KASAN related constants during compilation. If set to one all function instrumentation will be done with function calls instead. The default hwasan-instrument-with-calls value for the x86 architecture in the compiler is "1", which is not true for other architectures. Because of this, enabling inline mode in software tag-based KASAN doesn't work on x86 as the kernel script doesn't zero out the parameter and always sets up the outline mode. Explicitly zero out hwasan-instrument-with-calls when enabling inline mode in tag-based KASAN. Signed-off-by: Maciej Wieczor-Retman Reviewed-by: Andrey Konovalov Reviewed-by: Alexander Potapenko Reviewed-by: Andrey Ryabinin --- Changelog v9: - Add Andrey Ryabinin's Reviewed-by tag. Changelog v7: - Add Alexander's Reviewed-by tag. Changelog v6: - Add Andrey's Reviewed-by tag. Changelog v3: - Add this patch to the series. scripts/Makefile.kasan | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan index 0ba2aac3b8dc..e485814df3e9 100644 --- a/scripts/Makefile.kasan +++ b/scripts/Makefile.kasan @@ -76,8 +76,11 @@ CFLAGS_KASAN :=3D -fsanitize=3Dkernel-hwaddress RUSTFLAGS_KASAN :=3D -Zsanitizer=3Dkernel-hwaddress \ -Zsanitizer-recover=3Dkernel-hwaddress =20 +# LLVM sets hwasan-instrument-with-calls to 1 on x86 by default. Set it to= 0 +# when inline mode is enabled. ifdef CONFIG_KASAN_INLINE kasan_params +=3D hwasan-mapping-offset=3D$(KASAN_SHADOW_OFFSET) + kasan_params +=3D hwasan-instrument-with-calls=3D0 else kasan_params +=3D hwasan-instrument-with-calls=3D1 endif --=20 2.53.0 From nobody Thu Apr 2 00:13:50 2026 Received: from mail-4316.protonmail.ch (mail-4316.protonmail.ch [185.70.43.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A0CFD28371 for ; Mon, 30 Mar 2026 14:33:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.16 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881221; cv=none; b=koGJrxZZn2f0k6CXkVseGzyt/MxnTeJyydDYlj+AL1yPhg3UWUJ2QPv0q4tjOeS4orrPrnavsSG0VmPUFlO1cABp7oIr/qM6R6LQZriPo4Ea1R6fkLoXiguCcJ3lCvBe+4eWdM0Y6QjMzAIx/W3L/41drfCDQlegQUjn1ey8Kps= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881221; c=relaxed/simple; bh=XB2QB+gnLMVEOZPCJi6+NHHet3BNaDy+5/eRZ3WIQOw=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Qfmz1J5Hf0jTlFU4erzHfrEQKozkNkYHwIRL1Yga1hxZEiLzuI0pVkf27tnkJ9EYFs7Gu4irslacnC8hQJ13r2Jut1gJdotOe9WfwYJgI5ohTRXmvXfg2FjBe+zk3Q5dqfhoXmb0kcA30RybUuSlqslXT58prVogLgv9fM7o18E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me; spf=pass smtp.mailfrom=pm.me; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b=dupg4/Bi; arc=none smtp.client-ip=185.70.43.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pm.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b="dupg4/Bi" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1774881216; x=1775140416; bh=AInB1WLraGnVpbEFot6AYEw25ZN3HBhArAeFNl6DT0g=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=dupg4/BiGzfJ4BSGyBiX4+Li4qFJ8XZZ1DH2q/I0C7DlIDiMOYhEzWEAnkwaMxznQ k9CRhqu2l44Qb1U8pgQgcuoOL/d4XuuH3LBXl1ApjoldI49K6d36jCtvKe+tQy4SUU nm6Fy6KeGOOhVd1UbUZX1wdxvjKSJQh6jm/6QUOUYNirGo5d1hYVEkEMe6GKVolhQ+ U+O845xjsolSa29ASzgvKouJxHob9paLyL0s6RHRLDXTAibzb1k4CJw+T+3JgLmAAr aj3qdw3ySL7uifKyVMlKreIcwhv82Djefo3Eo5I66Mp8KLTV68fRI0YtQ5w7r70nGo tbv+Pxi/jXZ4Q== Date: Mon, 30 Mar 2026 14:33:30 +0000 To: Andrey Ryabinin , Alexander Potapenko , Andrey Konovalov , Dmitry Vyukov , Vincenzo Frascino , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Andrew Morton , Kairui Song , Qi Zheng , Shakeel Butt , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko From: Maciej Wieczor-Retman Cc: m.wieczorretman@pm.me, Maciej Wieczor-Retman , kasan-dev@googlegroups.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: [PATCH v12 04/15] x86/kasan: Add arch specific kasan functions Message-ID: In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: f12ade9a7d415496909ab469ba49499df63371a3 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Maciej Wieczor-Retman KASAN's software tag-based mode needs multiple macros/functions to handle tag and pointer interactions - to set, retrieve and reset tags from the top bits of a pointer. Mimic functions currently used by arm64 but change the tag's position to bits [60:57] in the pointer. Signed-off-by: Maciej Wieczor-Retman Reviewed-by: Andrey Ryabinin --- Changelog v9: - Rename KASAN_TAG_BYTE_MASK to KASAN_TAG_BITS_MASK. - Add Andrey Ryabinin's Reviewed-by tag. Changelog v7: - Add KASAN_TAG_BYTE_MASK to avoid circular includes and avoid removing KASAN_TAG_MASK from mmzone.h. - Remove Andrey's Acked-by tag. Changelog v6: - Remove empty line after ifdef CONFIG_KASAN_SW_TAGS - Add ifdef 64 bit to avoid problems in vdso32. - Add Andrey's Acked-by tag. Changelog v4: - Rewrite __tag_set() without pointless casts and make it more readable. Changelog v3: - Reorder functions so that __tag_*() etc are above the arch_kasan_*() ones. - Remove CONFIG_KASAN condition from __tag_set() arch/x86/include/asm/kasan.h | 42 ++++++++++++++++++++++++++++++++++-- include/linux/kasan-tags.h | 2 ++ include/linux/mmzone.h | 2 +- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/kasan.h b/arch/x86/include/asm/kasan.h index d7e33c7f096b..c868ae734f68 100644 --- a/arch/x86/include/asm/kasan.h +++ b/arch/x86/include/asm/kasan.h @@ -3,6 +3,8 @@ #define _ASM_X86_KASAN_H =20 #include +#include +#include #define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL) #define KASAN_SHADOW_SCALE_SHIFT 3 =20 @@ -24,8 +26,43 @@ KASAN_SHADOW_SCALE_SHIFT))) =20 #ifndef __ASSEMBLER__ +#include +#include +#include + +#ifdef CONFIG_KASAN_SW_TAGS +#define __tag_shifted(tag) FIELD_PREP(GENMASK_ULL(60, 57), tag) +#define __tag_reset(addr) (sign_extend64((u64)(addr), 56)) +#define __tag_get(addr) ((u8)FIELD_GET(GENMASK_ULL(60, 57), (u64)addr)) +#else +#define __tag_shifted(tag) 0UL +#define __tag_reset(addr) (addr) +#define __tag_get(addr) 0 +#endif /* CONFIG_KASAN_SW_TAGS */ + +#ifdef CONFIG_64BIT +static inline void *__tag_set(const void *__addr, u8 tag) +{ + u64 addr =3D (u64)__addr; + + addr &=3D ~__tag_shifted(KASAN_TAG_BITS_MASK); + addr |=3D __tag_shifted(tag & KASAN_TAG_BITS_MASK); + + return (void *)addr; +} +#else +static inline void *__tag_set(void *__addr, u8 tag) +{ + return __addr; +} +#endif + +#define arch_kasan_set_tag(addr, tag) __tag_set(addr, tag) +#define arch_kasan_reset_tag(addr) __tag_reset(addr) +#define arch_kasan_get_tag(addr) __tag_get(addr) =20 #ifdef CONFIG_KASAN + void __init kasan_early_init(void); void __init kasan_init(void); void __init kasan_populate_shadow_for_vaddr(void *va, size_t size, int nid= ); @@ -34,8 +71,9 @@ static inline void kasan_early_init(void) { } static inline void kasan_init(void) { } static inline void kasan_populate_shadow_for_vaddr(void *va, size_t size, int nid) { } -#endif =20 -#endif +#endif /* CONFIG_KASAN */ + +#endif /* __ASSEMBLER__ */ =20 #endif diff --git a/include/linux/kasan-tags.h b/include/linux/kasan-tags.h index ad5c11950233..36cc4f70674a 100644 --- a/include/linux/kasan-tags.h +++ b/include/linux/kasan-tags.h @@ -10,6 +10,8 @@ #define KASAN_TAG_WIDTH 0 #endif =20 +#define KASAN_TAG_BITS_MASK ((1UL << KASAN_TAG_WIDTH) - 1) + #ifndef KASAN_TAG_KERNEL #define KASAN_TAG_KERNEL 0xFF /* native kernel pointers tag */ #endif diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 7de42be81d4b..61df894ad105 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -1266,7 +1266,7 @@ static inline bool zone_is_empty(const struct zone *z= one) #define NODES_MASK ((1UL << NODES_WIDTH) - 1) #define SECTIONS_MASK ((1UL << SECTIONS_WIDTH) - 1) #define LAST_CPUPID_MASK ((1UL << LAST_CPUPID_SHIFT) - 1) -#define KASAN_TAG_MASK ((1UL << KASAN_TAG_WIDTH) - 1) +#define KASAN_TAG_MASK KASAN_TAG_BITS_MASK #define ZONEID_MASK ((1UL << ZONEID_SHIFT) - 1) =20 static inline enum zone_type memdesc_zonenum(memdesc_flags_t flags) --=20 2.53.0 From nobody Thu Apr 2 00:13:50 2026 Received: from mail-244121.protonmail.ch (mail-244121.protonmail.ch [109.224.244.121]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3D47E2E7623 for ; Mon, 30 Mar 2026 14:33:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=109.224.244.121 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881230; cv=none; b=WbhAwqj/5enrl2P//oDQvAEQBxo0GUnhKmGKhnONkO0f7XINsi9FvzTP4RgPKXdqbOgL6ayihGy9CDHbejGzeX7xUxHSkWK7ZkXWnN5kJ/4yxeVgHP+0UEDit6kuEmety47y30ua615FdHd8YDW6OzmYqj2S56/h8+n+ETO8jdg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881230; c=relaxed/simple; bh=7AFthwAm+gatT35eXeU/LM3MuDQxV8VZ/+uxZ3AfbIU=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=AYB4TLf+S4sLcmTwq+3+KsNO4mfWZvUTZBu474GdPxYANb4NCVRNSahS2Fe5r5OZ85pE35GNdLEW2JaeLwe2y/pGHrnZ8NZVjNE/R4g1Ru26JEt+Z/02oLUyH3TQ8Y8OGrRHOst8E8HLq2F8RwJxEV4VGfisIaK4PWJaV/0aJmM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me; spf=pass smtp.mailfrom=pm.me; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b=mUgT38hH; arc=none smtp.client-ip=109.224.244.121 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pm.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b="mUgT38hH" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1774881222; x=1775140422; bh=P/sihZxhx1D4j95rOaUZIBK6YpmtfpmdHtZkQ0gkPEM=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=mUgT38hHjSxFENnSwNipuYJirXL8p/jUUBzDIt7l1ZXerS+XQoeEsdpFy0YkBD3D/ M7D9oazEAXN6GwVGL7J2oejTQfrkYoHQHzczZgGteLuDJgpjJCHN204Hwn98TNM7Vy LRD6rr4+Ncis8WMvN7tifyj4qEEnT81L+uEhRsvD08gbmsyLVG3WOhERJzhDWoYqY9 +gWrRG+XA61FRviTaabZ9lCfl13lIXlsc8sgqFsNK4ZXVVfJAjc0qHR75UZTO1lGXH EfcjohslZFa2+YiooSxTS3sF97R6lYEt4QcHIbyp94Rm0sMty41ZjmvQ7flUW7YUjq 0ZCtXYuRoN67Q== Date: Mon, 30 Mar 2026 14:33:37 +0000 To: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Andy Lutomirski , Peter Zijlstra From: Maciej Wieczor-Retman Cc: m.wieczorretman@pm.me, Maciej Wieczor-Retman , linux-kernel@vger.kernel.org Subject: [PATCH v12 05/15] x86/mm: Reset pointer tag in x - __START_KERNEL_map instances Message-ID: <8ace9c34403e4bdbb8ab00190c7ce8570535f7ee.1774872838.git.m.wieczorretman@pm.me> In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: 5def07ea5224cd619a7293d1652f1b5c1485faed Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Maciej Wieczor-Retman With KASAN software tag-based mode arbitrary kernel pointers can be tagged, and any place where pointer arithmetic is used to convert a virtual address into a physical one can raise errors if the virtual address is tagged. To lower the amount of lines added it's beneficial to move the similar pointer arithmetic to a helper first. Reset the tag in the __phys_addr_kernel_start() which plugs into all the relevant virtual to physical address helpers. Signed-off-by: Maciej Wieczor-Retman --- Changelog v11: - Split off this patch from the tag reset patch. Move x - __START_KERNEL_map to a helper so less lines are added. arch/x86/include/asm/page_64.h | 11 +++++++++-- arch/x86/mm/physaddr.c | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h index 1895c207f629..9260a0d693d6 100644 --- a/arch/x86/include/asm/page_64.h +++ b/arch/x86/include/asm/page_64.h @@ -7,6 +7,7 @@ #ifndef __ASSEMBLER__ #include #include +#include =20 #include #include @@ -20,9 +21,15 @@ extern unsigned long vmalloc_base; extern unsigned long vmemmap_base; extern unsigned long direct_map_physmem_end; =20 +static __always_inline unsigned long __phys_addr_kernel_start(unsigned lon= g x) +{ + x =3D __tag_reset(x); + return x - __START_KERNEL_map; +} + static __always_inline unsigned long __phys_addr_nodebug(unsigned long x) { - unsigned long y =3D x - __START_KERNEL_map; + unsigned long y =3D __phys_addr_kernel_start(x); =20 /* use the carry flag to determine if x was < __START_KERNEL_map */ x =3D y + ((x > y) ? phys_base : (__START_KERNEL_map - PAGE_OFFSET)); @@ -38,7 +45,7 @@ extern unsigned long __phys_addr(unsigned long); =20 static inline unsigned long __phys_addr_symbol(unsigned long x) { - unsigned long y =3D x - __START_KERNEL_map; + unsigned long y =3D __phys_addr_kernel_start(x); =20 /* only check upper bounds since lower bounds will trigger carry */ VIRTUAL_BUG_ON(y >=3D KERNEL_IMAGE_SIZE); diff --git a/arch/x86/mm/physaddr.c b/arch/x86/mm/physaddr.c index 8d31c6b9e184..682e23541228 100644 --- a/arch/x86/mm/physaddr.c +++ b/arch/x86/mm/physaddr.c @@ -14,7 +14,7 @@ #ifdef CONFIG_DEBUG_VIRTUAL unsigned long __phys_addr(unsigned long x) { - unsigned long y =3D x - __START_KERNEL_map; + unsigned long y =3D __phys_addr_kernel_start(x); =20 /* use the carry flag to determine if x was < __START_KERNEL_map */ if (unlikely(x > y)) { @@ -35,7 +35,7 @@ EXPORT_SYMBOL(__phys_addr); =20 bool __virt_addr_valid(unsigned long x) { - unsigned long y =3D x - __START_KERNEL_map; + unsigned long y =3D __phys_addr_kernel_start(x); =20 /* use the carry flag to determine if x was < __START_KERNEL_map */ if (unlikely(x > y)) { --=20 2.53.0 From nobody Thu Apr 2 00:13:50 2026 Received: from mail-106118.protonmail.ch (mail-106118.protonmail.ch [79.135.106.118]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7DACA1A8F97 for ; Mon, 30 Mar 2026 14:33:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=79.135.106.118 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881238; cv=none; b=t6wL7GNJmYTvdVQ/ihsysjmEK9W9yDWRQl9TQrbFXcX9ENUblbI+P/g3n5EqBW6A7WFJcCeeXQFrLi4yQsc6NkYT7lLS7FxEJ4GfRNtkaAVFQYF9LlUK99OJ1jUKjDPyCzAzSkjHEYqfAnapHqHbd37KuUD4D5LwVsQs1qs2LaM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881238; c=relaxed/simple; bh=cNMMLMCSwknhzs1FrpAU10vAGQQE2QvtRAyRJd5vpdQ=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DtGljHzfhkfiyYSM57GJ7ke0nbdrlL6be848Q57XUvqTShSFfgXIDmJaJ+CvTIRfvTdV8HGCrnF4K7nAHlsQPQtvMOsGdfGieJVf+ou3Bdd1XCZ2TUQ/AuOGeWKb0L0Ug2nDGmzYck3PEdUiSX6mNLfDzVnTE0o77bddCeC3h08= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me; spf=pass smtp.mailfrom=pm.me; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b=YCCLybHY; arc=none smtp.client-ip=79.135.106.118 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pm.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b="YCCLybHY" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1774881229; x=1775140429; bh=qKJp2zmpSOHrWvXWXvVfm1wRsYfpExx2ugXRE4WLUFU=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=YCCLybHYi2wR2wkPVJqxMiQnlVDCKaRSAc2GM2k4yVvHs2+q/xLGEQmy1ci96SVPe ksL1M18aqk3T+U81SeRfTAWcLdzwSjTjKzqLtI5QiW11A2y/FbKAgTDTFezGKbYoAs lAy3jSe2vY/cAgrClSZfcuKZoRSF7SKoG67G4XwdHpD0urxhJXKPrz3bPaiOnXM/Ui px6s72vg+QThjq6CrchL4qKa25I74kOJnsRR3TnWFM0ryokXew0zZb8q7bsoodgWSt di67Knp/aRc8Pf3yWTXpGD6Nd1f62Xm3hy/yNYNx8I4T65ECLLumqOMlhrURNFi03W R0Nvo9JsEbLdA== Date: Mon, 30 Mar 2026 14:33:43 +0000 To: Catalin Marinas , Will Deacon , Andrey Ryabinin , Alexander Potapenko , Andrey Konovalov , Dmitry Vyukov , Vincenzo Frascino , Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko From: Maciej Wieczor-Retman Cc: m.wieczorretman@pm.me, Maciej Wieczor-Retman , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kasan-dev@googlegroups.com, linux-mm@kvack.org Subject: [PATCH v12 06/15] kasan: arm64: x86: Make page_to_virt() KASAN aware Message-ID: In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: b6d1646a2fe7b6e96ef4cb8b05ca936c4900195d Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Maciej Wieczor-Retman Special page_to_virt() implementation is needed if an architecture wants to enable KASAN software tag-based mode. Make page_to_virt() KASAN aware in arch-independent code so architectures implementing the software tag-based mode don't have to define their own implementations anymore. When KASAN is disabled or for architectures that don't implement the software tag-based mode page_to_virt() will be optimized to it's previous form. Signed-off-by: Maciej Wieczor-Retman --- Changelog v11: - Redo the patch to work on the page_to_virt macro. Split off changes about virt to phys conversion to an earlier patch. - Remove Alexander's acked-by due to bigger changes. Changelog v7: - Add Alexander's Acked-by tag. Changelog v5: - Move __tag_reset() calls into __phys_addr_nodebug() and __virt_addr_valid() instead of calling it on the arguments of higher level functions. Changelog v4: - Simplify page_to_virt() by removing pointless casts. - Remove change in __is_canonical_address() because it's taken care of in a later patch due to a LAM compatible definition of canonical. arch/arm64/include/asm/memory.h | 5 ----- include/linux/kasan.h | 10 ++++++++++ include/linux/mm.h | 5 ++++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memor= y.h index 875c0bd0d85a..39dd0071d3ec 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -411,11 +411,6 @@ static inline unsigned long virt_to_pfn(const void *ka= ddr) */ =20 #if defined(CONFIG_DEBUG_VIRTUAL) -#define page_to_virt(x) ({ \ - __typeof__(x) __page =3D x; \ - void *__addr =3D __va(page_to_phys(__page)); \ - (void *)__tag_set((const void *)__addr, page_kasan_tag(__page));\ -}) #define virt_to_page(x) pfn_to_page(virt_to_pfn(x)) #else #define page_to_virt(x) ({ \ diff --git a/include/linux/kasan.h b/include/linux/kasan.h index e18908f3ad6e..271c59e9f422 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h @@ -527,6 +527,11 @@ static inline void *kasan_reset_tag(const void *addr) return (void *)arch_kasan_reset_tag(addr); } =20 +static inline void *kasan_set_tag(const void *addr, u8 tag) +{ + return (void *)arch_kasan_set_tag(addr, tag); +} + /** * kasan_report - print a report about a bad memory access detected by KAS= AN * @addr: address of the bad access @@ -544,6 +549,11 @@ static inline void *kasan_reset_tag(const void *addr) return (void *)addr; } =20 +static inline void *kasan_set_tag(const void *addr, u8 tag) +{ + return (void *)addr; +} + #endif /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS*/ =20 #ifdef CONFIG_KASAN_HW_TAGS diff --git a/include/linux/mm.h b/include/linux/mm.h index 09044934dda8..f234650a4edf 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -117,7 +117,10 @@ extern int mmap_rnd_compat_bits __read_mostly; #endif =20 #ifndef page_to_virt -#define page_to_virt(x) __va(PFN_PHYS(page_to_pfn(x))) +#define page_to_virt(x) ({ \ + void *__addr =3D __va(PFN_PHYS(page_to_pfn((struct page *)x))); \ + kasan_set_tag(__addr, page_kasan_tag(x)); \ +}) #endif =20 #ifndef lm_alias --=20 2.53.0 From nobody Thu Apr 2 00:13:50 2026 Received: from mail-244116.protonmail.ch (mail-244116.protonmail.ch [109.224.244.116]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A3F532E7162 for ; Mon, 30 Mar 2026 14:33:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=109.224.244.116 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881239; cv=none; b=QMacGGGjYGE/TcQxzV5VF4XdZlGTNtis4TY3zEitqyNX/W9cgkxwnpBP5aOH/haO6gjkPM2mLvW6kO68cqSKXPEFiXqTFyAFGh8jO5EtAcVVN3O1b189XHwZlPm5PVg5JT+oCgxJi3UxQcm4vwxt05Rv6s3UyemyiXw3J71UqZU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881239; c=relaxed/simple; bh=rYcYU9ZWL1vy2pbB3vmo9XiRTrpuTtXXHyDEYzp0q5c=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=OOpN2GngRz2RsvMtENNxXBl4G7aqtMUiiZgwPO738nA6AS07nLF98ME6+blG+ra3lqjlxTaSm9dBR6AXUQkzvJC6LKuvUSeBW2oPNWEXhHekiNw+dM+w/mOeOelF1MWQ61wdw6EmhpL5VyEe7xXKqhMkHqyRaeGw6+Ga9bE8wPc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me; spf=pass smtp.mailfrom=pm.me; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b=od67eMOl; arc=none smtp.client-ip=109.224.244.116 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pm.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b="od67eMOl" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1774881235; x=1775140435; bh=gDBMQkfHnwQdapFOEWUlLxhTfDL9GpT+jCrwjbzqofU=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=od67eMOlQ+NaI/AYiqnm8BOOip9pxmsJUVxLQvmVWpte+3qlXsdTJZ25X9Spt8iZJ qigfk8oZija7lIu+FhdZ3PNt4dZilS47LxLU/777CfjPV5uMeNlGatFZSx5N6kGJ9t KAFvyzG+MURSpLwUsKleMb4jl5g3RrPx1q3tE5xXxUbgTJMXy1C08QtIs0JfAUp+9N f713qUHe9tJoL3nzaPbt1kKPH4VcG83D4gLIgY5066Kpa7tH/p1Ra4T97XZvsC7DUT zLF/YfQPaW+G25OJoJc9Govr3YcO1ewp00Qvka6aNfLQDkcvCTx2vdP7lfo9TLZBSr exhlNxhFJ6y8w== Date: Mon, 30 Mar 2026 14:33:50 +0000 To: Andrew Morton , Mike Rapoport , Uladzislau Rezki From: Maciej Wieczor-Retman Cc: m.wieczorretman@pm.me, Maciej Wieczor-Retman , Alexander Potapenko , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH v12 07/15] mm/execmem: Untag addresses in EXECMEM_ROX related pointer arithmetic Message-ID: <4a07f48214b0cf5e5888d826183e76af55ffed77.1774872838.git.m.wieczorretman@pm.me> In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: 53838e2a6e7b5d98ce1845d28d58094b9833961a Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Maciej Wieczor-Retman ARCH_HAS_EXECMEM_ROX was re-enabled in x86 at Linux 6.14 release. vm_reset_perms() calculates range's start and end addresses using min() and max() functions. To do that it compares pointers but, with KASAN software tags mode enabled, some are tagged - addr variable is, while start and end variables aren't. This can cause the wrong address to be chosen and result in various errors in different places. Reset tags in the address used as function argument in min(), max(). execmem_cache_add() adds tagged pointers to a maple tree structure, which then are incorrectly compared when walking the tree. That results in different pointers being returned later and page permission violation errors panicking the kernel. Reset tag of the address range inserted into the maple tree inside execmem_vmalloc() which then gets propagated to execmem_cache_add(). Signed-off-by: Maciej Wieczor-Retman Acked-by: Alexander Potapenko Acked-by: Mike Rapoport (Microsoft) --- Changelog v10: - Add Mike's acked-by tag. Changelog v7: - Add Alexander's acked-by tag. - Add comments on why these tag resets are needed (Alexander) Changelog v6: - Move back the tag reset from execmem_cache_add() to execmem_vmalloc() (Mike Rapoport) - Rewrite the changelogs to match the code changes from v6 and v5. Changelog v5: - Remove the within_range() change. - arch_kasan_reset_tag -> kasan_reset_tag. Changelog v4: - Add patch to the series. mm/execmem.c | 9 ++++++++- mm/vmalloc.c | 7 ++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/mm/execmem.c b/mm/execmem.c index 084a207e4278..047079efe379 100644 --- a/mm/execmem.c +++ b/mm/execmem.c @@ -59,7 +59,14 @@ static void *execmem_vmalloc(struct execmem_range *range= , size_t size, return NULL; } =20 - return p; + /* + * Resetting the tag here is necessary to avoid the tagged address + * ending up in the maple tree structure. There it's linear address + * can be incorrectly compared with other addresses which can result in + * a wrong address being picked down the line and for example a page + * permission violation error panicking the kernel. + */ + return kasan_reset_tag(p); } =20 struct vm_struct *execmem_vmap(size_t size) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index b31b208f6ecb..b2adc1524bd1 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -3361,7 +3361,12 @@ static void vm_reset_perms(struct vm_struct *area) * the vm_unmap_aliases() flush includes the direct map. */ for (i =3D 0; i < area->nr_pages; i +=3D 1U << page_order) { - unsigned long addr =3D (unsigned long)page_address(area->pages[i]); + /* + * Addresses' tag needs resetting so it can be properly used in + * the min() and max() below. Otherwise the start or end values + * might be favoured. + */ + unsigned long addr =3D (unsigned long)kasan_reset_tag(page_address(area-= >pages[i])); =20 if (addr) { unsigned long page_size; --=20 2.53.0 From nobody Thu Apr 2 00:13:50 2026 Received: from mail-244123.protonmail.ch (mail-244123.protonmail.ch [109.224.244.123]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B10CE2EDD69 for ; Mon, 30 Mar 2026 14:34:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=109.224.244.123 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881245; cv=none; b=Vzj3GenFiNw/9zkBDVFer/CQsMX7BCpRaVmMwzIy2AETtFk7IgFlvCZ/5Om8SyFlHpfPUnZRY5sFPV0i+ThC1Dwd1uvnG38xK+gHvhlFZFiCTIOEx6MlB4PCcdBexVIfNo6L5YFhB/BJIHHYWr4HpwUNnSZNX5c536fZOw3TszI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881245; c=relaxed/simple; bh=IrdPXXebpwRuiG3UcmBGZipuHvApjSHn/WQXzPro91E=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=vAVj8fncpqS1et8Htx0cBdRFVyAND3QA1orbFeWQtS6OdtmFJDHRz07vfjdmA1lMTHWLyYgBy6p6Xj/GZ0qyFjCqvCNTo0vDiggLqRcdZHG3fOjl5S6+eukDdYev6KNib52J2+Flk4VG0ZLGxMOGNANyDsJD3iwNfO0oJFqbnlQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me; spf=pass smtp.mailfrom=pm.me; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b=hHWE4XfX; arc=none smtp.client-ip=109.224.244.123 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pm.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b="hHWE4XfX" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1774881241; x=1775140441; bh=fLHwEkOWFBQMUpvTpaURzpC8jNFoLdOQa4MBEpchEew=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=hHWE4XfXCv7a8w9mDClxb9DYUnLhlr3ZuEFUYkbY45rHLExh0jNgs5GqAhq/89PBQ NQ04fc17shF35uPeXvVbDAr5TGQVoqQfd/P2NvFK3eNtDVlVnq4dlBEJkMaaILnTjG 0xEgzMCY+C+e86LeegsVd8WX+JQD8eHmBigN1DFK8hKalDkq7CqcAzYqETyQFVALdu RtzZ+8ehHBMXD5ZHF2DRvp6u6mYpg3oN7wJSH0mjxPO5s5ShsfECij0Qdr18PkPZAT G6kK8FrELG9YduQsAKk/UXd/++u0LXtM11wcZx/19Rf3hUsw3la3x8E8utj1hF1VxE KG5nLs9AcdxYQ== Date: Mon, 30 Mar 2026 14:33:56 +0000 To: Dave Hansen , Andy Lutomirski , Peter Zijlstra , Thomas Gleixner , Ingo Molnar , Borislav Petkov , x86@kernel.org, "H. Peter Anvin" From: Maciej Wieczor-Retman Cc: m.wieczorretman@pm.me, Maciej Wieczor-Retman , linux-kernel@vger.kernel.org Subject: [PATCH v12 08/15] x86/mm: Use physical address comparisons in fill_p*d/pte Message-ID: In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: 4ca4907790ed77eb3f17b37e52c05e2350ec7cee Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Maciej Wieczor-Retman Calculating page offset returns a pointer without a tag. When comparing the calculated offset to a tagged page pointer an error is raised because they are not equal. Change pointer comparisons to physical address comparisons as to avoid issues with tagged pointers that pointer arithmetic would create. Open code pte_offset_kernel(), pmd_offset(), pud_offset() and p4d_offset(). Because one parameter is always zero and the rest of the function insides are enclosed inside __va(), removing that layer lowers the complexity of final assembly. Signed-off-by: Maciej Wieczor-Retman Acked-by: Dave Hansen --- Changelog v11: - Add Dave's Acked-by. Changelog v9: - Rename patch title so it fits the tip standards. Changelog v7: - Swap ternary operator outcomes in fill_p4d since the order was incorrect. Changelog v2: - Open code *_offset() to avoid it's internal __va(). arch/x86/mm/init_64.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index df2261fa4f98..dd9f15ab8b86 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -269,7 +269,10 @@ static p4d_t *fill_p4d(pgd_t *pgd, unsigned long vaddr) if (pgd_none(*pgd)) { p4d_t *p4d =3D (p4d_t *)spp_getpage(); pgd_populate(&init_mm, pgd, p4d); - if (p4d !=3D p4d_offset(pgd, 0)) + + if (__pa(p4d) !=3D (pgtable_l5_enabled() ? + (unsigned long)pgd_val(*pgd) & PTE_PFN_MASK : + __pa(pgd))) printk(KERN_ERR "PAGETABLE BUG #00! %p <-> %p\n", p4d, p4d_offset(pgd, 0)); } @@ -281,7 +284,7 @@ static pud_t *fill_pud(p4d_t *p4d, unsigned long vaddr) if (p4d_none(*p4d)) { pud_t *pud =3D (pud_t *)spp_getpage(); p4d_populate(&init_mm, p4d, pud); - if (pud !=3D pud_offset(p4d, 0)) + if (__pa(pud) !=3D (p4d_val(*p4d) & p4d_pfn_mask(*p4d))) printk(KERN_ERR "PAGETABLE BUG #01! %p <-> %p\n", pud, pud_offset(p4d, 0)); } @@ -293,7 +296,7 @@ static pmd_t *fill_pmd(pud_t *pud, unsigned long vaddr) if (pud_none(*pud)) { pmd_t *pmd =3D (pmd_t *) spp_getpage(); pud_populate(&init_mm, pud, pmd); - if (pmd !=3D pmd_offset(pud, 0)) + if (__pa(pmd) !=3D (pud_val(*pud) & pud_pfn_mask(*pud))) printk(KERN_ERR "PAGETABLE BUG #02! %p <-> %p\n", pmd, pmd_offset(pud, 0)); } @@ -305,7 +308,7 @@ static pte_t *fill_pte(pmd_t *pmd, unsigned long vaddr) if (pmd_none(*pmd)) { pte_t *pte =3D (pte_t *) spp_getpage(); pmd_populate_kernel(&init_mm, pmd, pte); - if (pte !=3D pte_offset_kernel(pmd, 0)) + if (__pa(pte) !=3D (pmd_val(*pmd) & pmd_pfn_mask(*pmd))) printk(KERN_ERR "PAGETABLE BUG #03!\n"); } return pte_offset_kernel(pmd, vaddr); --=20 2.53.0 From nobody Thu Apr 2 00:13:50 2026 Received: from mail-43101.protonmail.ch (mail-43101.protonmail.ch [185.70.43.101]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BAE3E30EF97 for ; Mon, 30 Mar 2026 14:34:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.101 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881250; cv=none; b=WZ8ZQ3B02Z7WgybHk86maw2PXgYmWfl5hvsafES9ghTz6+OEsqA37OxJEkrK1cmt4EJZbdVZb+Bg3y2GQ1pYUlZMw+S82h5su3qgB0ZqXcNH9E3c2wL6avnlozRJGdvFOmDM393ANArbCUkkfBWWhsdkwARrmpUNlvlHDdSNe9I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881250; c=relaxed/simple; bh=V+RVEeTIiyKE2lGOZ60G1elPpCREDpubZZJqoJxO+jY=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=GFq5acMDAzwB1Y3UmRhobFA4A3/LmKpRnRfmcY88YdOz7sWScdiogUUicZi8AN6kGveb4a4JgR7BFxvbKLEGFf41j+4uAfrawT+94IX3mFF6r2xSjL+Y+YxDHjxc1nPZdQtrgcXLJ/wBWG+B/JZwkWUA2SkpVtWiHehpZEMXONE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me; spf=pass smtp.mailfrom=pm.me; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b=UH7Abow8; arc=none smtp.client-ip=185.70.43.101 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pm.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b="UH7Abow8" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1774881247; x=1775140447; bh=svfiyvtEE/lqQ8xsx5lT5DL7oiLrvzGxpb3VchVEZvw=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=UH7Abow8xp71xGDg6LUTiUbjskDkGOkHnQadY8xw4aGTxIrP2n1LASBl4/iU5m4HV 6w3wggXtV8C9BFn11tOonUZQbDdNEfUvX4HBl69+uo4hI3uQAseQVvFlbYvXl68Cj3 Ayr8ADUKVVSzp/y3cagztlvFkX3UVUYe9/mp0MJIthZfA70aKI8xZY+mGtArGH9r5n SQC8tkGTGiquzfErXbPj7imQ4qE0X1RmycpE9/xHShdYExD1mDIu5mtaxRpKOLGUc3 TMLTNz9em8sKhZhkqycaNW8zTfglVbmoARbMP1a3Ra1R2+YbQq1/iCJnIezP1AOrMT ANFPJdQixChLA== Date: Mon, 30 Mar 2026 14:34:02 +0000 To: Andrey Ryabinin , Alexander Potapenko , Andrey Konovalov , Dmitry Vyukov , Vincenzo Frascino , Dave Hansen , Andy Lutomirski , Peter Zijlstra , Thomas Gleixner , Ingo Molnar , Borislav Petkov , x86@kernel.org, "H. Peter Anvin" From: Maciej Wieczor-Retman Cc: m.wieczorretman@pm.me, Maciej Wieczor-Retman , kasan-dev@googlegroups.com, linux-kernel@vger.kernel.org Subject: [PATCH v12 09/15] x86/kasan: Initialize KASAN raw shadow memory Message-ID: In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: 826801d18a1010869f43bc17fde445210fa756d3 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Maciej Wieczor-Retman In KASAN's generic mode the default value in shadow memory is zero. During initialization of shadow memory pages they are allocated and zeroed. In KASAN's tag-based mode the default tag for the arm64 architecture is 0xFE which corresponds to any memory that should not be accessed. On x86 (where tags are 4-bit wide instead of 8-bit wide) that tag is 0xE so during the initializations all the bytes in shadow memory pages should be filled with it. Use memblock_alloc_try_nid_raw() instead of memblock_alloc_try_nid() to avoid zeroing out the memory so it can be set with the KASAN invalid tag. Signed-off-by: Maciej Wieczor-Retman Reviewed-by: Alexander Potapenko Reviewed-by: Andrey Ryabinin --- Changelog v9: - Rename patch title so it fits the tip standards. - Add Andrey Ryabinin's Reviewed-by tag. Changelog v7: - Fix flipped arguments in memset(). - Add Alexander's reviewed-by tag. Changelog v2: - Remove dense mode references, use memset() instead of kasan_poison(). arch/x86/mm/kasan_init_64.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c index 998b6010d6d3..7f5c11328ec1 100644 --- a/arch/x86/mm/kasan_init_64.c +++ b/arch/x86/mm/kasan_init_64.c @@ -34,6 +34,18 @@ static __init void *early_alloc(size_t size, int nid, bo= ol should_panic) return ptr; } =20 +static __init void *early_raw_alloc(size_t size, int nid, bool should_pani= c) +{ + void *ptr =3D memblock_alloc_try_nid_raw(size, size, + __pa(MAX_DMA_ADDRESS), MEMBLOCK_ALLOC_ACCESSIBLE, nid); + + if (!ptr && should_panic) + panic("%pS: Failed to allocate page, nid=3D%d from=3D%lx\n", + (void *)_RET_IP_, nid, __pa(MAX_DMA_ADDRESS)); + + return ptr; +} + static void __init kasan_populate_pmd(pmd_t *pmd, unsigned long addr, unsigned long end, int nid) { @@ -63,8 +75,9 @@ static void __init kasan_populate_pmd(pmd_t *pmd, unsigne= d long addr, if (!pte_none(*pte)) continue; =20 - p =3D early_alloc(PAGE_SIZE, nid, true); - entry =3D pfn_pte(PFN_DOWN(__pa(p)), PAGE_KERNEL); + p =3D early_raw_alloc(PAGE_SIZE, nid, true); + memset(p, KASAN_SHADOW_INIT, PAGE_SIZE); + entry =3D pfn_pte(PFN_DOWN(__pa_nodebug(p)), PAGE_KERNEL); set_pte_at(&init_mm, addr, pte, entry); } while (pte++, addr +=3D PAGE_SIZE, addr !=3D end); } @@ -436,7 +449,7 @@ void __init kasan_init(void) * it may contain some garbage. Now we can clear and write protect it, * since after the TLB flush no one should write to it. */ - memset(kasan_early_shadow_page, 0, PAGE_SIZE); + memset(kasan_early_shadow_page, KASAN_SHADOW_INIT, PAGE_SIZE); for (i =3D 0; i < PTRS_PER_PTE; i++) { pte_t pte; pgprot_t prot; --=20 2.53.0 From nobody Thu Apr 2 00:13:50 2026 Received: from mail-4322.protonmail.ch (mail-4322.protonmail.ch [185.70.43.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 266B12F1FD0 for ; Mon, 30 Mar 2026 14:34:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.22 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881261; cv=none; b=ZA5OLMvrBAPQa0IJoG7pA6JreHoJPsGx3+C/1sVP0IDbxx8H6HEr3+x6scpEOThhl81zyNn0c2h+3WKlpo94ZeyJkOVGxUyX1KIDQTUPEbH8ljEr5bw9/pRWVMZyQhzKnyf6udj/tf82ptaeNXtivjHrqAVDo6o4OJTj5OmOLRk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881261; c=relaxed/simple; bh=HEk3URbZ/6THzIJGq7fLcDOYJTGoprphT19QGX3qyP0=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=rL3O8zgkevGy/EKOw/QDcQmm+miPnjp6ZrbuwTB6qEHXick9auzmRQwlfM/ivXJ0RwAqWc+jWn+ciyXS7vRN7E3HyiAu+dZdrrYVG7I2dwJtA3jKuiu1PlTcpOrIn0V6lYd/66Tclyie/bzlfDxDvaWqWXCOZtBsiZulllI2OJI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me; spf=pass smtp.mailfrom=pm.me; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b=EErd8ZGb; arc=none smtp.client-ip=185.70.43.22 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pm.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b="EErd8ZGb" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1774881252; x=1775140452; bh=dJUPQVhZMRfdzveegBvIFV3TwRa6qj795ujvLrKLhXQ=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=EErd8ZGbRocHn2SG5ZCZ4M3EQ24YhiS4SycR9Z5VbL1l82+q+1z4q87kOKNowst4y wIRvtLtko3X5UOhVhDyImehgjobhtKIZzvJzmWOuLf7M5BGZxfdioi/NdTA4Seccs+ luhx7121/vJc9Y8kISXvYTT9gzg9xKNfFJXvHs2/U5XOPCEare4mS/vLPelNkMOBWp jDaHjpL/WCTvzp+ScFOarbARYorLXSZSw9ddZ16u7mye3kWPMqP1Aum2tMSfX7rnDx 3Rq0Y4K0O3zllRahntE9Ml+2NSt62zYHOBAM5HRs3v/mvf/uKRuLixnR86OPvT2tbG iIPpeiANLDPMg== Date: Mon, 30 Mar 2026 14:34:07 +0000 To: Dave Hansen , Andy Lutomirski , Peter Zijlstra , Thomas Gleixner , Ingo Molnar , Borislav Petkov , x86@kernel.org, "H. Peter Anvin" From: Maciej Wieczor-Retman Cc: m.wieczorretman@pm.me, Maciej Wieczor-Retman , linux-kernel@vger.kernel.org Subject: [PATCH v12 10/15] x86/mm: Reset tags in a canonical address helper call Message-ID: <3611e30bb2776a951a68791b7668ff0ebd903aa1.1774872838.git.m.wieczorretman@pm.me> In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: 40ba4e4f63436a9f3eb1dcb4a2f57b5f44b1ede3 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Maciej Wieczor-Retman With KASAN software tag-based mode arbitrary kernel pointers can be tagged. __is_canonical_address() helper can cause issues when met with tagged pointers that expect the loosened canonicality checks. The function itself shouldn't be made LAM-aware since for example in KVM, where it's used extensively - it's not practical to deal with differences between host and guest which might want a different LAM state. Also by the time __is_canonical_address() is invoked KVM has already done any necessary LAM unmasking. Reset the address' tag early in copy_from_kernel_nofault_allowed() so pointer arithmetic checks before a __is_canonical_address() call can work properly. Signed-off-by: Maciej Wieczor-Retman --- Changelog v11: - Reset tag earlier in copy_from_kernel_nofault_allowed() so the is_vsyscall_vaddr() can properly check tagged pointers. - Redo the patch message. Changelog v9: - Redo the patch to not break KVM. - Remove Alexander's acked-by tag. Changelog v7: - Add Alexander's acked-by tag. - Add parentheses around vaddr_bits as suggested by checkpatch. - Apply the bitmasks to the __canonical_address() function which is used in kvm code. Changelog v6: - Use bitmasks to check both kernel and userspace addresses in the __is_canonical_address() (Dave Hansen and Samuel Holland). Changelog v4: - Add patch to the series. arch/x86/mm/maccess.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/mm/maccess.c b/arch/x86/mm/maccess.c index 42115ac079cf..7d8fa58b61b8 100644 --- a/arch/x86/mm/maccess.c +++ b/arch/x86/mm/maccess.c @@ -9,6 +9,7 @@ bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size) { unsigned long vaddr =3D (unsigned long)unsafe_src; + vaddr =3D __tag_reset(vaddr); =20 /* * Do not allow userspace addresses. This disallows --=20 2.53.0 From nobody Thu Apr 2 00:13:50 2026 Received: from mail-43103.protonmail.ch (mail-43103.protonmail.ch [185.70.43.103]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 010F52F260C for ; Mon, 30 Mar 2026 14:34:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.103 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881262; cv=none; b=jd1cGNUitUcvKGI4P5gkpMtfB8OFUxNEUXlltZHB+Q3oahkPhVh6r7LdMLfoLlfZnIah8kzqeU7Sjq/ATlhdEwpWu1NwfOxf+4zD7oh9IwcpldgSiFReKf3k/me33sQ6O62/X03z52gNz40FQ0WmcDWW7rcP4S699x2ShbA/yUw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881262; c=relaxed/simple; bh=Ha7lN9bSbT4rjqr83U4Yc2Wkef1ryrDJBI/LG3Mj2oQ=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=cUk6YgZKEe0bJl3nMrvq8+3TIqHA94kmwW6sSILJpIobMIqQSBt5ktaKsx/xNkfEq9/mtBi4jZ29KbIpOc258FO6Nt46pbVKe6+Bkz8BR9/dA0+ifN5DDO33zH3k0GjPLTOunledvk3HCGpD3StLqA0/LqtG97mPxDcXXDFxdTk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me; spf=pass smtp.mailfrom=pm.me; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b=INgmc5MI; arc=none smtp.client-ip=185.70.43.103 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pm.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b="INgmc5MI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1774881258; x=1775140458; bh=8q+A+Haremrmiz+feKlaHxC2ccHzsYvDqSm9RyNCONM=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=INgmc5MI9zB1qGGlxqncRh7B6x8iAPDeRUTMBtVs1WxesFCNDLJKgrUq2ivxuqr// QiO31YFpIsi0L3cqzB7cIOY2DghVhlp5Dkz1WNcZURSY++1tLNphd9h6EHWjYyIHcF 2jZxmwGQor0nDtEdEHbbNEXy/WOtEGgVZvTFm9D08h7q1BQOGhlzai19HuJ0pHhT10 FV3o667VsAr9K/n0mz82y08lbvN10OIyuDlVxRJ1wl3+ERfhKuiOfhAsjBwcKLuGQd zfbcPc/yBpDOTfY8B5oleG9uH9JxecUAqvEjxfc9iqx8t5hOfFK26hBPlvmecBPh+o kRLj+yYRVbKbg== Date: Mon, 30 Mar 2026 14:34:13 +0000 To: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Andy Lutomirski , Peter Zijlstra From: Maciej Wieczor-Retman Cc: m.wieczorretman@pm.me, Maciej Wieczor-Retman , Alexander Potapenko , linux-kernel@vger.kernel.org Subject: [PATCH v12 11/15] x86/mm: Initialize LAM_SUP Message-ID: <820f42da171d9a602d1c4cd83eefc7974025c642.1774872838.git.m.wieczorretman@pm.me> In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: 5f6782749c287a14d7ab8a7b4ee353d6e5040e7f Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Maciej Wieczor-Retman To make use of KASAN's tag based mode on x86, Linear Address Masking (LAM) needs to be enabled. To do a bit in CR4 has to be set. When launching secondary CPUs the LAM CR4 bit needs to be added to a mask in head_64.S. Bits that are not part of that mask are cleared when secondary CPUs are getting enabled by the primary one. Signed-off-by: Maciej Wieczor-Retman Acked-by: Alexander Potapenko --- Changelog v11: - Redo the patch message according to Dave's suggestions. Changelog v9: - Rename patch title so it fits the tip standards. Changelog v7: - Add Alexander's acked-by tag. Changelog v6: - boot_cpu_has() -> cpu_feature_enabled() arch/x86/kernel/head_64.S | 3 +++ arch/x86/mm/init.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 7ed5520dd52e..87d1c08fd932 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -209,6 +209,9 @@ SYM_INNER_LABEL(common_startup_64, SYM_L_LOCAL) * there will be no global TLB entries after the execution." */ movl $(X86_CR4_PAE | X86_CR4_LA57), %edx +#ifdef CONFIG_ADDRESS_MASKING + orl $X86_CR4_LAM_SUP, %edx +#endif #ifdef CONFIG_X86_MCE /* * Preserve CR4.MCE if the kernel will enable #MC support. diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index fb67217fddcd..11804ccf2fbb 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -763,6 +763,9 @@ void __init init_mem_mapping(void) probe_page_size_mask(); setup_pcid(); =20 + if (cpu_feature_enabled(X86_FEATURE_LAM) && IS_ENABLED(CONFIG_KASAN_SW_TA= GS)) + cr4_set_bits_and_update_boot(X86_CR4_LAM_SUP); + #ifdef CONFIG_X86_64 end =3D max_pfn << PAGE_SHIFT; #else --=20 2.53.0 From nobody Thu Apr 2 00:13:50 2026 Received: from mail-4322.protonmail.ch (mail-4322.protonmail.ch [185.70.43.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 55258302163 for ; Mon, 30 Mar 2026 14:34:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.22 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881267; cv=none; b=Ne8nA2/WEH0usYEB02Fv4sQ+Mrf6cUqCp9TGG4OhuEB393sFneO/VUVHwz2jfwKfmdINUH6S4LcpNhCExFgEeEH6lA/W8lExfwkRdVkGZMTdR7qq5m8TpYvnWFq5DLqSap0zkha7v4Ck/Tewdh/o+GLln+do+CcZ/AH88uEfAOA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881267; c=relaxed/simple; bh=rz7p9jc3KEAU2CN3A3kTwST1nAH3niP9Qkjh2cBt8hs=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=JIv4XmWdvvc/S8reMQD/VXZkFSEb/0LnMWmDj22bUW0pw18jt8LmNEL2xZUx0cTYyeIk9JLuYfb5MmxhnwzIfWWlqzmLZYHjeAqLuk7btSO77sHGASyMsoMq2IZca6XtrNY32hbBA9qLxp+li4yzzg2XTEdghGopiTTYN5SvNa0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me; spf=pass smtp.mailfrom=pm.me; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b=bqODVTob; arc=none smtp.client-ip=185.70.43.22 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pm.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b="bqODVTob" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1774881264; x=1775140464; bh=/GycTFJ6YqEM59YZ69bixAdyxP3vleuMSrnAsUVSYsk=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=bqODVTobwF3N4T/6S7/p96fZqjzSMu5rWm2pdBW2I4iSovnHKPTItXBAVK32LOEYQ Ib6movBqwFkcEIT7QGz0jYOVT22KwsByb6bLMu98YYD/G8TIaUe5XtPEv7M3I+9iaS MI4AIo+tcXmU9lolAEslzqynk5UPuiBuBTVBU3scHdUuV3KY/tpLTtl3uJhCxtcwGS 59gdNrLj34CrRg1GN4KqlBs8B1vVUhHVZxMGaTWwTCriKEi+rh2R/CPeSSfskk2f3F vtRULVkYr7zEX4+S/Zd14Ex/wzH1POtQKGmvpxMfAxpKoTIf4RnzIbA2BBGivs5l+D ZElRbcRFKw1ig== Date: Mon, 30 Mar 2026 14:34:19 +0000 To: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" From: Maciej Wieczor-Retman Cc: m.wieczorretman@pm.me, Maciej Wieczor-Retman , Andrey Konovalov , linux-kernel@vger.kernel.org Subject: [PATCH v12 12/15] x86: Increase minimal SLAB alignment for KASAN Message-ID: In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: 2b516d37f0e5df1f5405bae5c6e6e17b462357dd Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Maciej Wieczor-Retman 8 byte minimal SLAB alignment interferes with KASAN's granularity of 16 bytes. It causes a lot of out-of-bounds errors for unaligned 8 byte allocations. Compared to a kernel with KASAN disabled, the memory footprint increases because all kmalloc-8 allocations now are realized as kmalloc-16, which has twice the object size. But more meaningfully, when compared to a kernel with generic KASAN enabled, there is no difference. Because of redzones in generic KASAN, kmalloc-8' and kmalloc-16' object size is the same (48 bytes). So changing the minimal SLAB alignment of the tag-based mode doesn't have any negative impact when compared to the other software KASAN mode. Adjust x86 minimal SLAB alignment to match KASAN granularity size. Signed-off-by: Maciej Wieczor-Retman Reviewed-by: Andrey Konovalov --- Changelog v9: - Rename patch title so it fits the tip standards. Changelog v6: - Add Andrey's Reviewed-by tag. Changelog v4: - Extend the patch message with some more context and impact information. Changelog v3: - Fix typo in patch message 4 -> 16. - Change define location to arch/x86/include/asm/cache.c. arch/x86/include/asm/cache.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/include/asm/cache.h b/arch/x86/include/asm/cache.h index 69404eae9983..3232583b5487 100644 --- a/arch/x86/include/asm/cache.h +++ b/arch/x86/include/asm/cache.h @@ -21,4 +21,8 @@ #endif #endif =20 +#ifdef CONFIG_KASAN_SW_TAGS +#define ARCH_SLAB_MINALIGN (1ULL << KASAN_SHADOW_SCALE_SHIFT) +#endif + #endif /* _ASM_X86_CACHE_H */ --=20 2.53.0 From nobody Thu Apr 2 00:13:50 2026 Received: from mail-4322.protonmail.ch (mail-4322.protonmail.ch [185.70.43.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 13DDF3148C9 for ; Mon, 30 Mar 2026 14:34:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.22 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881272; cv=none; b=cSa6vypBPMmP8RMuI7RYGKxNqv7/28Ebezh1n4kLoKMnYX8oS7gbGTMINOVUfKW2erjxigMJdxzCL7UO48+iWzuQvaUhLpFTjKu0hBdljWDA8MouY2Slx1Y9LaBSGZtjGuk+dVtnOBTf2U4dEqRW6cs61p50nY5BfciDSH7RauY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881272; c=relaxed/simple; bh=LwNfxBWgQmpaN0N55me2m8MQEa8QkZFClIxbBKNRrBM=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=C+5EilaTOgUcfdr9m35fZcmBCyivMMWvN34+P03hVbJwlmD3cpHyJo/QD8jFG+TVJbCU7HYoMM5RsA3zDLGh7eP6giMLGaGxZPZGUzc48woGzdUYKPFQRIIgvBidwxE5jMP3Qpt8Ru+uWFdMzrAOmpKlzp1jKU+tRp6U3IZ/QPI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me; spf=pass smtp.mailfrom=pm.me; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b=Cwa05oM8; arc=none smtp.client-ip=185.70.43.22 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pm.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b="Cwa05oM8" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1774881268; x=1775140468; bh=iGV4u3tIjmDilzg0P4gIC9AUsBUkKpvQgpSv2yugQhc=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=Cwa05oM82wFyg3lhhabVDaLk/BqvscLtdRojlYkkQXVtAIu8VoElb6AKtIkSvzXNG ClL8kHz5z4+IT1RgM5YuUyX8ziJo25NyBYYjawzm7goklxcP+AFOiK8kp5U+OMLr3h iVEHYX2EJZWcpVKeFi1X6dFTNpdR7m9QlFXhgjLqHWfEtWXsWeuYrP8STLTAEBCrcQ LHgkqG2/wExRgSRqxMa+hG1k5OeF7oUODrso93gwnZ1AFcroJy0sxBECAayt4O0eVn Mh7b3zyx9Y24hd/5BIAplMjQxyLl36Am3mpUZnClfzhtbkZRby9oTuMRTM7CFp9v5l YWr9nk4554Fpw== Date: Mon, 30 Mar 2026 14:34:25 +0000 To: Andrey Ryabinin , Alexander Potapenko , Andrey Konovalov , Dmitry Vyukov , Vincenzo Frascino , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" From: Maciej Wieczor-Retman Cc: m.wieczorretman@pm.me, Maciej Wieczor-Retman , kasan-dev@googlegroups.com, linux-kernel@vger.kernel.org Subject: [PATCH v12 13/15] x86/kasan: Use a logical bit shift for kasan_mem_to_shadow Message-ID: <17b6cc428f2115fbb1421ace0143c9fc730bb166.1774872838.git.m.wieczorretman@pm.me> In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: 642f9f91beb2ffb0a81430d413c8865537107233 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Maciej Wieczor-Retman The tag-based KASAN adopts an arithemitc bit shift to convert a memory address to a shadow memory address. While it makes a lot of sense on arm64, it doesn't work well for all cases on x86 - either the non-canonical hook becomes quite complex for different paging levels, or the inline mode would need a lot more adjustments. Thus the best working scheme is the logical bit shift and non-canonical shadow offset that x86 uses for generic KASAN, of course adjusted for the increased granularity from 8 to 16 bytes. Add an arch specific implementation of kasan_mem_to_shadow() that uses the logical bit shift. Signed-off-by: Maciej Wieczor-Retman --- Changelog v11: - Remove arch_kasan_non_canonical_hook() since an arch independent version was added to the first patch in the series. Changelog v9: - Rename patch title so it fits the tip standards. - Take out the x86 part from mm/kasan/report.c and put it in the arch specific function. Adjust the patch message. Changelog v7: - Redo the patch message and add a comment to __kasan_mem_to_shadow() to provide better explanation on why x86 doesn't work well with the arithemitc bit shift approach (Marco). Changelog v4: - Add this patch to the series. arch/x86/include/asm/kasan.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/x86/include/asm/kasan.h b/arch/x86/include/asm/kasan.h index c868ae734f68..060ef997bfae 100644 --- a/arch/x86/include/asm/kasan.h +++ b/arch/x86/include/asm/kasan.h @@ -31,6 +31,21 @@ #include =20 #ifdef CONFIG_KASAN_SW_TAGS +/* + * Using the non-arch specific implementation of __kasan_mem_to_shadow() w= ith a + * arithmetic bit shift can cause high code complexity in KASAN's non-cano= nical + * hook for x86 or might not work for some paging level and KASAN mode + * combinations. The inline mode compiler support could also suffer from h= igher + * complexity for no specific benefit. Therefore the generic mode's logical + * shift implementation is used. + */ +static inline void *__kasan_mem_to_shadow(const void *addr) +{ + return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT) + + KASAN_SHADOW_OFFSET; +} +#define kasan_mem_to_shadow(addr) __kasan_mem_to_shadow(addr) + #define __tag_shifted(tag) FIELD_PREP(GENMASK_ULL(60, 57), tag) #define __tag_reset(addr) (sign_extend64((u64)(addr), 56)) #define __tag_get(addr) ((u8)FIELD_GET(GENMASK_ULL(60, 57), (u64)addr)) --=20 2.53.0 From nobody Thu Apr 2 00:13:50 2026 Received: from mail-4316.protonmail.ch (mail-4316.protonmail.ch [185.70.43.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 32C0E2F7ADE for ; Mon, 30 Mar 2026 14:34:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.16 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881280; cv=none; b=R5gXxcKZkthFVSvmsv0Ms1L7k7QsCTBByb9q4MRL0nmVgRLjuDyeYm9d6V7FFgo9svNpYMj4mRLwaakKfwRZLJx2o3CmtSPRRkUGrTrGEEF8fjt1CHdEoqGhtc08+he4d1Mr0bOW+eyo+ZnovGHCOSfZSHSJZi077w9lfTUzDDU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881280; c=relaxed/simple; bh=7iH3LVB6raB+8cSBD6faZ6jAuU7D2CfJAVIH3uRd3g0=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=reLuL1sM1PTAJyMWEwNCoMzOi9buA4gfMI+oxhHgALXLRPm3v8NB5rAc/Jq6NUVQvxyQI64YJWtkbrMcgPQChlJbXrO8oYj9O1c4EQbtV9bt8zDDEfyAmXnQXtGhWdL3DVVNLcKxLAn0v+tfypOgVP7r1eX8xYuZ949Fq40kHR8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me; spf=pass smtp.mailfrom=pm.me; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b=pr7eqQgM; arc=none smtp.client-ip=185.70.43.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pm.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b="pr7eqQgM" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1774881274; x=1775140474; bh=qLLLCvqo1LX+82C7sfL+nRVnDeD+vBvCbwCWC25/LJE=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=pr7eqQgMF8UDx4/AoLpt3QDKZulItdQkFyKdpDwLLiax7i41zBAavC+u8bptJb09b OZntgGxM3OvCHTMm/sUzkBGvcXLJtn45QeDFhVBI0B/8igIbGh90xSkWHvzx88sbMH LtQzjaRefepVW5VyF2ZhO5JPQB8RXZIHYA7iI84zkP0RQY+AuqZZ9mdKVSc1dtj9B5 uTagqJL7lIV23LynIit1u2Cn52ZLdzZsI8bd8kI67GzBswbXgSxPaFFGm1bVKFRITQ 3HLgLghmlcrCqY2T+Clj2CmZwm1QB6ONYZThZz6+WaeM+OYW7B+EAUJJWfHxG9GR0I aSIGpzI/a4sMA== Date: Mon, 30 Mar 2026 14:34:31 +0000 To: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Andrey Ryabinin , Alexander Potapenko , Andrey Konovalov , Dmitry Vyukov , Vincenzo Frascino , Andy Lutomirski , Peter Zijlstra , Andrew Morton From: Maciej Wieczor-Retman Cc: m.wieczorretman@pm.me, Maciej Wieczor-Retman , linux-kernel@vger.kernel.org, kasan-dev@googlegroups.com Subject: [PATCH v12 14/15] x86/kasan: Make software tag-based kasan available Message-ID: In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: 0dbea1d62116e604d557e6b6a3f980c4a1188a45 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Maciej Wieczor-Retman Make CONFIG_KASAN_SW_TAGS available for x86 machines if they have ADDRESS_MASKING enabled (LAM) as that works similarly to Top-Byte Ignore (TBI) that allows the software tag-based mode on arm64 platform. The value for sw_tags KASAN_SHADOW_OFFSET was calculated by rearranging the formulas for KASAN_SHADOW_START and KASAN_SHADOW_END from arch/x86/include/asm/kasan.h - the only prerequisites being KASAN_SHADOW_SCALE_SHIFT of 4, and KASAN_SHADOW_END equal to the one from KASAN generic mode. Set scale macro based on KASAN mode: in software tag-based mode 16 bytes of memory map to one shadow byte and 8 in generic mode. Disable CONFIG_KASAN_INLINE and CONFIG_KASAN_STACK when CONFIG_KASAN_SW_TAGS is enabled on x86 until the appropriate compiler support is available. Lock software tag KASAN behind CC_IS_CLANG due to lack of proper support by gcc resulting in kernel booting issues. Signed-off-by: Maciej Wieczor-Retman --- Changelog v12: - Put CC_IS_CLANG and ADDRESS_MASKING into one Kconfig option that will control whether KASAN sw-tags is available. Changelog v11: - Split off the documentation changes. - Rewrite the Kconfig.kasan entry for sw_tags. Changelog v10: - Update Documentation/dev-tools/kasan.rst with x86 related informations. Changelog v9: - Lock HAVE_ARCH_KASAN_HAS_SW_TAGS behind CC_IS_CLANG due to lack of support from gcc. - Remove pr_info() from KASAN initialization since it's now done by the generic init helper. - Add paragraph to the mm.rst to explain the mutual exclusive nature of the KASAN address ranges. - Use cpu_feature_enabled() instead of boot_cpu_has() in kasan_init_64.c. Changelog v7: - Add a paragraph to the patch message explaining how the various addresses and the KASAN_SHADOW_OFFSET were calculated. Changelog v6: - Don't enable KASAN if LAM is not supported. - Move kasan_init_tags() to kasan_init_64.c to not clutter the setup.c file. - Move the #ifdef for the KASAN scale shift here. - Move the gdb code to patch "Use arithmetic shift for shadow computation". - Return "depends on KASAN" line to Kconfig. - Add the defer kasan config option so KASAN can be disabled on hardware that doesn't have LAM. Changelog v4: - Add x86 specific kasan_mem_to_shadow(). - Revert x86 to the older unsigned KASAN_SHADOW_OFFSET. Do the same to KASAN_SHADOW_START/END. - Modify scripts/gdb/linux/kasan.py to keep x86 using unsigned offset. - Disable inline and stack support when software tags are enabled on x86. Changelog v3: - Remove runtime_const from previous patch and merge the rest here. - Move scale shift definition back to header file. - Add new kasan offset for software tag based mode. - Fix patch message typo 32 -> 16, and 16 -> 8. - Update lib/Kconfig.kasan with x86 now having software tag-based support. Changelog v2: - Remove KASAN dense code. arch/x86/Kconfig | 9 +++++++++ arch/x86/boot/compressed/misc.h | 1 + arch/x86/include/asm/kasan.h | 5 +++++ arch/x86/mm/kasan_init_64.c | 5 +++++ lib/Kconfig.kasan | 4 +++- 5 files changed, 23 insertions(+), 1 deletion(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c290fe363f27..ab8051939faf 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -67,6 +67,7 @@ config X86 select ARCH_CLOCKSOURCE_INIT select ARCH_CONFIGURES_CPU_MITIGATIONS select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE + select ARCH_DISABLE_KASAN_INLINE if X86_64 && KASAN_SW_TAGS select ARCH_ENABLE_HUGEPAGE_MIGRATION if X86_64 && HUGETLB_PAGE && MIGRAT= ION select ARCH_ENABLE_MEMORY_HOTPLUG if X86_64 select ARCH_ENABLE_SPLIT_PMD_PTLOCK if (PGTABLE_LEVELS > 2) && (X86_64 ||= X86_PAE) @@ -195,6 +196,8 @@ config X86 select HAVE_ARCH_JUMP_LABEL_RELATIVE select HAVE_ARCH_KASAN if X86_64 select HAVE_ARCH_KASAN_VMALLOC if X86_64 + select HAVE_ARCH_KASAN_SW_TAGS if X86_KASAN_SW_TAGS + select ARCH_NEEDS_DEFER_KASAN if KASAN_SW_TAGS select HAVE_ARCH_KFENCE select HAVE_ARCH_KMSAN if X86_64 select HAVE_ARCH_KGDB @@ -409,8 +412,14 @@ config AUDIT_ARCH config KASAN_SHADOW_OFFSET hex depends on KASAN + default 0xeffffc0000000000 if KASAN_SW_TAGS default 0xdffffc0000000000 =20 +config X86_KASAN_SW_TAGS + def_bool y + depends on CC_IS_CLANG + depends on ADDRESS_MASKING + config HAVE_INTEL_TXT def_bool y depends on INTEL_IOMMU && ACPI diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/mis= c.h index 4f86c5903e03..9bc1dcb0f8b0 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h @@ -14,6 +14,7 @@ #undef CONFIG_ARCH_HAS_LAZY_MMU_MODE #undef CONFIG_KASAN #undef CONFIG_KASAN_GENERIC +#undef CONFIG_KASAN_SW_TAGS =20 #define __NO_FORTIFY =20 diff --git a/arch/x86/include/asm/kasan.h b/arch/x86/include/asm/kasan.h index 060ef997bfae..f3d08a002aeb 100644 --- a/arch/x86/include/asm/kasan.h +++ b/arch/x86/include/asm/kasan.h @@ -6,7 +6,12 @@ #include #include #define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL) + +#ifdef CONFIG_KASAN_SW_TAGS +#define KASAN_SHADOW_SCALE_SHIFT 4 +#else #define KASAN_SHADOW_SCALE_SHIFT 3 +#endif =20 /* * Compiler uses shadow offset assuming that addresses start diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c index 7f5c11328ec1..8cbb8ec32061 100644 --- a/arch/x86/mm/kasan_init_64.c +++ b/arch/x86/mm/kasan_init_64.c @@ -465,4 +465,9 @@ void __init kasan_init(void) =20 init_task.kasan_depth =3D 0; kasan_init_generic(); + + if (cpu_feature_enabled(X86_FEATURE_LAM)) + kasan_init_sw_tags(); + else + pr_info("KernelAddressSanitizer not initialized (sw-tags): hardware does= n't support LAM\n"); } diff --git a/lib/Kconfig.kasan b/lib/Kconfig.kasan index a4bb610a7a6f..4be4e8943bd1 100644 --- a/lib/Kconfig.kasan +++ b/lib/Kconfig.kasan @@ -112,7 +112,9 @@ config KASAN_SW_TAGS =20 Requires GCC 11+ or Clang. =20 - Supported only on arm64 CPUs and relies on Top Byte Ignore. + Supported on: + arm64: CPUs with Top Byte Ignore + x86: CPUs with Linear Address Masking. =20 Consumes about 1/16th of available memory at kernel start and add an overhead of ~20% for dynamic allocations. --=20 2.53.0 From nobody Thu Apr 2 00:13:50 2026 Received: from mail-4322.protonmail.ch (mail-4322.protonmail.ch [185.70.43.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5EFD92FE59C; Mon, 30 Mar 2026 14:34:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.22 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881285; cv=none; b=EujF81kPNYsnNpPUUFlwST8FE8nzTmzZRaRlTBufNTK8zUZisQk5UqU5h/3iu9x1F8HHAyfiOz79q1GMBzZ42p/bcXisOnC8WbflF1xWxMIJdKnicvoIGSJ50++zabBDv1blZPfS28citpR+k8AXjWf6pH+Ab/WIsKXL69ZpzhE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774881285; c=relaxed/simple; bh=j3RO6GN6DceqVgbfJifPD7Mr4hXFOiKjw/TNqZPOPe0=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=kU048OOof5BUkq/phMlWu2rXvWBIZtpVtKqweBIp+SyY4MG4M3OkeIjiganm+r373S5ugjtFzJmBLdSWv4nJctpB85QWBeXqkv2CYAgu9S/LHZ+mehU/Y0SWS3Cpby1fZIG2VcO8f+PT1+DDczyx9Srobyt80mQr0jql8sY8eq8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me; spf=pass smtp.mailfrom=pm.me; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b=c7Tp3bYU; arc=none smtp.client-ip=185.70.43.22 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pm.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b="c7Tp3bYU" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1774881281; x=1775140481; bh=sI6qR0mJYdxFmMNIqBBXQAz3LXcRYa0zIgeJz3FHVi8=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=c7Tp3bYUuClM1sU2w9QzL2EoPaAcizdQb7LbZZMbNA2LGaXAC9Z7eKTNEJtRxFaJu Gn4NT2JjHES7LGElLAaBsZL7KIrbrOs6LDc62bVRvP4kPSAqTNfEEV6cRXq4R7MYhK 2aAU4Vl5/ZiMYg8UaSBik/7HF4Ne4oxG4w5FYeqFZ9ys7tesY0O1v9/EagR8/52ZhB K4+EQIZ/aEWgFYJiZjGrA2oRz8R7CMkVte9dV1n4Ht4xRO0WQ+covM+NIuA3Yu3sE+ Ft9hYMmrddYGsMe4V7br0rtvs3EDBn05zwuL8vf4Sl7kxblDprh8RANScRCeSxes+F Q5eBIT7vWrqZg== Date: Mon, 30 Mar 2026 14:34:37 +0000 To: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Jonathan Corbet , Shuah Khan , Andrey Ryabinin , Alexander Potapenko , Andrey Konovalov , Dmitry Vyukov , Vincenzo Frascino From: Maciej Wieczor-Retman Cc: m.wieczorretman@pm.me, Maciej Wieczor-Retman , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, kasan-dev@googlegroups.com, workflows@vger.kernel.org Subject: [PATCH v12 15/15] docs: Update KASAN and x86 memory map documentations Message-ID: In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: b24a4a44216345a8c35f780b91587fa32f629bc6 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Maciej Wieczor-Retman Update the documentation concerning changes to x86's memory address space and new architecture addition to KASAN's software tag-based mode. Redo paragraphs in KASAN's documentation on hardware and software implementation details to allow better extensibility. Signed-off-by: Maciej Wieczor-Retman --- Changelog v11: - Split off the documentation portion of v10's patch 13. - Apply Dave's suggestions to reformat the footer explaining alternate ranges for KASAN shadow memory, put arch hardware implementation in a separate paragraph and make a table to hold various implementation details. Documentation/arch/x86/x86_64/mm.rst | 21 +++++++++- Documentation/dev-tools/kasan.rst | 61 ++++++++++++++++++++-------- 2 files changed, 62 insertions(+), 20 deletions(-) diff --git a/Documentation/arch/x86/x86_64/mm.rst b/Documentation/arch/x86/= x86_64/mm.rst index a6cf05d51bd8..3c78ab1afd8d 100644 --- a/Documentation/arch/x86/x86_64/mm.rst +++ b/Documentation/arch/x86/x86_64/mm.rst @@ -60,7 +60,7 @@ Complete virtual memory map with 4-level page tables ffffe90000000000 | -23 TB | ffffe9ffffffffff | 1 TB | ... unused= hole ffffea0000000000 | -22 TB | ffffeaffffffffff | 1 TB | virtual me= mory map (vmemmap_base) ffffeb0000000000 | -21 TB | ffffebffffffffff | 1 TB | ... unused= hole - ffffec0000000000 | -20 TB | fffffbffffffffff | 16 TB | KASAN shad= ow memory + ffffec0000000000 | -20 TB | fffffbffffffffff | 16 TB | KASAN shad= ow memory[1] __________________|____________|__________________|_________|___________= _________________________________________________ | | Identical = layout to the 56-bit one from here on: @@ -130,7 +130,7 @@ Complete virtual memory map with 5-level page tables ffd2000000000000 | -11.5 PB | ffd3ffffffffffff | 0.5 PB | ... unused= hole ffd4000000000000 | -11 PB | ffd5ffffffffffff | 0.5 PB | virtual me= mory map (vmemmap_base) ffd6000000000000 | -10.5 PB | ffdeffffffffffff | 2.25 PB | ... unused= hole - ffdf000000000000 | -8.25 PB | fffffbffffffffff | ~8 PB | KASAN shad= ow memory + ffdf000000000000 | -8.25 PB | fffffbffffffffff | ~8 PB | KASAN shad= ow memory[1] __________________|____________|__________________|_________|___________= _________________________________________________ | | Identical = layout to the 47-bit one from here on: @@ -178,3 +178,20 @@ correct as KASAN disables KASLR. =20 For both 4- and 5-level layouts, the KSTACK_ERASE_POISON value in the last= 2MB hole: ffffffffffff4111 + +1. The range is different based on what KASAN mode is used and what paging= level + is used: + +:: + + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D + Start addr | Offset | End addr | Size | VM area de= scription + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D + | | | | 4-level pa= ging: + ffffec0000000000 | -20 TB | fffffbffffffffff | 16 TB | KASAN shad= ow memory (generic mode) + fffff40000000000 | -8 TB | fffffbffffffffff | 8 TB | KASAN shad= ow memory (software tag-based mode) + __________________|____________|__________________|_________|___________= ____________________________________ + | | | | 5-level pa= ging: + ffdf000000000000 | -8.25 PB | fffffbffffffffff | ~8 PB | KASAN shad= ow memory (generic mode) + ffeffc0000000000 | -6 PB | fffffbffffffffff | 4 PB | KASAN shad= ow memory (software tag-based mode) + __________________|____________|__________________|_________|___________= ____________________________________ diff --git a/Documentation/dev-tools/kasan.rst b/Documentation/dev-tools/ka= san.rst index b11c1be8dff4..d42d80e9fcf1 100644 --- a/Documentation/dev-tools/kasan.rst +++ b/Documentation/dev-tools/kasan.rst @@ -22,8 +22,8 @@ architectures, but it has significant performance and mem= ory overheads. =20 Software Tag-Based KASAN or SW_TAGS KASAN, enabled with CONFIG_KASAN_SW_TA= GS, can be used for both debugging and dogfood testing, similar to userspace H= WASan. -This mode is only supported for arm64, but its moderate memory overhead al= lows -using it for testing on memory-restricted devices with real workloads. +This mode is only supported for arm64 and x86, but its moderate memory ove= rhead +allows using it for testing on memory-restricted devices with real workloa= ds. =20 Hardware Tag-Based KASAN or HW_TAGS KASAN, enabled with CONFIG_KASAN_HW_TA= GS, is the mode intended to be used as an in-field memory bug detector or as a @@ -346,16 +346,21 @@ Software Tag-Based KASAN ~~~~~~~~~~~~~~~~~~~~~~~~ =20 Software Tag-Based KASAN uses a software memory tagging approach to checki= ng -access validity. It is currently only implemented for the arm64 architectu= re. - -Software Tag-Based KASAN uses the Top Byte Ignore (TBI) feature of arm64 C= PUs -to store a pointer tag in the top byte of kernel pointers. It uses shadow = memory -to store memory tags associated with each 16-byte memory cell (therefore, = it -dedicates 1/16th of the kernel memory for shadow memory). - -On each memory allocation, Software Tag-Based KASAN generates a random tag= , tags -the allocated memory with this tag, and embeds the same tag into the retur= ned -pointer. +access validity. It is currently only implemented for the arm64 and x86 +architectures. To function, special hardware CPU features* are needed for +repurposing space inside the kernel pointers to store pointer tags. + +Software Tag-Based mode uses shadow memory to store memory tags associated= with +each 16-byte memory cell (therefore, it dedicates 1/16th of the kernel mem= ory +for shadow memory). On each memory allocation, Software Tag-Based KASAN +generates a random tag, tags the allocated memory with this tag, and embed= s the +same tag into the returned pointer. + +Two special tag values can be distinguished. A match-all pointer tag (othe= rwise +called the 'kernel tag' because it's supposed to be equal to the value nor= mally +present in the same bits of the linear address when KASAN is disabled) - +accesses through such pointers are not checked. Another value is also rese= rved +to tag freed memory regions. =20 Software Tag-Based KASAN uses compile-time instrumentation to insert checks before each memory access. These checks make sure that the tag of the memo= ry @@ -367,12 +372,32 @@ Software Tag-Based KASAN also has two instrumentation= modes (outline, which emits callbacks to check memory accesses; and inline, which performs the s= hadow memory checks inline). With outline instrumentation mode, a bug report is printed from the function that performs the access check. With inline -instrumentation, a ``brk`` instruction is emitted by the compiler, and a -dedicated ``brk`` handler is used to print bug reports. - -Software Tag-Based KASAN uses 0xFF as a match-all pointer tag (accesses th= rough -pointers with the 0xFF pointer tag are not checked). The value 0xFE is cur= rently -reserved to tag freed memory regions. +instrumentation, the compiler emits a specific arch-dependent instruction = with a +dedicated handler to print bug reports. + +Architecture specific details: + +:: + + +-----------------------+--------+---------------------+ + | detail \ architecture | arm64 | x86 | + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+= =3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D+ + | Hardware feature | TBI | LAM | + +-----------------------+--------+---------------------+ + | Kernel tag | 0xFF | 0x0F | + +-----------------------+--------+---------------------+ + | Freed memory tag | 0xFE | 0x0E | + +-----------------------+--------+---------------------+ + | Tag width | 8 bits | 4 bits | + +-----------------------+--------+---------------------+ + | Inline instruction | brk | no compiler support | + +-----------------------+--------+---------------------+ + +* Different architectures implement different hardware features to mask and + repurpose linear address bits. arm64 utilizes Top Byte Ignore (TBI) to m= ask + out and allow storing tags in the top byte of the pointer. x86 uses Line= ar + Address Masking (LAM) to store tags in the four bits of the kernel point= er's + top byte. =20 Hardware Tag-Based KASAN ~~~~~~~~~~~~~~~~~~~~~~~~ --=20 2.53.0