From patchwork Tue May 17 18:09:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Catalin Marinas X-Patchwork-Id: 12852837 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4E092C433EF for ; Tue, 17 May 2022 18:11:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=7VxqLxRQbAndSPUuGvdXX62ZdvYUmEvi6PgZkyludtk=; b=3Hjm/BCsFqbuUk AeLqPLen04ubq4wdyXtlAxi8ZgNBqrDH4FS9Yd67X5NjRvDjb60MyaC9Mv81mN6I/ZgPyvzzAGxcq emiGjWcc417wDqzwi9y41Bpjr7/vbcLVKTc1WfNPeVI3TnhW16VaurG/y5FuZUceFUHqQ1Wf5X/w2 GBkg5CpfFT2Phaezrt6AJTKvs2kv+B3G1GobDAft8OIYqMAPY3DBu2ta05c1bzHvHraAlmdYmvlF8 xqyZ3niq2aiJxDOR/9v0olp2WwWXsHBTG1KxvvnZEyIi2pVarIklvft6KTAXjHcOvN/upJPPBmLNZ OZaKr4CifL4eUdNos1uw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nr1eC-00FAQj-Ot; Tue, 17 May 2022 18:10:16 +0000 Received: from ams.source.kernel.org ([2604:1380:4601:e00::1]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nr1dt-00FAJR-IJ for linux-arm-kernel@lists.infradead.org; Tue, 17 May 2022 18:09:59 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 20084B81B6B; Tue, 17 May 2022 18:09:55 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2AD9EC34100; Tue, 17 May 2022 18:09:52 +0000 (UTC) From: Catalin Marinas To: Andrey Ryabinin , Andrey Konovalov Cc: Will Deacon , Vincenzo Frascino , Peter Collingbourne , kasan-dev@googlegroups.com, linux-mm@kvack.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH 2/3] mm: kasan: Reset the tag on pages intended for user Date: Tue, 17 May 2022 19:09:44 +0100 Message-Id: <20220517180945.756303-3-catalin.marinas@arm.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220517180945.756303-1-catalin.marinas@arm.com> References: <20220517180945.756303-1-catalin.marinas@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220517_110957_930953_0C2224ED X-CRM114-Status: GOOD ( 16.50 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org On allocation kasan colours a page with a random tag and stores such tag in page->flags so that a subsequent page_to_virt() reconstructs the correct tagged pointer. However, when such page is mapped in user-space with PROT_MTE, the kernel's initial tag is overridden. Ensure that such pages have the tag reset (match-all) at allocation time since any late clearing of the tag is racy with other page_to_virt() dereferencing. Signed-off-by: Catalin Marinas Cc: Andrey Ryabinin Cc: Andrey Konovalov Cc: Vincenzo Frascino --- include/linux/gfp.h | 10 +++++++--- mm/page_alloc.c | 9 ++++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 3e3d36fc2109..88b1d4fe4dcb 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -58,13 +58,15 @@ struct vm_area_struct; #define ___GFP_SKIP_ZERO 0x1000000u #define ___GFP_SKIP_KASAN_UNPOISON 0x2000000u #define ___GFP_SKIP_KASAN_POISON 0x4000000u +#define ___GFP_PAGE_KASAN_TAG_RESET 0x8000000u #else #define ___GFP_SKIP_ZERO 0 #define ___GFP_SKIP_KASAN_UNPOISON 0 #define ___GFP_SKIP_KASAN_POISON 0 +#define ___GFP_PAGE_KASAN_TAG_RESET 0 #endif #ifdef CONFIG_LOCKDEP -#define ___GFP_NOLOCKDEP 0x8000000u +#define ___GFP_NOLOCKDEP 0x10000000u #else #define ___GFP_NOLOCKDEP 0 #endif @@ -259,12 +261,13 @@ struct vm_area_struct; #define __GFP_SKIP_ZERO ((__force gfp_t)___GFP_SKIP_ZERO) #define __GFP_SKIP_KASAN_UNPOISON ((__force gfp_t)___GFP_SKIP_KASAN_UNPOISON) #define __GFP_SKIP_KASAN_POISON ((__force gfp_t)___GFP_SKIP_KASAN_POISON) +#define __GFP_PAGE_KASAN_TAG_RESET ((__force gfp_t)___GFP_PAGE_KASAN_TAG_RESET) /* Disable lockdep for GFP context tracking */ #define __GFP_NOLOCKDEP ((__force gfp_t)___GFP_NOLOCKDEP) /* Room for N __GFP_FOO bits */ -#define __GFP_BITS_SHIFT (27 + IS_ENABLED(CONFIG_LOCKDEP)) +#define __GFP_BITS_SHIFT (28 + IS_ENABLED(CONFIG_LOCKDEP)) #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) /** @@ -343,7 +346,8 @@ struct vm_area_struct; #define GFP_NOWAIT (__GFP_KSWAPD_RECLAIM) #define GFP_NOIO (__GFP_RECLAIM) #define GFP_NOFS (__GFP_RECLAIM | __GFP_IO) -#define GFP_USER (__GFP_RECLAIM | __GFP_IO | __GFP_FS | __GFP_HARDWALL) +#define GFP_USER (__GFP_RECLAIM | __GFP_IO | __GFP_FS | __GFP_HARDWALL | \ + __GFP_PAGE_KASAN_TAG_RESET) #define GFP_DMA __GFP_DMA #define GFP_DMA32 __GFP_DMA32 #define GFP_HIGHUSER (GFP_USER | __GFP_HIGHMEM) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 0e42038382c1..f9018a84f4e3 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2382,6 +2382,7 @@ inline void post_alloc_hook(struct page *page, unsigned int order, bool init = !want_init_on_free() && want_init_on_alloc(gfp_flags) && !should_skip_init(gfp_flags); bool init_tags = init && (gfp_flags & __GFP_ZEROTAGS); + int i; set_page_private(page, 0); set_page_refcounted(page); @@ -2407,8 +2408,6 @@ inline void post_alloc_hook(struct page *page, unsigned int order, * should be initialized as well). */ if (init_tags) { - int i; - /* Initialize both memory and tags. */ for (i = 0; i != 1 << order; ++i) tag_clear_highpage(page + i); @@ -2430,7 +2429,11 @@ inline void post_alloc_hook(struct page *page, unsigned int order, /* Propagate __GFP_SKIP_KASAN_POISON to page flags. */ if (kasan_hw_tags_enabled() && (gfp_flags & __GFP_SKIP_KASAN_POISON)) SetPageSkipKASanPoison(page); - + /* if match-all page address required, reset the tag */ + if (gfp_flags & __GFP_PAGE_KASAN_TAG_RESET) { + for (i = 0; i != 1 << order; ++i) + page_kasan_tag_reset(page + i); + }; set_page_owner(page, order, gfp_flags); page_table_check_alloc(page, order); }