From patchwork Tue Sep 15 21:16:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Konovalov X-Patchwork-Id: 11777785 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 E26FD59D for ; Tue, 15 Sep 2020 21:17:52 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 9DB812078E for ; Tue, 15 Sep 2020 21:17:52 +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="fsTRc89Y" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9DB812078E 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 3485A900096; Tue, 15 Sep 2020 17:17:50 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 2FA27900070; Tue, 15 Sep 2020 17:17:50 -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 14C10900096; Tue, 15 Sep 2020 17:17:50 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0006.hostedemail.com [216.40.44.6]) by kanga.kvack.org (Postfix) with ESMTP id ECDE2900070 for ; Tue, 15 Sep 2020 17:17:49 -0400 (EDT) Received: from smtpin20.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with ESMTP id B1D6E181AEF09 for ; Tue, 15 Sep 2020 21:17:49 +0000 (UTC) X-FDA: 77266557858.20.pet36_3e012f527114 Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin20.hostedemail.com (Postfix) with ESMTP id 83DF5180C07A3 for ; Tue, 15 Sep 2020 21:17:49 +0000 (UTC) X-Spam-Summary: 1,0,0,b138c76f27a07722,d41d8cd98f00b204,3fc9hxwokcge9mcqdxjmukfnnfkd.bnlkhmtw-llju9bj.nqf@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: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.221.74:@flex--andreyknvl.bounces.google.com:.lbl8.mailshell.net-66.100.201.100 62.18.0.100;04y8gqns6unfeeiaayeuido73qif6ocanq4fd6m43w4n46wa9w1t16kagb4g4xe.fhz5y1wosmj1pdj6zunj4nfe8jppn8gsfo5amxttn834pwm5937uzk1ipwf5kxx.1-lbl8.mailshell.net-223.238.255.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0, MSF:not X-HE-Tag: pet36_3e012f527114 X-Filterd-Recvd-Size: 8772 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.74]) by imf15.hostedemail.com (Postfix) with ESMTP for ; Tue, 15 Sep 2020 21:17:49 +0000 (UTC) Received: by mail-wr1-f74.google.com with SMTP id l15so1705121wro.10 for ; Tue, 15 Sep 2020 14:17:48 -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=OJ/8AnntxXTECtkQTOaxjfZECPzBTRORy6i2yS83kOo=; b=fsTRc89Y8Zxhcw1t5FHcT2l04+Vs91ABV7dJ+vBPhhaHv+cdI42HIqPxytva99Oc/f tEF8Ajhet3GGkGV0lxMNdANtx58YTLh2raBV++EuvcTDG4lfRtVuBPZ3dhERXQrVolz5 qR6ht87ldpJ+K6V9qf/aTiaHgi3Rtj8MoV5qm6W2Yu0VKdVnI/+pNvbLjwyDqlInDyuy ixzwUN/j7DQ1s685G6q7r/X917lEDMjNnDlwT5fg2nngAWAgJG608O+mBfOBdT4/IE+Y +oA5tacqx8skGTtNElJzGeTixoBhDz1eN9lgftdMtVlInLtvMnDII+IeqTWP3nfZ3K5e Mfdg== 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=OJ/8AnntxXTECtkQTOaxjfZECPzBTRORy6i2yS83kOo=; b=lm2Q1f4VST8QCwXQYm7MIhafNTCodKNpfJoJy1FHjpumnOczhMfPhPclCo1ODhPp5k CN5w7qH1xKfV1FctEVDPnpp4xextm9G6UiDvQRcGAh4t2BR9LbCntsjYxIyr/pC9QcBC axF8r4mYba9/xVgJcgT5Sle4MAY0JeVBRQZ7hOj7WftNjgU5IStebUUEw18EYUr4MHkB wBrh77VUud0aY0fV5kvEFJ+yZcnSZpL29zhHhJK5rQCPUjeiGBx6eMZox8SkMPvkyn4J iYkGYSgeSOSQgtmmojy03+id6rBtKtJMWgqBaVExgvdNQVZZN1BXTmb9CATDpRKtyHaW 3GPA== X-Gm-Message-State: AOAM531Yl3uwGV3TqLiI7hF3e9+ZZS/fdqFLt00g6GzUBY32mIF4zFhI LKidR4T8jJK8md0pKudHSf07YuzUH7KtDuEv X-Google-Smtp-Source: ABdhPJyB2fgN/4avIQbsrVPagRenog1bi9DkyzuhYeFDKwQHiHl1iiiqiRJ8H6iw/7DwoI0ckDpr8Mm/2qsFUGd0 X-Received: from andreyknvl3.muc.corp.google.com ([2a00:79e0:15:13:7220:84ff:fe09:7e9d]) (user=andreyknvl job=sendgmr) by 2002:a05:600c:2283:: with SMTP id 3mr1188256wmf.37.1600204668051; Tue, 15 Sep 2020 14:17:48 -0700 (PDT) Date: Tue, 15 Sep 2020 23:16:17 +0200 In-Reply-To: Message-Id: Mime-Version: 1.0 References: X-Mailer: git-send-email 2.28.0.618.gf4bc123cb7-goog Subject: [PATCH v2 35/37] 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-Rspamd-Queue-Id: 83DF5180C07A3 X-Spamd-Result: default: False [0.00 / 100.00] X-Rspamd-Server: rspam01 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 --- 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..8e134ca3a6fb 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);