From patchwork Thu Sep 24 22:50:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Konovalov X-Patchwork-Id: 11798375 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 49628139A for ; Thu, 24 Sep 2020 22:52:27 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 0BF8D23600 for ; Thu, 24 Sep 2020 22:52:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="YtLfFJF3" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0BF8D23600 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 7A57590000D; Thu, 24 Sep 2020 18:52:23 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 77D4F8E0001; Thu, 24 Sep 2020 18:52:23 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 6443C90000D; Thu, 24 Sep 2020 18:52:23 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0176.hostedemail.com [216.40.44.176]) by kanga.kvack.org (Postfix) with ESMTP id 468F18E0001 for ; Thu, 24 Sep 2020 18:52:23 -0400 (EDT) Received: from smtpin15.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay02.hostedemail.com (Postfix) with ESMTP id 12A9A2DFA for ; Thu, 24 Sep 2020 22:52:23 +0000 (UTC) X-FDA: 77299455366.15.note15_420542727162 Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin15.hostedemail.com (Postfix) with ESMTP id DCEF61814B0C1 for ; Thu, 24 Sep 2020 22:52:22 +0000 (UTC) X-Spam-Summary: 1,0,0,233fb56a069dc380,d41d8cd98f00b204,3jsntxwokcci8lbpcwiltjemmejc.amkjglsv-kkit8ai.mpe@flex--andreyknvl.bounces.google.com,,RULES_HIT:2:41:69:152:355:379:541:800:960:966:973:988:989:1042:1260:1277:1313:1314:1345:1359:1431:1437:1516:1518:1535:1593:1594:1605:1606:1730:1747:1777:1792:2196:2199:2393:2553:2559:2562:2918:3138:3139:3140:3141:3142:3152:3865:3866:3867:3868:3870:3871:3872:3874:4119:4250:4385:4605:5007:6261:6653:6742:7875:7904:9969:10004:11026:11232:11233:11473:11658:11914:12043:12048:12296:12297:12438:12555:12895:14096:14097:14394:14659:21080:21365:21433:21444:21451:21627:21772:21939:21966:21990:30012:30054:30055:30062:30070:30090,0,RBL:209.85.222.201:@flex--andreyknvl.bounces.google.com:.lbl8.mailshell.net-66.100.201.100 62.18.0.100;04yf7scqdiwq8t5towwbzgcpdsebhocanq4fd6m43w4n46wa9w1t16kagb4g4xe.fhz5y1wosmj1pdj6zunj4nfe8jppn8gsfo5amxttn834pwm5937uzk1ipwf5kxx.1-lbl8.mailshell.net-223.238.255.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainC ache:0,M X-HE-Tag: note15_420542727162 X-Filterd-Recvd-Size: 8774 Received: from mail-qk1-f201.google.com (mail-qk1-f201.google.com [209.85.222.201]) by imf35.hostedemail.com (Postfix) with ESMTP for ; Thu, 24 Sep 2020 22:52:22 +0000 (UTC) Received: by mail-qk1-f201.google.com with SMTP id 16so691660qky.8 for ; Thu, 24 Sep 2020 15:52:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=95tdm8ZDV/jYg512g9xnC5FEvh1w9aO1X3WPowE8lXY=; b=YtLfFJF3XqMfi9E9N3HSM7i55S/IjbkCC+kpe5PepleqwTIy1B8N7WmcNvUm8IefLx LSqgRPOE8xeS1OUwkA6rR+Clu4h3Zoc59WqWP5qhAQy71HrFvRy63E2466hmA1q9W5hj kWWUKVfYHZJCKPL+fKHNEgawX6UmQdm3UIqrQP2+6OFIC+E6Ky2JE0U/I48A3jHLQ1sj +UR+1QP5ZL7B7dVWEFDMXi2xk60ZdRwG5mLXFm5lEZlhR2w6eZmGo/eaQF1nwi/+sz// 2xdjjT+P+nl1ayZiK/PpXfmAXGv935ghEQu/m1kkIYXi98FwpHrI9FodL0DxYNmgV26x eFVQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=95tdm8ZDV/jYg512g9xnC5FEvh1w9aO1X3WPowE8lXY=; b=VPWUtmuaqXZ1cULfv0xXaisQ1dS3H2Ne/vepJkPRO0UE/5uYJveEgsQcKdzK0LR+bs NkB6oZ0dz3xavPzoDEQ4TCgvRgxeC9wgXWA3iHO0ue10zLxEEaTVQGzK4/YPOdWgL6Xh nEjOMd7I1WlgnD9/qXaCF5sCEmBH9Nw59OfJ9OBtSAJzNd6iroCs454ttzmJRCzP317s FivS7otmttmRTpe2P6QAtlUre1ZW8Nd2ieQIhNnqaeGHl+gECuqFSKpoHUROBVUZMm+Y dA61As7RnU94NCWTxFmIw7HNzeO9xSXUmktn484aPzFFZOf1FS7PfsITFcp3Kunm93xb pxtQ== X-Gm-Message-State: AOAM533yeKNpAXYL9cjbDEstgKYo3bpuFeLCoTUxTq7F5fXhSxQ673tA NA9KjjmNC+c6qpJ47o7nuFWhb/QFd89l1BDr X-Google-Smtp-Source: ABdhPJzHHsDSNDFPICxH7naEOhQTcMjejJmGfS0LDWcAy4pJpz+G+RDvqkCDX43GWzj21j87kvZvwYLxByh1i0xr X-Received: from andreyknvl3.muc.corp.google.com ([2a00:79e0:15:13:7220:84ff:fe09:7e9d]) (user=andreyknvl job=sendgmr) by 2002:a0c:e892:: with SMTP id b18mr1654354qvo.4.1600987941729; Thu, 24 Sep 2020 15:52:21 -0700 (PDT) Date: Fri, 25 Sep 2020 00:50:44 +0200 In-Reply-To: Message-Id: Mime-Version: 1.0 References: X-Mailer: git-send-email 2.28.0.681.g6f77f65b4e-goog Subject: [PATCH v3 37/39] kasan, slub: reset tags when accessing metadata From: Andrey Konovalov To: Dmitry Vyukov , Vincenzo Frascino , Catalin Marinas , kasan-dev@googlegroups.com Cc: Andrey Ryabinin , Alexander Potapenko , Marco Elver , Evgenii Stepanov , Elena Petrova , Branislav Rankov , Kevin Brodsky , Will Deacon , Andrew Morton , linux-arm-kernel@lists.infradead.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Andrey Konovalov X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: SLUB allocator 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. Signed-off-by: Andrey Konovalov Signed-off-by: Vincenzo Frascino Acked-by: Marco Elver --- Change-Id: I39f3c4d4f29299d4fbbda039bedf230db1c746fb --- mm/page_poison.c | 2 +- mm/slub.c | 25 ++++++++++++++----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/mm/page_poison.c b/mm/page_poison.c index 34b9181ee5d1..d90d342a391f 100644 --- a/mm/page_poison.c +++ b/mm/page_poison.c @@ -43,7 +43,7 @@ static void poison_page(struct page *page) /* KASAN still think the page is in-use, so skip it. */ kasan_disable_current(); - memset(addr, PAGE_POISON, PAGE_SIZE); + memset(kasan_reset_tag(addr), PAGE_POISON, PAGE_SIZE); kasan_enable_current(); kunmap_atomic(addr); } diff --git a/mm/slub.c b/mm/slub.c index 68c02b2eecd9..f5b4bef3cd6c 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -249,7 +249,7 @@ static inline void *freelist_ptr(const struct kmem_cache *s, void *ptr, { #ifdef CONFIG_SLAB_FREELIST_HARDENED /* - * When CONFIG_KASAN_SW_TAGS is enabled, ptr_addr might be tagged. + * When CONFIG_KASAN_SW/HW_TAGS is enabled, ptr_addr might be tagged. * Normally, this doesn't cause any issues, as both set_freepointer() * and get_freepointer() are called with a pointer with the same tag. * However, there are some issues with CONFIG_SLUB_DEBUG code. For @@ -275,6 +275,7 @@ static inline void *freelist_dereference(const struct kmem_cache *s, static inline void *get_freepointer(struct kmem_cache *s, void *object) { + object = kasan_reset_tag(object); return freelist_dereference(s, object + s->offset); } @@ -304,6 +305,7 @@ static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp) BUG_ON(object == fp); /* naive detection of double free or corruption */ #endif + freeptr_addr = (unsigned long)kasan_reset_tag((void *)freeptr_addr); *(void **)freeptr_addr = freelist_ptr(s, fp, freeptr_addr); } @@ -538,8 +540,8 @@ static void print_section(char *level, char *text, u8 *addr, unsigned int length) { metadata_access_enable(); - print_hex_dump(level, text, DUMP_PREFIX_ADDRESS, 16, 1, addr, - length, 1); + print_hex_dump(level, kasan_reset_tag(text), DUMP_PREFIX_ADDRESS, + 16, 1, addr, length, 1); metadata_access_disable(); } @@ -570,7 +572,7 @@ static struct track *get_track(struct kmem_cache *s, void *object, p = object + get_info_end(s); - return p + alloc; + return kasan_reset_tag(p + alloc); } static void set_track(struct kmem_cache *s, void *object, @@ -583,7 +585,8 @@ static void set_track(struct kmem_cache *s, void *object, unsigned int nr_entries; metadata_access_enable(); - nr_entries = stack_trace_save(p->addrs, TRACK_ADDRS_COUNT, 3); + nr_entries = stack_trace_save(kasan_reset_tag(p->addrs), + TRACK_ADDRS_COUNT, 3); metadata_access_disable(); if (nr_entries < TRACK_ADDRS_COUNT) @@ -747,7 +750,7 @@ static __printf(3, 4) void slab_err(struct kmem_cache *s, struct page *page, static void init_object(struct kmem_cache *s, void *object, u8 val) { - u8 *p = object; + u8 *p = kasan_reset_tag(object); if (s->flags & SLAB_RED_ZONE) memset(p - s->red_left_pad, val, s->red_left_pad); @@ -777,7 +780,7 @@ static int check_bytes_and_report(struct kmem_cache *s, struct page *page, u8 *addr = page_address(page); metadata_access_enable(); - fault = memchr_inv(start, value, bytes); + fault = memchr_inv(kasan_reset_tag(start), value, bytes); metadata_access_disable(); if (!fault) return 1; @@ -873,7 +876,7 @@ static int slab_pad_check(struct kmem_cache *s, struct page *page) pad = end - remainder; metadata_access_enable(); - fault = memchr_inv(pad, POISON_INUSE, remainder); + fault = memchr_inv(kasan_reset_tag(pad), POISON_INUSE, remainder); metadata_access_disable(); if (!fault) return 1; @@ -1118,7 +1121,7 @@ void setup_page_debug(struct kmem_cache *s, struct page *page, void *addr) return; metadata_access_enable(); - memset(addr, POISON_INUSE, page_size(page)); + memset(kasan_reset_tag(addr), POISON_INUSE, page_size(page)); metadata_access_disable(); } @@ -2884,10 +2887,10 @@ static __always_inline void *slab_alloc_node(struct kmem_cache *s, stat(s, ALLOC_FASTPATH); } - maybe_wipe_obj_freeptr(s, object); + maybe_wipe_obj_freeptr(s, kasan_reset_tag(object)); if (unlikely(slab_want_init_on_alloc(gfpflags, s)) && object) - memset(object, 0, s->object_size); + memset(kasan_reset_tag(object), 0, s->object_size); slab_post_alloc_hook(s, objcg, gfpflags, 1, &object);