linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Matteo Rizzo <matteorizzo@google.com>
To: cl@linux.com, penberg@kernel.org, rientjes@google.com,
	 iamjoonsoo.kim@lge.com, akpm@linux-foundation.org,
	vbabka@suse.cz,  roman.gushchin@linux.dev, 42.hyeyoo@gmail.com,
	keescook@chromium.org,  linux-kernel@vger.kernel.org,
	linux-doc@vger.kernel.org, linux-mm@kvack.org,
	 linux-hardening@vger.kernel.org, tglx@linutronix.de,
	mingo@redhat.com,  bp@alien8.de, dave.hansen@linux.intel.com,
	x86@kernel.org, hpa@zytor.com,  corbet@lwn.net, luto@kernel.org,
	peterz@infradead.org
Cc: jannh@google.com, matteorizzo@google.com, evn@google.com,
	 poprdi@google.com, jordyzomer@google.com
Subject: [RFC PATCH 14/14] security: add documentation for SLAB_VIRTUAL
Date: Fri, 15 Sep 2023 10:59:33 +0000	[thread overview]
Message-ID: <20230915105933.495735-15-matteorizzo@google.com> (raw)
In-Reply-To: <20230915105933.495735-1-matteorizzo@google.com>

From: Jann Horn <jannh@google.com>

Document what SLAB_VIRTUAL is trying to do, how it's implemented, and
why.

Signed-off-by: Jann Horn <jannh@google.com>
Co-developed-by: Matteo Rizzo <matteorizzo@google.com>
Signed-off-by: Matteo Rizzo <matteorizzo@google.com>
---
 Documentation/security/self-protection.rst | 102 +++++++++++++++++++++
 1 file changed, 102 insertions(+)

diff --git a/Documentation/security/self-protection.rst b/Documentation/security/self-protection.rst
index 910668e665cb..5a5e99e3f244 100644
--- a/Documentation/security/self-protection.rst
+++ b/Documentation/security/self-protection.rst
@@ -314,3 +314,105 @@ To help kill classes of bugs that result in kernel addresses being
 written to userspace, the destination of writes needs to be tracked. If
 the buffer is destined for userspace (e.g. seq_file backed ``/proc`` files),
 it should automatically censor sensitive values.
