From patchwork Wed Sep 19 18:54:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrey Konovalov X-Patchwork-Id: 971887 Return-Path: X-Original-To: incoming-imx@patchwork.ozlabs.org Delivered-To: patchwork-incoming-imx@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="sy8hZd3t"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=infradead.org header.i=@infradead.org header.b="OHuun0g+"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="IqYYK6SU"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42FqKP1rvvz9sBj for ; Thu, 20 Sep 2018 05:14:01 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=4m7fJTihhtYn1/JkTw/bt/GsrWHc4WheD5gK6YBeKIU=; b=sy8hZd3tkTuJ4b irPrefcwpL5A+KK8DK1v1c7P0m5WPfq1BeH+z6Jk19W2CTG/Tg7Oo6qx/4sSLhLOmSz1LJygkKe3D VuQKTwF/X1fT6cfYBbc+m2quIYe5O+SVasDaJ8fejkC8gBAaWFU8t0piRfAvPGZ0qp2olzCypDGDh 1Qf+a/r9pDgfLWW+5spM2ZclbANZq9zxpSYkhaUjyGrLCTVKajVKeL6cFob8kHlLdu0iBz3ReB9Sv IQDYDEI2OSkUJzP25g45XhJdP4Wp2vZNC33iL09jQnXhZgPdn1hmNGpT5jlOp9lD9ebpM6LbaTfTJ kx9iHD8ap8zstoR7qdeQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g2hv5-0005Gu-MN; Wed, 19 Sep 2018 19:13:51 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1g2htE-0003yX-62 for linux-arm-kernel@bombadil.infradead.org; Wed, 19 Sep 2018 19:11:56 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:Content-Type: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=MFWmZ2ymGw7SFNCT+sDf2yM6FOtMRHS5/lhwAKyi41M=; b=OHuun0g+weBtpb6zz+CCCOFLq6 IA+oC88OOd5xvhsr88zNMz9KMK+Umg091/C+ljgqoKxiOPKfagTP98HFL+F9LDI8cFK2BR6vlzU0U 2dCtXBGr5OeHH15ADoklHUhDor4NRiHCIvc68mWJZsY5Bf7ekQdjZKkwGsPMvNjZ7/gF68N7XxiOs dBLVHbhvo2oFomfbQYSqvhBHtOIzQbcev+UTDPpPbu4WFzGqGAOA41okri6LDWxO033MHt7itU+lh jhaBqVjGpqH3wD6L65CSCHl1iIQHN00ZTuO3yULL9lbxZGPAGvN69Kn3jck+ayMN5eJIPxgMfJs0b qj3R1ftA==; Received: from mail-wm1-x341.google.com ([2a00:1450:4864:20::341]) by casper.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1g2hdI-00038m-R3 for linux-arm-kernel@lists.infradead.org; Wed, 19 Sep 2018 18:55:30 +0000 Received: by mail-wm1-x341.google.com with SMTP id 207-v6so8118514wme.5 for ; Wed, 19 Sep 2018 11:55:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=MFWmZ2ymGw7SFNCT+sDf2yM6FOtMRHS5/lhwAKyi41M=; b=IqYYK6SU9pnRTgV15qs62JcLXf/m3ATgrjIeRvDfbSFBDxyovt3Dm4Lg786w5AseU5 Mae0w7RS8HUuPeA7f+uXCK1rM0x4/jv0+9M9dFUdiLqu62wpofAN28FjvVPhPK6chlvJ e45Vw6cbLFf1HeO4sgAnOyP5eiI74zXKJGiOuKPsiGQNlGkI7gdTwl1TygXQGf+I+wM1 a96JjD6bXs2c0ZNGqaIWn7CA75MiAsSV1e66KOMRFmquPJIgKpK9LrCcqz8KQjLDp4Uj 4l8Pi9agIB2MUaOjJcbdQbH+95GpX9EV2HsxGT9AKOGujouVX+qFVKm1V5f40rPIlZXs kNaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=MFWmZ2ymGw7SFNCT+sDf2yM6FOtMRHS5/lhwAKyi41M=; b=Q4lRtDE3S8Ds3sCfCisur1rxcvQHQjt6RfrmUSa+6CxYQYVVi3vG27b6nNO8uymhnO r0IBA6+D/uCnQfkE0Pie0xD3hzudVxOWvjOY0uaaW12j000x2QKGXGXpFz4M8gvHfHRo AmM7yzf/gkxK1oWYBkHd82grK2cR96w9d0UI1mfaNvxs3MS6mdDIhnYa/vqzhkkjEP8i S42ZtCERbvz+66axH8wz+adr3ZbSuX9H1Zz4G4FgvJ8YHf8OhAgr3oGdhdDTBe9LP/72 CBNtJLOXwRUm5aAoq0mHPCYXv9gXwNkmZqayvGGq1JLoo9IfHWRntthsHJpLHc4zOm9S A9ng== X-Gm-Message-State: APzg51A/xPNSiNbUpOKCz61fomJUy11H2Mz20eaKgySiR6X8a9ldtEqu N84+n9iEYkvcYTjZn7Iih+UGGQ== X-Google-Smtp-Source: ANB0VdbYUdT1KRAy58Mt7lu/XViex7l4kcxG8+LuGI0hRyyJeq/zNg/WgbiXvKSO+4udIQquLyu5aQ== X-Received: by 2002:a1c:9290:: with SMTP id u138-v6mr21163466wmd.52.1537383316609; Wed, 19 Sep 2018 11:55:16 -0700 (PDT) Received: from andreyknvl0.muc.corp.google.com ([2a00:79e0:15:10:84be:a42a:826d:c530]) by smtp.gmail.com with ESMTPSA id b10-v6sm8510065wmc.28.2018.09.19.11.55.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 19 Sep 2018 11:55:16 -0700 (PDT) From: Andrey Konovalov To: Andrey Ryabinin , Alexander Potapenko , Dmitry Vyukov , Catalin Marinas , Will Deacon , Christoph Lameter , Andrew Morton , Mark Rutland , Nick Desaulniers , Marc Zyngier , Dave Martin , Ard Biesheuvel , "Eric W . Biederman" , Ingo Molnar , Paul Lawrence , Geert Uytterhoeven , Arnd Bergmann , "Kirill A . Shutemov" , Greg Kroah-Hartman , Kate Stewart , Mike Rapoport , kasan-dev@googlegroups.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sparse@vger.kernel.org, linux-mm@kvack.org, linux-kbuild@vger.kernel.org Subject: [PATCH v8 08/20] kasan: add tag related helper functions Date: Wed, 19 Sep 2018 20:54:47 +0200 Message-Id: <79532ad7be1a40637e6646eb0ada6195974df503.1537383101.git.andreyknvl@google.com> X-Mailer: git-send-email 2.19.0.397.gdd90340f6a-goog In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180919_195528_869636_87732AB5 X-CRM114-Status: GOOD ( 22.05 ) X-Spam-Score: -15.6 (---------------) X-Spam-Report: SpamAssassin version 3.4.1 on casper.infradead.org summary: Content analysis details: (-15.6 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -7.5 USER_IN_DEF_DKIM_WL From: address is in the default DKIM white-list -0.0 SPF_PASS SPF: sender matches SPF record -7.5 USER_IN_DEF_SPF_WL From: address is in the default SPF white-list 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.5 ENV_AND_HDR_SPF_MATCH Env and Hdr From used in default SPF WL Match -0.0 DKIMWL_WL_MED DKIMwl.org - Whitelisted Medium sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Vishwath Mohan , Chintan Pandya , Jacob Bramley , Jann Horn , Ruben Ayrapetyan , Andrey Konovalov , Lee Smith , Kostya Serebryany , Mark Brand , Ramana Radhakrishnan , Evgeniy Stepanov Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org List-Id: linux-imx-kernel.lists.patchwork.ozlabs.org This commit adds a few helper functions, that are meant to be used to work with tags embedded in the top byte of kernel pointers: to set, to get or to reset (set to 0xff) the top byte. Signed-off-by: Andrey Konovalov --- arch/arm64/mm/kasan_init.c | 2 ++ include/linux/kasan.h | 13 +++++++++ mm/kasan/kasan.h | 55 ++++++++++++++++++++++++++++++++++++++ mm/kasan/tags.c | 37 +++++++++++++++++++++++++ 4 files changed, 107 insertions(+) diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c index 7a31e8ccbad2..ecd3f25cc323 100644 --- a/arch/arm64/mm/kasan_init.c +++ b/arch/arm64/mm/kasan_init.c @@ -250,6 +250,8 @@ void __init kasan_init(void) memset(kasan_zero_page, KASAN_SHADOW_INIT, PAGE_SIZE); cpu_replace_ttbr1(lm_alias(swapper_pg_dir)); + kasan_init_tags(); + /* At this point kasan is fully initialized. Enable error messages */ init_task.kasan_depth = 0; pr_info("KernelAddressSanitizer initialized\n"); diff --git a/include/linux/kasan.h b/include/linux/kasan.h index e7162ca9d66b..7e5be87a05b3 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h @@ -169,6 +169,19 @@ static inline void kasan_cache_shutdown(struct kmem_cache *cache) {} #define KASAN_SHADOW_INIT 0xFF +void kasan_init_tags(void); + +void *kasan_reset_tag(const void *addr); + +#else /* CONFIG_KASAN_SW_TAGS */ + +static inline void kasan_init_tags(void) { } + +static inline void *kasan_reset_tag(const void *addr) +{ + return (void *)addr; +} + #endif /* CONFIG_KASAN_SW_TAGS */ #endif /* LINUX_KASAN_H */ diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h index 19b950eaccff..63ab9775275b 100644 --- a/mm/kasan/kasan.h +++ b/mm/kasan/kasan.h @@ -8,6 +8,10 @@ #define KASAN_SHADOW_SCALE_SIZE (1UL << KASAN_SHADOW_SCALE_SHIFT) #define KASAN_SHADOW_MASK (KASAN_SHADOW_SCALE_SIZE - 1) +#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 */ + #define KASAN_FREE_PAGE 0xFF /* page was freed */ #define KASAN_PAGE_REDZONE 0xFE /* redzone for kmalloc_large allocations */ #define KASAN_KMALLOC_REDZONE 0xFC /* redzone inside slub object */ @@ -126,6 +130,57 @@ static inline void quarantine_reduce(void) { } static inline void quarantine_remove_cache(struct kmem_cache *cache) { } #endif +#ifdef CONFIG_KASAN_SW_TAGS + +#define KASAN_TAG_SHIFT 56 +#define KASAN_TAG_MASK (0xFFUL << KASAN_TAG_SHIFT) + +u8 random_tag(void); + +static inline void *set_tag(const void *addr, u8 tag) +{ + u64 a = (u64)addr; + + a &= ~KASAN_TAG_MASK; + a |= ((u64)tag << KASAN_TAG_SHIFT); + + return (void *)a; +} + +static inline u8 get_tag(const void *addr) +{ + return (u8)((u64)addr >> KASAN_TAG_SHIFT); +} + +static inline void *reset_tag(const void *addr) +{ + return set_tag(addr, KASAN_TAG_KERNEL); +} + +#else /* CONFIG_KASAN_SW_TAGS */ + +static inline u8 random_tag(void) +{ + return 0; +} + +static inline void *set_tag(const void *addr, u8 tag) +{ + return (void *)addr; +} + +static inline u8 get_tag(const void *addr) +{ + return 0; +} + +static inline void *reset_tag(const void *addr) +{ + return (void *)addr; +} + +#endif /* CONFIG_KASAN_SW_TAGS */ + /* * Exported functions for interfaces called from assembly or from generated * code. Declarations here to avoid warning about missing declarations. diff --git a/mm/kasan/tags.c b/mm/kasan/tags.c index 04194923c543..700323946867 100644 --- a/mm/kasan/tags.c +++ b/mm/kasan/tags.c @@ -38,6 +38,43 @@ #include "kasan.h" #include "../slab.h" +static DEFINE_PER_CPU(u32, prng_state); + +void kasan_init_tags(void) +{ + int cpu; + + for_each_possible_cpu(cpu) + per_cpu(prng_state, cpu) = get_random_u32(); +} + +/* + * If a preemption happens between this_cpu_read and this_cpu_write, the only + * side effect is that we'll give a few allocated in different contexts objects + * the same tag. Since tag-based KASAN is meant to be used a probabilistic + * bug-detection debug feature, this doesn’t have significant negative impact. + * + * Ideally the tags use strong randomness to prevent any attempts to predict + * them during explicit exploit attempts. But strong randomness is expensive, + * and we did an intentional trade-off to use a PRNG. This non-atomic RMW + * sequence has in fact positive effect, since interrupts that randomly skew + * PRNG at unpredictable points do only good. + */ +u8 random_tag(void) +{ + u32 state = this_cpu_read(prng_state); + + state = 1664525 * state + 1013904223; + this_cpu_write(prng_state, state); + + return (u8)(state % (KASAN_TAG_MAX + 1)); +} + +void *kasan_reset_tag(const void *addr) +{ + return reset_tag(addr); +} + void check_memory_region(unsigned long addr, size_t size, bool write, unsigned long ret_ip) {