Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp677596pxk; Thu, 24 Sep 2020 15:56:39 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxzZKlamuvXW4DM6/sU+pxCxMAEDJuUCN1gCRiHBN/uEWY7LUoR/kmU3ik/ih49UZ8VxTff X-Received: by 2002:a05:6402:1212:: with SMTP id c18mr1051170edw.344.1600988199074; Thu, 24 Sep 2020 15:56:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1600988199; cv=none; d=google.com; s=arc-20160816; b=E8WtJzsol+tTLx8f5vBW0pfhABby+x7XSNgeNEazheZFcu5B2saK3azs8JRn2kcRH3 PKo1uZuXpa2teI9ieWs9q9HVu4DkDfzKXvDmHNoOXz4FSc8IfNdKdOvdlH6e6WlU+xUn 3Stt5qF6A7iS4bMzJEbSz1quEVqSikVxem+nU/BUOElg+8AgYh1qRH9t88yA/IdW9fKU PG9iLEwjAdoUOxQ4Pcgi+BDsfu6YYyFeNNLR/45j+nV8DZVtp3xoMPTKIxWBFBq31rkp 2SiFDbex81EVopTN8TNkbWn30xO8IhEzxv4nBGIlEhGApTna5LmdBHrk1NzzaUQkqtiy i+og== 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:references:mime-version :message-id:in-reply-to:date:sender:dkim-signature; bh=95tdm8ZDV/jYg512g9xnC5FEvh1w9aO1X3WPowE8lXY=; b=K348Mek9QqHuBpGVYStHxcgodhXbCBmZpkSl16fHAhvnz3xvAIgY/ojTZvTcXImLSo WBPg06iSZZ/+k/CnolCNDvLtkqCUzrp0/Pi5PgbZpMHWs5+4ki+iDqllV9df4LJPyePt yvKQJuVnwCXCOZS0h26L1VJrjfxpAMLUBwTh/vg6nAEGYEU0+zZosaJjPH+eSqBmkNqK IysAHBeGHDQ92G4ekgAv8dN7wuIrwbaKdl0VICFUOehdpdpCgmrmDgVs1a5vddwyG1FS vXajkZFQtOBNXs+c/Gt12cRvmRmDBzJi2gB1xTtZSASJzKRgUIH7/Tq6cI2uo0nQ1sHB XpYQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=YtLfFJF3; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id e2si569493edv.242.2020.09.24.15.56.15; Thu, 24 Sep 2020 15:56:39 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=YtLfFJF3; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727143AbgIXWwi (ORCPT + 99 others); Thu, 24 Sep 2020 18:52:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50772 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727086AbgIXWwW (ORCPT ); Thu, 24 Sep 2020 18:52:22 -0400 Received: from mail-qt1-x84a.google.com (mail-qt1-x84a.google.com [IPv6:2607:f8b0:4864:20::84a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9438CC0613D3 for ; Thu, 24 Sep 2020 15:52:22 -0700 (PDT) Received: by mail-qt1-x84a.google.com with SMTP id w3so40696qtn.16 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=aUcM+txi9iUyfhz2SMjajthXTPjvT92Sfyzc/gX4NdI81oa9olmW+GcPdQ3o3Zqg/O JISTAzeylkjyCq/rM2Jc2PhTg1YMF3NaZrjt7L0cEnhXKQpZN+e3Gd+v6VPqRdEAOJ1H pVCQCaIukZ/7/0U3ViBdg7mXd6ZZrFoP6mn+bpv2x6hLmztspNV7fzOMqHUwUoXfitDX ZlGHdDbIqp68b0gAXTNdBWYQerRzLeqaBszui3eJ4BZOR0McesKzaDBJLw4KeEW9EMp0 4XUFUWhJXPb87KnHTYPE0ahR0jBWdT1kGgM0qBocMPA5fdIwzSQ6pPZ0NW4YcHqTTHLv 0Y3Q== X-Gm-Message-State: AOAM532YBNZ6MeAU3jRqZdvxbIUwUn9dYUTuklWomQsPUSg155CpUf6v iPVklMH9vGfO1gn9McrtCrOD6JQXNpKTuUt7 Sender: "andreyknvl via sendgmr" 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 Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- 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); -- 2.28.0.681.g6f77f65b4e-goog