+
+
+Memory Allocator Mitigations
+============================
+
+Protection against cross-cache attacks (SLAB_VIRTUAL)
+-----------------------------------------------------
+
+SLAB_VIRTUAL is a mitigation that deterministically prevents cross-cache
+attacks.
+
+Linux Kernel use-after-free vulnerabilities are commonly exploited by turning
+them into an object type confusion (having two active pointers of different
+types to the same memory location) using one of the following techniques:
+
+1. Direct object reuse: make the kernel give the victim object back to the slab
+   allocator, then allocate the object again from the same slab cache as a
+   different type. This is only possible if the victim object resides in a slab
+   cache which can contain objects of different types - for example one of the
+   kmalloc caches.
+2. "Cross-cache attack": make the kernel give the victim object back to the slab
+   allocator, then make the slab allocator give the page containing the object
+   back to the page allocator, then either allocate the page directly as some
+   other type of page or make the slab allocator allocate it again for a
+   different slab cache and allocate an object from there.
+
+In either case, the important part is that the same virtual address is reused
+for two objects of different types.
+
+The first case can be addressed by separating objects of different types
+into different slab caches. If a slab cache only contains objects of the
+same type then directly turning an use-after-free into a type confusion is
+impossible as long as the slab page that contains the victim object remains
+assigned to that slab cache. This type of mitigation is easily bypassable
+by cross-cache attacks: if the attacker can make the slab allocator return
+the page containing the victim object to the page allocator and then make
+it use the same page for a different slab cache, type confusion becomes
+possible again. Addressing the first case is therefore only worthwhile if
+cross-cache attacks are also addressed. AUTOSLAB uses a combination of
+probabilistic mitigations for this. SLAB_VIRTUAL addresses the second case
+deterministically by changing the way the slab allocator allocates memory.
+
+Preventing slab virtual address reuse
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In theory there is an easy fix against cross-cache attacks: modify the slab
+allocator so that it never gives memory back to the page allocator. In practice
+this would be problematic because physical memory remains permanently assigned
+to a slab cache even if it doesn't contain any active objects. A viable
+cross-cache mitigation must allow the system to reclaim unused physical memory.
+In the current design of the slab allocator there is no way
+to keep a region of virtual memory permanently assigned to a slab cache without
+also permanently reserving physical memory. That is because the virtual
+addresses that the slab allocator uses come from the linear map region, where
+there is a 1:1 correspondence between virtual and physical addresses.
+
+SLAB_VIRTUAL's solution is to create a dedicated virtual memory region that is
+only used for slab memory, and to enforce that once a range of virtual addresses
+is used for a slab cache, it is never reused for any other caches. Using a
+dedicated region of virtual memory lets us reserve ranges of virtual addresses
+to prevent cross-cache attacks and at the same time release physical memory back
+to the system when it's no longer needed. This is what Chromium's PartitionAlloc
+does in userspace
+(https://chromium.googlesource.com/chromium/src/+/354da2514b31df2aa14291199a567e10a7671621/base/allocator/partition_allocator/PartitionAlloc.md).
+
+Implementation
+~~~~~~~~~~~~~~
+
+SLAB_VIRTUAL reserves a region of virtual memory for the slab allocator. All
+pointers returned by the slab allocator point to this region. The region is
+statically partitioned in two sub-regions: the metadata region and the data
+region. The data region is where the actual objects are allocated from. The
+metadata region is an array of struct slab objects, one for each PAGE_SIZE bytes
+in the data region.
+Without SLAB_VIRTUAL, struct slab is overlaid on top of the struct page/struct
+folio that corresponds to the physical memory page backing the slab instead of
+using a dedicated memory region. This doesn't work for SLAB_VIRTUAL, which needs
+to store metadata for slabs even when no physical memory is allocated to them.
+Having an array of struct slab lets us implement virt_to_slab efficiently purely
+with arithmetic. In order to support high-order slabs, the struct slabs
+corresponding to tail pages contain a pointer to the head slab, which
+corresponds to the slab's head page.
+
+TLB flushing
+~~~~~~~~~~~~
+
+Before it can release a page of physical memory back to the page allocator, the
+slab allocator must flush the TLB entries for that page on all CPUs. This is not
+only necessary for the mitigation to work reliably but it's also required for
+correctness. Without a TLB flush some CPUs might continue using the old mapping
+if the virtual address range is reused for a new slab and cause memory
+corruption even in the absence of other bugs. The slab allocator can release
+pages in contexts where TLB flushes can't be performed (e.g. in hardware
+interrupt handlers). Pages to free are not freed directly, and instead they are
+put on a queue and freed from a workqueue context which also flushes the TLB.
+
+Performance
+~~~~~~~~~~~
+
+SLAB_VIRTUAL's performance impact depends on the workload. On kernel compilation
+(kernbench) the slowdown is about 1-2% depending on the machine type and is
+slightly worse on machines with more cores.
-- 
2.42.0.459.ge4e396fd5e-goog



  parent reply	other threads:[~2023-09-15 11:00 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-15 10:59 [RFC PATCH 00/14] Prevent cross-cache attacks in the SLUB allocator Matteo Rizzo
2023-09-15 10:59 ` [RFC PATCH 01/14] mm/slub: don't try to dereference invalid freepointers Matteo Rizzo
2023-09-15 20:50   ` Kees Cook
2023-09-30 11:04   ` Hyeonggon Yoo
2023-09-15 10:59 ` [RFC PATCH 02/14] mm/slub: add is_slab_addr/is_slab_page helpers Matteo Rizzo
2023-09-15 20:55   ` Kees Cook
2023-09-15 10:59 ` [RFC PATCH 03/14] mm/slub: move kmem_cache_order_objects to slab.h Matteo Rizzo
2023-09-15 20:56   ` Kees Cook
2023-09-15 10:59 ` [RFC PATCH 04/14] mm: use virt_to_slab instead of folio_slab Matteo Rizzo
2023-09-15 20:59   ` Kees Cook
2023-09-15 10:59 ` [RFC PATCH 05/14] mm/slub: create folio_set/clear_slab helpers Matteo Rizzo
2023-09-15 21:02   ` Kees Cook
2023-09-15 10:59 ` [RFC PATCH 06/14] mm/slub: pass additional args to alloc_slab_page Matteo Rizzo
2023-09-15 21:03   ` Kees Cook
2023-09-15 10:59 ` [RFC PATCH 07/14] mm/slub: pass slab pointer to the freeptr decode helper Matteo Rizzo
2023-09-15 21:06   ` Kees Cook
2023-09-15 10:59 ` [RFC PATCH 08/14] security: introduce CONFIG_SLAB_VIRTUAL Matteo Rizzo
2023-09-15 21:07   ` Kees Cook
2023-09-15 10:59 ` [RFC PATCH 09/14] mm/slub: add the slab freelists to kmem_cache Matteo Rizzo
2023-09-15 21:08   ` Kees Cook
2023-09-15 10:59 ` [RFC PATCH 10/14] x86: Create virtual memory region for SLUB Matteo Rizzo
2023-09-15 21:13   ` Kees Cook
2023-09-15 21:49     ` Dave Hansen
2023-09-18  8:54       ` Matteo Rizzo
2023-09-15 10:59 ` [RFC PATCH 11/14] mm/slub: allocate slabs from virtual memory Matteo Rizzo
2023-09-15 21:22   ` Kees Cook
2023-09-15 21:57   ` Dave Hansen
2023-10-11  9:17     ` Matteo Rizzo
2023-09-15 10:59 ` [RFC PATCH 12/14] mm/slub: introduce the deallocated_pages sysfs attribute Matteo Rizzo
2023-09-15 21:23   ` Kees Cook
2023-09-15 10:59 ` [RFC PATCH 13/14] mm/slub: sanity-check freepointers Matteo Rizzo
2023-09-15 21:26   ` Kees Cook
2023-09-15 10:59 ` Matteo Rizzo [this message]
2023-09-15 21:34   ` [RFC PATCH 14/14] security: add documentation for SLAB_VIRTUAL Kees Cook
2023-09-20  9:04   ` Vlastimil Babka
2023-09-15 15:19 ` [RFC PATCH 00/14] Prevent cross-cache attacks in the SLUB allocator Dave Hansen
2023-09-15 16:30   ` Lameter, Christopher
2023-09-18 12:08     ` Matteo Rizzo
2023-09-18 17:39       ` Ingo Molnar
2023-09-18 18:05         ` Linus Torvalds
2023-09-19 15:48           ` Matteo Rizzo
2023-09-19 16:02             ` Dave Hansen
2023-09-19 17:56               ` Kees Cook
2023-09-19 18:49             ` Linus Torvalds
2023-09-19 13:42         ` Matteo Rizzo
2023-09-19 15:56           ` Dave Hansen
2023-09-20  7:44           ` Ingo Molnar
2023-09-20  8:49       ` Vlastimil Babka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230915105933.495735-15-matteorizzo@google.com \
    --to=matteorizzo@google.com \
    --cc=42.hyeyoo@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=bp@alien8.de \
    --cc=cl@linux.com \
    --cc=corbet@lwn.net \
    --cc=dave.hansen@linux.intel.com \
    --cc=evn@google.com \
    --cc=hpa@zytor.com \
    --cc=iamjoonsoo.kim@lge.com \
    --cc=jannh@google.com \
    --cc=jordyzomer@google.com \
    --cc=keescook@chromium.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=luto@kernel.org \
    --cc=mingo@redhat.com \
    --cc=penberg@kernel.org \
    --cc=peterz@infradead.org \
    --cc=poprdi@google.com \
    --cc=rientjes@google.com \
    --cc=roman.gushchin@linux.dev \
    --cc=tglx@linutronix.de \
    --cc=vbabka@suse.cz \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox