From patchwork Fri Sep 15 10:59:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matteo Rizzo X-Patchwork-Id: 140373 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:172:b0:3f2:4152:657d with SMTP id h50csp972882vqi; Fri, 15 Sep 2023 04:32:01 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEAVDpxOGZhPW4Z7mJq0amwPabUBv8HvhVjY+7LNPjQJQpAF7kpTniaO4Sg3XDezIPAnra2 X-Received: by 2002:a17:90a:fd98:b0:274:686d:497b with SMTP id cx24-20020a17090afd9800b00274686d497bmr1082736pjb.27.1694777521442; Fri, 15 Sep 2023 04:32:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1694777521; cv=none; d=google.com; s=arc-20160816; b=PTBHo/3bwVKvJKhnJPZxMPBTLqfp7wpnKbMd4jiMRY2JFIJQcykad5Cm6DMxLGqJoL rbyC2HS/t3Z828sYLUxkb1G8LXDbxEbQWBQpVDanlMCqWYZ+O/B5uFMKhU9L5zfm7f1P cVO3bWD/vDnWgI5a3j0OXa0SNJim+IYSWNvhn3TITHX7SBX31pS4uqh5VXtSSElInlV/ YTb1ZYiI1o8rNeUrl0e9o5BsnQmnVdZ9aQunGEEblZ27yK7VGsPNC1VgN6XLlAQ1ROCz cXss4iBcLfb/4g0HYj1Rzmo6MqeXvOWIR42ssAdobs4P4s7YpSdUcoZPZlIs2HFKfKLa oYjg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:dkim-signature; bh=/kdjtZjOl0pG1Y8OuH7SH0XgMhsH4ZDWKrdEtcTG86U=; fh=hxrcP/evkFXgdiqiA6zEdvE31LUTUVye/z/fSCqBw68=; b=n5PJO1beq3Nsk3XVmpUFRO5Tbsv8gFvMK5uHDDuhHjWmBNPnnEeMV14U9FI/edvC8O ZrcPhBRElEbyMXC6BmXs1Ez6B1Zmkz7JJbc9Jhlg+FZjhF4VHMQHoO2L+PlZaPh2CkcQ uCS6z/LjDdHO5XMTxNB0pxBhZb+uCtFeRM1PjSEO5Qre16mqa07e6PGxMqDq3SrjcB3D DsfoKbqVCHJ8uDjkuDymkPDyPD3jbi+DEGEJCoKNWiYX6QuPTJDi1JYSDg714B4nh0bo HhjzE5C+Zq6DFxpiNucOtBt8iZb3HaxAUfcYV/gOAILJt1NnmuzDU3iStBobsRwEdg2A KCWw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=3ndptF9y; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.31 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from morse.vger.email (morse.vger.email. [23.128.96.31]) by mx.google.com with ESMTPS id v20-20020a17090a899400b0026813cd5719si3159471pjn.128.2023.09.15.04.31.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Sep 2023 04:32:01 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.31 as permitted sender) client-ip=23.128.96.31; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=3ndptF9y; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.31 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by morse.vger.email (Postfix) with ESMTP id 8E52380DB34D; Fri, 15 Sep 2023 04:01:55 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at morse.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234398AbjIOLBG (ORCPT + 32 others); Fri, 15 Sep 2023 07:01:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59632 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234330AbjIOLBB (ORCPT ); Fri, 15 Sep 2023 07:01:01 -0400 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1C5FF2D54 for ; Fri, 15 Sep 2023 04:00:15 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-594e5e2e608so25545777b3.2 for ; Fri, 15 Sep 2023 04:00:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1694775614; x=1695380414; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=/kdjtZjOl0pG1Y8OuH7SH0XgMhsH4ZDWKrdEtcTG86U=; b=3ndptF9yE0L023Xk0WgZY1aIs2w8tVLrrV0WwCIQAni/dKRZByoLnrT4Lu1rqRxp4f 3aE2B70ZTkvS/LjcxEI6kN/ibdqHpR4C0ru2VUsEkAnV8zATtSXLvuNoLPr0cfTii1DQ crghhB/Xk/og2ZfPvknCkfOpKwNz8M04i8MHtgefFYZKRTjvZdFXYHTrs6xR8KkJmPWg i95HteKNtPwzhxRjoPS0s85gf4CWtjHzloF9Irb4BKNgiq+MdlPNvUkgApzudF4r/Bo7 jtEl/yrmZCLqEUeC8CNGp9VFPm3KBg9kur28tfqVBmd6tzAQFCS0tJvvB0BVA4li4xl2 HHBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694775614; x=1695380414; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=/kdjtZjOl0pG1Y8OuH7SH0XgMhsH4ZDWKrdEtcTG86U=; b=IaSmLEvjQDCgfaSBiZQyBI3A043AaAaYKAQKDgBgLdooWAEoOZtmDIYLcP1WZmV/ko Rbutw2J06hc5asmTMWagz1Jdz6Y1ZwSd9twAEvcidxJ5q/SUvuE8ue02+ImzHgPleHov 9xIYC66YGL83ULsTKJEwSD7BRl8OF9OLjxFcJsn20Xah3AoDdMuOCPAJ1kS49X/EYGtt afws1GxvePIG3ABP5SFzv1Tnh34ljlIl9aa6JXl58UvM2qqYb9eksLTWAnfIWPT2JeWy uzki95pynXB8ruhuYzVHpKWnUyMoeQKmMJIOYCa0UfsrDIjYsL+TW+hpPPY9Wl8E0qGq YLHg== X-Gm-Message-State: AOJu0Yw/0l8tvyMYZ6UXzLmkk05+81AW2TqyDB31WT8eYZMbrR2QPiMd W3EvoKBG5tMDmrphyJjvzzT1n3e05M8GR4YeXQ== X-Received: from mr-cloudtop2.c.googlers.com ([fda3:e722:ac3:cc00:31:98fb:c0a8:2a6]) (user=matteorizzo job=sendgmr) by 2002:a81:b643:0:b0:59b:f863:6f60 with SMTP id h3-20020a81b643000000b0059bf8636f60mr37260ywk.4.1694775614195; Fri, 15 Sep 2023 04:00:14 -0700 (PDT) Date: Fri, 15 Sep 2023 10:59:33 +0000 In-Reply-To: <20230915105933.495735-1-matteorizzo@google.com> Mime-Version: 1.0 References: <20230915105933.495735-1-matteorizzo@google.com> X-Mailer: git-send-email 2.42.0.459.ge4e396fd5e-goog Message-ID: <20230915105933.495735-15-matteorizzo@google.com> Subject: [RFC PATCH 14/14] security: add documentation for SLAB_VIRTUAL From: Matteo Rizzo 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 X-Spam-Status: No, score=-8.4 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on morse.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (morse.vger.email [0.0.0.0]); Fri, 15 Sep 2023 04:01:55 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1777103034145978586 X-GMAIL-MSGID: 1777103034145978586 From: Jann Horn Document what SLAB_VIRTUAL is trying to do, how it's implemented, and why. Signed-off-by: Jann Horn Co-developed-by: Matteo Rizzo Signed-off-by: Matteo Rizzo --- 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.