- 10 Nov, 2020 37 commits
-
-
This change updates KASAN documentation to reflect the addition of boot parameters and also reworks and clarifies some of the existing sections, in particular: defines what a memory granule is, mentions quarantine, makes Kunit section more readable. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com>
-
The reason cache merging is disabled with KASAN is because KASAN puts its metadata right after the allocated object. When the merged caches have slightly different sizes, the metadata ends up in different places, which KASAN doesn't support. It might be possible to adjust the metadata allocation algorithm and make it friendly to the cache merging code. Instead this change takes a simpler approach and allows merging caches when no metadata is present. Which is the case for hardware tag-based KASAN with kasan.mode=prod. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Link: https://linux-review.googlesource.com/id/Ia114847dfb2244f297d2cb82d592bf6a07455dba
-
KASAN marks caches that are sanitized with the SLAB_KASAN cache flag. Currently if the metadata that is appended after the object (stores e.g. stack trace ids) doesn't fit into KMALLOC_MAX_SIZE (can only happen with SLAB, see the comment in the patch), KASAN turns off sanitization completely. With this change sanitization of the object data is always enabled. However the metadata is only stored when it fits. Instead of checking for SLAB_KASAN flag accross the code to find out whether the metadata is there, use cache->kasan_info.alloc/free_meta_offset. As 0 can be a valid value for free_meta_offset, introduce KASAN_NO_FREE_META as an indicator that the free metadata is missing. Along the way rework __kasan_cache_create() and add claryfying comments. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Link: https://linux-review.googlesource.com/id/Icd947e2bea054cb5cfbdc6cf6652227d97032dcb
-
Currently it says that the memory gets poisoned by page_alloc code. Clarify this by mentioning the specific callback that poisons the memory. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Reviewed-by:
Dmitry Vyukov <dvyukov@google.com> Link: https://linux-review.googlesource.com/id/I1334dffb69b87d7986fab88a1a039cc3ea764725
-
set_tag() already ignores the tag for the generic mode, so just call it as is. Add a check for the generic mode to assign_tag(), and simplify its call in ____kasan_kmalloc(). Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Reviewed-by:
Dmitry Vyukov <dvyukov@google.com> Link: https://linux-review.googlesource.com/id/I18905ca78fb4a3d60e1a34a4ca00247272480438
-
For hardware tag-based mode kasan_poison_memory() already rounds up the size. Do the same for software modes and remove round_up() from the common code. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Reviewed-by:
Dmitry Vyukov <dvyukov@google.com> Link: https://linux-review.googlesource.com/id/Ib397128fac6eba874008662b4964d65352db4aa4
-
Rename kasan_poison_kfree() to kasan_slab_free_mempool() as it better reflects what this annotation does. No functional changes. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Reviewed-by:
Dmitry Vyukov <dvyukov@google.com> Link: https://linux-review.googlesource.com/id/I5026f87364e556b506ef1baee725144bb04b8810
-
kasan_poison_kfree() is currently only called for mempool allocations that are backed by either kmem_cache_alloc() or kmalloc(). Therefore, the page passed to kasan_poison_kfree() is always PageSlab() and there's no need to do the check. Remove it. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Reviewed-by:
Dmitry Vyukov <dvyukov@google.com> Link: https://linux-review.googlesource.com/id/If31f88726745da8744c6bea96fb32584e6c2778c
-
Declare the kasan_enabled static key in include/linux/kasan.h and in include/linux/mm.h and check it in all kasan annotations. This allows to avoid any slowdown caused by function calls when kasan_enabled is disabled. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Link: https://linux-review.googlesource.com/id/I2589451d3c96c97abbcbf714baabe6161c6f153e
-
Hardware tag-based KASAN mode is intended to eventually be used in production as a security mitigation. Therefore there's a need for finer control over KASAN features and for an existence of a kill switch. This change adds a few boot parameters for hardware tag-based KASAN that allow to disable or otherwise control particular KASAN features. The features that can be controlled are: 1. Whether KASAN is enabled at all. 2. Whether KASAN collects and saves alloc/free stacks. 3. Whether KASAN panics on a detected bug or not. With this change a new boot parameter kasan.mode allows to choose one of three main modes: - kasan.mode=off - KASAN is disabled, no tag checks are performed - kasan.mode=prod - only essential production features are enabled - kasan.mode=full - all KASAN features are enabled The chosen mode provides default control values for the features mentioned above. However it's also possible to override the default values by providing: - kasan.stacktrace=off/on - enable alloc/free stack collection (default: on for mode=full, otherwise off) - kasan.fault=report/panic - only report tag fault or also panic (default: report) If kasan.mode parameter is not provided, it defaults to full when CONFIG_DEBUG_KERNEL is enabled, and to prod otherwise. It is essential that switching between these modes doesn't require rebuilding the kernel with different configs, as this is required by the Android GKI (Generic Kernel Image) initiative [1]. [1] https://source.android.com/devices/architecture/kernel/generic-kernel-image Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Link: https://linux-review.googlesource.com/id/If7d37003875b2ed3e0935702c8015c223d6416a4
-
Currently kasan_unpoison_memory() is used as both an external annotation and as an internal memory poisoning helper. Rename external annotation to kasan_unpoison_data() and inline the internal helper for hardware tag-based mode to avoid undeeded function calls. There's the external annotation kasan_unpoison_slab() that is currently defined as static inline and uses kasan_unpoison_memory(). With this change it's turned into a function call. Overall, this results in the same number of calls for hardware tag-based mode as kasan_unpoison_memory() is now inlined. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Link: https://linux-review.googlesource.com/id/Ia7c8b659f79209935cbaab3913bf7f082cc43a0e
-
Using kasan_poison_memory() or check_invalid_free() currently results in function calls. Move their definitions to mm/kasan/kasan.h and turn them into static inline functions for hardware tag-based mode to avoid unneeded function calls. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Reviewed-by:
Dmitry Vyukov <dvyukov@google.com> Link: https://linux-review.googlesource.com/id/Ia9d8191024a12d1374675b3d27197f10193f50bb
-
Using random_tag() currently results in a function call. Move its definition to mm/kasan/kasan.h and turn it into a static inline function for hardware tag-based mode to avoid uneeded function calls. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Link: https://linux-review.googlesource.com/id/Iac5b2faf9a912900e16cca6834d621f5d4abf427
-
Using kasan_reset_tag() currently results in a function call. As it's called quite often from the allocator code, this leads to a noticeable slowdown. Move it to include/linux/kasan.h and turn it into a static inline function. Also remove the now unneeded reset_tag() internal KASAN macro and use kasan_reset_tag() instead. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Link: https://linux-review.googlesource.com/id/I4d2061acfe91d480a75df00b07c22d8494ef14b5
-
There's no need for __kasan_unpoison_stack() helper, as it's only currently used in a single place. Removing it also removes unneeded arithmetic. No functional changes. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Reviewed-by:
Dmitry Vyukov <dvyukov@google.com> Link: https://linux-review.googlesource.com/id/Ie5ba549d445292fe629b4a96735e4034957bcc50
-
Even though hardware tag-based mode currently doesn't support checking vmalloc allocations, it doesn't use shadow memory and works with VMAP_STACK as is. Change VMAP_STACK definition accordingly. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Link: https://linux-review.googlesource.com/id/I3552cbc12321dec82cd7372676e9372a2eb452ac
-
There's a config option CONFIG_KASAN_STACK that has to be enabled for KASAN to use stack instrumentation and perform validity checks for stack variables. There's no need to unpoison stack when CONFIG_KASAN_STACK is not enabled. Only call kasan_unpoison_task_stack[_below]() when CONFIG_KASAN_STACK is enabled. Note, that CONFIG_KASAN_STACK is an option that is currently always defined when CONFIG_KASAN is enabled, and therefore has to be tested with #if instead of #ifdef. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Link: https://linux-review.googlesource.com/id/If8a891e9fe01ea543e00b576852685afec0887e3
-
Add set_alloc_info() helper and move kasan_set_track() into it. This will simplify the code for one of the upcoming changes. No functional changes. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Reviewed-by:
Dmitry Vyukov <dvyukov@google.com> Link: https://linux-review.googlesource.com/id/I0316193cbb4ecc9b87b7c2eee0dd79f8ec908c1a
-
Rename get_alloc_info() and get_free_info() to kasan_get_alloc_meta() and kasan_get_free_meta() to better reflect what those do and avoid confusion with kasan_set_free_info(). No functional changes. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Reviewed-by:
Dmitry Vyukov <dvyukov@google.com> Link: https://linux-review.googlesource.com/id/Ib6e4ba61c8b12112b403d3479a9799ac8fff8de1
-
Move get_free_info() call into quarantine_put() to simplify the call site. No functional changes. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Reviewed-by:
Dmitry Vyukov <dvyukov@google.com> Link: https://linux-review.googlesource.com/id/Iab0f04e7ebf8d83247024b7190c67c3c34c7940f
-
Vincenzo Frascino authored
This test is specific to MTE and verifies that the GCR_EL1 register is context switched correctly. It spawn 1024 processes and each process spawns 5 threads. Each thread writes a random setting of GCR_EL1 through the prctl() system call and reads it back verifying that it is the same. If the values are not the same it reports a failure. Note: The test has been extended to verify that even SYNC and ASYNC mode setting is preserved correctly over context switching. Signed-off-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> --- Change-Id: Ia917684a2b8e5f29e705ca5cbf360b010df6f61e
-
Add documentation for hardware tag-based KASAN mode and also add some clarifications for software tag-based mode. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Signed-off-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Reviewed-by:
Marco Elver <elver@google.com> --- Change-Id: Ib46cb444cfdee44054628940a82f5139e10d0258
-
Hardware tag-based KASAN is now ready, enable the configuration option. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Signed-off-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Acked-by:
Catalin Marinas <catalin.marinas@arm.com> --- Change-Id: I6eb1eea770e6b61ad71c701231b8d815a7ccc853
-
Kernel allocator code accesses metadata for slab objects, that may lie out-of-bounds of the object itself, or be accessed when an object is freed. Such accesses trigger tag faults and lead to false-positive reports with hardware tag-based KASAN. Software KASAN modes disable instrumentation for allocator code via KASAN_SANITIZE Makefile macro, and rely on kasan_enable/disable_current() annotations which are used to ignore KASAN reports. With hardware tag-based KASAN neither of those options are available, as it doesn't use compiler instrumetation, no tag faults are ignored, and MTE is disabled after the first one. Instead, reset tags when accessing metadata (currently only for SLUB). Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Signed-off-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Acked-by:
Marco Elver <elver@google.com> --- Change-Id: I39f3c4d4f29299d4fbbda039bedf230db1c746fb
-
Add error reporting for hardware tag-based KASAN. When CONFIG_KASAN_HW_TAGS is enabled, print KASAN report from the arm64 tag fault handler. SAS bits aren't set in ESR for all faults reported in EL1, so it's impossible to find out the size of the access the caused the fault. Adapt KASAN reporting code to handle this case. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Co-developed-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Signed-off-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Reviewed-by:
Catalin Marinas <catalin.marinas@arm.com> --- Change-Id: I3780fe7db6e075dff2937d3d8508f55c9322b095
-
Provide implementation of KASAN functions required for the hardware tag-based mode. Those include core functions for memory and pointer tagging (tags_hw.c) and bug reporting (report_tags_hw.c). Also adapt common KASAN code to support the new mode. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Signed-off-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Acked-by:
Catalin Marinas <catalin.marinas@arm.com> --- Change-Id: I8a8689ba098174a4d0ef3f1d008178387c80ee1c
-
Some #ifdef CONFIG_KASAN checks are only relevant for software KASAN modes (either related to shadow memory or compiler instrumentation). Expand those into CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Signed-off-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Reviewed-by:
Catalin Marinas <catalin.marinas@arm.com> --- Change-Id: I91e661e2c1627783cb845d877c6371dfc8779505
-
With the intoduction of hardware tag-based KASAN some kernel checks of this kind: ifdef CONFIG_KASAN will be updated to: if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) x86 and s390 use a trick to #undef CONFIG_KASAN for some of the code that isn't linked with KASAN runtime and shouldn't have any KASAN annotations. Also #undef CONFIG_KASAN_GENERIC with CONFIG_KASAN. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Signed-off-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Reviewed-by:
Marco Elver <elver@google.com> Acked-by:
Vasily Gorbik <gor@linux.ibm.com> --- Change-Id: I2a622db0cb86a8feb60c30d8cb09190075be2a90
-
Hardware tag-based KASAN has granules of MTE_GRANULE_SIZE. Define KASAN_GRANULE_SIZE to MTE_GRANULE_SIZE for CONFIG_KASAN_HW_TAGS. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Signed-off-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Reviewed-by:
Marco Elver <elver@google.com> --- Change-Id: I5d1117e6a991cbca00d2cfb4ba66e8ae2d8f513a
-
This patch add a set of arch_*() memory tagging helpers currently only defined for arm64 when hardware tag-based KASAN is enabled. These helpers will be used by KASAN runtime to implement the hardware tag-based mode. The arch-level indirection level is introduced to simplify adding hardware tag-based KASAN support for other architectures in the future by defining the appropriate arch_*() macros. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Co-developed-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Signed-off-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Reviewed-by:
Catalin Marinas <catalin.marinas@arm.com> --- Change-Id: I42b0795a28067872f8308e00c6f0195bca435c2a
-
Hardware tag-based KASAN uses the memory tagging approach, which requires all allocations to be aligned to the memory granule size. Align the allocations to MTE_GRANULE_SIZE via ARCH_SLAB_MINALIGN when CONFIG_KASAN_HW_TAGS is enabled. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Signed-off-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Reviewed-by:
Catalin Marinas <catalin.marinas@arm.com> --- Change-Id: I51ebd3f9645e6330e5a92973bf7c86b62d632c2b
-
Vincenzo Frascino authored
free_reserved_area() memsets the pages belonging to a given memory area. To do that retrieves the page address via page_address(). For the architectures that support KASAN the pointer to the page can be tagged as a result of page_address() but the underlying memory untouched by any allocator. This scenario causes a tag fault during the memset() operation. Untag the address to avoid spurious faults. Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by:
Vincenzo Frascino <vincenzo.frascino@arm.com>
-
Vincenzo Frascino authored
When MTE is present, the GCR_EL1 register contains the tags mask that allows to exclude tags from the random generation via the IRG instruction. With the introduction of the new Tag-Based KASAN API that provides a mechanism to reserve tags for special reasons, the MTE implementation has to make sure that the GCR_EL1 setting for the kernel does not affect the userspace processes and viceversa. Save and restore the kernel/user mask in GCR_EL1 in kernel entry and exit. Signed-off-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Co-developed-by:
Andrey Konovalov <andreyknvl@google.com> Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Reviewed-by:
Catalin Marinas <catalin.marinas@arm.com> --- Change-Id: I0081cba5ace27a9111bebb239075c9a466af4c84
-
Vincenzo Frascino authored
The gcr_user mask is a per thread mask that represents the tags that are excluded from random generation when the Memory Tagging Extension is present and an 'irg' instruction is invoked. gcr_user affects the behavior on EL0 only. Currently that mask is an include mask and it is controlled by the user via prctl() while GCR_EL1 accepts an exclude mask. Convert the include mask into an exclude one to make it easier the register setting. Note: This change will affect gcr_kernel (for EL1) introduced with a future patch. Signed-off-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Reviewed-by:
Catalin Marinas <catalin.marinas@arm.com> --- Change-Id: Id15c0b47582fb51594bb26fb8353d78c7d0953c1
-
Vincenzo Frascino authored
Hardware tag-based KASAN relies on Memory Tagging Extension (MTE) feature and requires it to be enabled. MTE supports This patch adds a new mte_init_tags() helper, that enables MTE in Synchronous mode in EL1 and is intended to be called from KASAN runtime during initialization. The Tag Checking operation causes a synchronous data abort as a consequence of a tag check fault when MTE is configured in synchronous mode. As part of this change enable match-all tag for EL1 to allow the kernel to access user pages without faulting. This is required because the kernel does not have knowledge of the tags set by the user in a page. Note: For MTE, the TCF bit field in SCTLR_EL1 affects only EL1 in a similar way as TCF0 affects EL0. MTE that is built on top of the Top Byte Ignore (TBI) feature hence we enable it as part of this patch as well. Signed-off-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Co-developed-by:
Andrey Konovalov <andreyknvl@google.com> Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> --- Change-Id: I4d67497268bb7f0c2fc5dcacefa1e273df4af71d
-
Vincenzo Frascino authored
Add the implementation of the in-kernel fault handler. When a tag fault happens on a kernel address: * MTE is disabled on the current CPU, * the execution continues. When a tag fault happens on a user address: * the kernel executes do_bad_area() and panics. The tag fault handler for kernel addresses is currently empty and will be filled in by a future commit. Signed-off-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Co-developed-by:
Andrey Konovalov <andreyknvl@google.com> Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Reviewed-by:
Catalin Marinas <catalin.marinas@arm.com> --- Change-Id: I9b8aa79567f7c45f4d6a1290efcf34567e620717
-
Vincenzo Frascino authored
The hardware tag-based KASAN for compatibility with the other modes stores the tag associated to a page in page->flags. Due to this the kernel faults on access when it allocates a page with an initial tag and the user changes the tags. Reset the tag associated by the kernel to a page in all the meaningful places to prevent kernel faults on access. Note: An alternative to this approach could be to modify page_to_virt(). This though could end up being racy, in fact if a CPU checks the PG_mte_tagged bit and decides that the page is not tagged but another CPU maps the same with PROT_MTE and becomes tagged the subsequent kernel access would fail. Signed-off-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> --- Change-Id: I8451d438bb63364de2a3e68041e3a27866921d4e
-
- 09 Nov, 2020 3 commits
-
-
Vincenzo Frascino authored
Provide helper functions to manipulate allocation and pointer tags for kernel addresses. Low-level helper functions (mte_assign_*, written in assembly) operate tag values from the [0x0, 0xF] range. High-level helper functions (mte_get/set_*) use the [0xF0, 0xFF] range to preserve compatibility with normal kernel pointers that have 0xFF in their top byte. MTE_GRANULE_SIZE and related definitions are moved to mte-def.h header that doesn't have any dependencies and is safe to include into any low-level header. Signed-off-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Co-developed-by:
Andrey Konovalov <andreyknvl@google.com> Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Reviewed-by:
Catalin Marinas <catalin.marinas@arm.com> --- Change-Id: I1b5230254f90dc21a913447cb17f07fea7944ece
-
Vincenzo Frascino authored
Hardware tag-based KASAN relies on Memory Tagging Extension (MTE) which is an armv8.5-a architecture extension. Enable the correct asm option when the compiler supports it in order to allow the usage of ALTERNATIVE()s with MTE instructions. Signed-off-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Reviewed-by:
Catalin Marinas <catalin.marinas@arm.com> --- Change-Id: I172e15e4c189f073e4c14a10276b276092e76536
-
Andrey Konovalov authored
This patch adds a configuration option for a new KASAN mode called hardware tag-based KASAN. This mode uses the memory tagging approach like the software tag-based mode, but relies on arm64 Memory Tagging Extension feature for tag management and access checking. Signed-off-by:
Andrey Konovalov <andreyknvl@google.com> Co-developed-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Signed-off-by:
Vincenzo Frascino <vincenzo.frascino@arm.com> Reviewed-by:
Marco Elver <elver@google.com> --- Change-Id: I246c2def9fffa6563278db1bddfbe742ca7bdefe
-