From patchwork Tue Apr 18 16:42:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Rutland X-Patchwork-Id: 13215909 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 kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 95430C77B7D for ; Tue, 18 Apr 2023 16:42:30 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 1F27F8E0003; Tue, 18 Apr 2023 12:42:30 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 1A49A8E0001; Tue, 18 Apr 2023 12:42:30 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 0916B8E0003; Tue, 18 Apr 2023 12:42:30 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id EC4228E0001 for ; Tue, 18 Apr 2023 12:42:29 -0400 (EDT) Received: from smtpin11.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay01.hostedemail.com (Postfix) with ESMTP id AD5941C645C for ; Tue, 18 Apr 2023 16:42:29 +0000 (UTC) X-FDA: 80695080018.11.A13B9D5 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by imf05.hostedemail.com (Postfix) with ESMTP id 27357100013 for ; Tue, 18 Apr 2023 16:42:26 +0000 (UTC) Authentication-Results: imf05.hostedemail.com; dkim=none; spf=pass (imf05.hostedemail.com: domain of mark.rutland@arm.com designates 217.140.110.172 as permitted sender) smtp.mailfrom=mark.rutland@arm.com; dmarc=pass (policy=none) header.from=arm.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1681836147; a=rsa-sha256; cv=none; b=hCdTEJCnvpOsXpT4nuY30hhVOzE/JYp9uRuvZtW64TdCEA3bsbJdp3lXOKcc3bl4fdhGsk B+d30DNAO9QUhVtREkneKKZdncUMxqKGT1RXJhotTBUNyQr5J/b4hIrHtQ89Up/ETEIlyJ /ilYVoQyFAeG4uP/oTgDAygdVA7pYqk= ARC-Authentication-Results: i=1; imf05.hostedemail.com; dkim=none; spf=pass (imf05.hostedemail.com: domain of mark.rutland@arm.com designates 217.140.110.172 as permitted sender) smtp.mailfrom=mark.rutland@arm.com; dmarc=pass (policy=none) header.from=arm.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1681836147; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:references; bh=G6Z/2ZgKXp8PPKCDjOV9eB8S1vzbb6PdfxIcqEgeVWg=; b=ECvoX7fed+o03c9VeFrrrmv3TGkxRjRNJ7b1uHyEjQnrqUq9iG+epyy4BKgZbnUxGIrwvA yIPaju2SiIkS6iu4sbU7fJml0dwlk8NEOfL7MsBj3RRe7NIXKeZ9ZYpCaI0y/yTVeFXxk4 JRWdDp+S4YqTrM8as4BzF34vFL7Tkj0= Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 8D72911FB; Tue, 18 Apr 2023 09:43:09 -0700 (PDT) Received: from lakrids.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com [10.121.207.14]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 80F633F5A1; Tue, 18 Apr 2023 09:42:24 -0700 (PDT) From: Mark Rutland To: linux-kernel@vger.kernel.org Cc: akpm@linux-foundation.org, andreyknvl@google.com, dvyukov@google.com, elver@google.com, glider@google.com, kasan-dev@googlegroups.com, linux-mm@kvack.org, mark.rutland@arm.com, ryabinin.a.a@gmail.com Subject: [PATCH] kasan: hw_tags: avoid invalid virt_to_page() Date: Tue, 18 Apr 2023 17:42:12 +0100 Message-Id: <20230418164212.1775741-1-mark.rutland@arm.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 X-Rspam-User: X-Rspamd-Queue-Id: 27357100013 X-Rspamd-Server: rspam01 X-Stat-Signature: eko88sxn3scquprhgn4ks3ss5k3dnxte X-HE-Tag: 1681836146-703167 X-HE-Meta: U2FsdGVkX1+R2ByAAjV7nB6NyrcaOkOWDA3jE4NItvcLWGnmy5r+wqSORJG6AIWbZ2HpHpqvQugQDHLJQEPv8/vOMo976uSIDFi693v0BmvKhFqKOaHS8gDdRogMxug8Bvwjv55muNMltIFx4RVz+hp+QSQTNZTO/tOAoUTgvX3zICDjjNd7++of3SaxA/O4COJtRxmjUSOJQ3hKv19Lr7lG3+XcNRKfWsS1Y0Lb2l/ZFzhULiJ7aWSvtXhjrvCK4tfvZA/xxKvVgse33Y1Y4BWJRX5cpxM4oDOumCAebFY02M0osh0MNpdHnXRkZdwsnH0nGKANJyoh7lE2vGA76UZ+o7Mxlw2EWSxQpwexWwQjpkw1C6U90I0bnADLruOjSgcGb2mZd2bUUIF3MYMTeBdueEoEQWr2IavkWOmVgPKRi7VEjSBxnm8YEIKBlYM8/2TZ/6EiRwu5CJkLDn0wx3H3lzl5JOQn3rvKBsCNtcXo8j9fpJryUGZhad8jCnnVDYYwUWHOuuyo2JzfleuwJdiH9l+hYKWhIbvwkpShBQUy6CCvLay2tz8oDkF1YHhKfNdGyjRhBQuUW/TfEKtcUlZGwviQ5sbXykJChK3dXDoa1dgpJITijXxwtpKIXycy6jMuzd4DVNnhPF23jpcdohrb0WaosBN3+AXQWmoSBqIFMTtGuJztq7MFySN/QsUl4e7r4Fa+6cNlkYdMMmreUmge9YY5x6NS0zz9ZNrWLct66K/jrejeIxpTZQbNeLOzDuZAv9fAAKSLB6KTkZ5EGdfk+wBNYegrPNX0IlyP9hFb2kZyN3ONPoi7BrOn67gYifieAl9cRdF6J/13vDNqjJNVt0oL3UKCm4hAUxlG7bHbiyEqj0E8mX+oLeqLMf7h96UbnL2yACrXOsMbAj0f0ItxYXlG99Y27tQ9Qt5AkOWbI5EiAliB1ihvVtQqMXqM2yP0hFAj9Yxuh9qdGUF ktsCZ3k4 m41k0wucJ07Y3132XBRvtZTb1E80wp6QOgaQOG952Gg3tzbwyQ4zjMqDxG2sA4IchckYScLdoWnGAkayIiRG8plC6mD7eJDVLMfpaNqbBrdEkpgOCvXJ51lO4qalRi2tjaC0QWwAnSgS5PWgE0k7eM0eetR7yDu31I3mQuE11vb4WP3oXy4Z6SjHgfA02AJ7aj3pll5raiEIc/QlRn8buamLi7yUaVsjTtlW7VitAforvh9hPOJAhDzXmcaYbUWcu6erAHZJOao+oADVfFMlfsenRvDbx/93HUdf/Z53RmVY3UIn1TfDbbv42zHBraN9Azfat5aJ4qXgqH2jW3lxoY1IHlX1lJo/sXbK6tw3uB3EgaIpABmIjOWHs/BF3xArtBYA8RijDcDLw/+TwyRI8Ia0HKBEDOr+ScK6VwX4ejbcK/BhthNFhJD8UFf7axEd7GmIDW4dFYCAJO4zmScdMqJ91IDlch9qX9VY/o1gJlZI4cU+f+i/bVuq2DlA2wjVUcOlgQqpyyRpeVtbrSedxZpxRZSRM90B+DtQ+0Uq43ULUxeFpJuCxbR+vM9AqesV1UzZS 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: When booting with 'kasan.vmalloc=off', a kernel configured with support for KASAN_HW_TAGS will explode at boot time due to bogus use of virt_to_page() on a vmalloc adddress. With CONFIG_DEBUG_VIRTUAL selected this will be reported explicitly, and with or without CONFIG_DEBUG_VIRTUAL the kernel will dereference a bogus address: | ------------[ cut here ]------------ | virt_to_phys used for non-linear address: (____ptrval____) (0xffff800008000000) | WARNING: CPU: 0 PID: 0 at arch/arm64/mm/physaddr.c:15 __virt_to_phys+0x78/0x80 | Modules linked in: | CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.3.0-rc3-00073-g83865133300d-dirty #4 | Hardware name: linux,dummy-virt (DT) | pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) | pc : __virt_to_phys+0x78/0x80 | lr : __virt_to_phys+0x78/0x80 | sp : ffffcd076afd3c80 | x29: ffffcd076afd3c80 x28: 0068000000000f07 x27: ffff800008000000 | x26: fffffbfff0000000 x25: fffffbffff000000 x24: ff00000000000000 | x23: ffffcd076ad3c000 x22: fffffc0000000000 x21: ffff800008000000 | x20: ffff800008004000 x19: ffff800008000000 x18: ffff800008004000 | x17: 666678302820295f x16: ffffffffffffffff x15: 0000000000000004 | x14: ffffcd076b009e88 x13: 0000000000000fff x12: 0000000000000003 | x11: 00000000ffffefff x10: c0000000ffffefff x9 : 0000000000000000 | x8 : 0000000000000000 x7 : 205d303030303030 x6 : 302e30202020205b | x5 : ffffcd076b41d63f x4 : ffffcd076afd3827 x3 : 0000000000000000 | x2 : 0000000000000000 x1 : ffffcd076afd3a30 x0 : 000000000000004f | Call trace: | __virt_to_phys+0x78/0x80 | __kasan_unpoison_vmalloc+0xd4/0x478 | __vmalloc_node_range+0x77c/0x7b8 | __vmalloc_node+0x54/0x64 | init_IRQ+0x94/0xc8 | start_kernel+0x194/0x420 | __primary_switched+0xbc/0xc4 | ---[ end trace 0000000000000000 ]--- | Unable to handle kernel paging request at virtual address 03fffacbe27b8000 | Mem abort info: | ESR = 0x0000000096000004 | EC = 0x25: DABT (current EL), IL = 32 bits | SET = 0, FnV = 0 | EA = 0, S1PTW = 0 | FSC = 0x04: level 0 translation fault | Data abort info: | ISV = 0, ISS = 0x00000004 | CM = 0, WnR = 0 | swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000041bc5000 | [03fffacbe27b8000] pgd=0000000000000000, p4d=0000000000000000 | Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP | Modules linked in: | CPU: 0 PID: 0 Comm: swapper/0 Tainted: G W 6.3.0-rc3-00073-g83865133300d-dirty #4 | Hardware name: linux,dummy-virt (DT) | pstate: 200000c5 (nzCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) | pc : __kasan_unpoison_vmalloc+0xe4/0x478 | lr : __kasan_unpoison_vmalloc+0xd4/0x478 | sp : ffffcd076afd3ca0 | x29: ffffcd076afd3ca0 x28: 0068000000000f07 x27: ffff800008000000 | x26: 0000000000000000 x25: 03fffacbe27b8000 x24: ff00000000000000 | x23: ffffcd076ad3c000 x22: fffffc0000000000 x21: ffff800008000000 | x20: ffff800008004000 x19: ffff800008000000 x18: ffff800008004000 | x17: 666678302820295f x16: ffffffffffffffff x15: 0000000000000004 | x14: ffffcd076b009e88 x13: 0000000000000fff x12: 0000000000000001 | x11: 0000800008000000 x10: ffff800008000000 x9 : ffffb2f8dee00000 | x8 : 000ffffb2f8dee00 x7 : 205d303030303030 x6 : 302e30202020205b | x5 : ffffcd076b41d63f x4 : ffffcd076afd3827 x3 : 0000000000000000 | x2 : 0000000000000000 x1 : ffffcd076afd3a30 x0 : ffffb2f8dee00000 | Call trace: | __kasan_unpoison_vmalloc+0xe4/0x478 | __vmalloc_node_range+0x77c/0x7b8 | __vmalloc_node+0x54/0x64 | init_IRQ+0x94/0xc8 | start_kernel+0x194/0x420 | __primary_switched+0xbc/0xc4 | Code: d34cfc08 aa1f03fa 8b081b39 d503201f (f9400328) | ---[ end trace 0000000000000000 ]--- | Kernel panic - not syncing: Attempted to kill the idle task! This is because init_vmalloc_pages() erroneously calls virt_to_page() on a vmalloc address, while virt_to_page() is only valid for addresses in the linear/direct map. Since init_vmalloc_pages() expects virtual addresses in the vmalloc range, it must use vmalloc_to_page() rather than virt_to_page(). We call init_vmalloc_pages() from __kasan_unpoison_vmalloc(), where we check !is_vmalloc_or_module_addr(), suggesting that we might encounter a non-vmalloc address. Luckily, this never happens. By design, we only call __kasan_unpoison_vmalloc() on pointers in the vmalloc area, and I have verified that we don't violate that expectation. Given that, is_vmalloc_or_module_addr() must always be true for any legitimate argument to __kasan_unpoison_vmalloc(). Correct init_vmalloc_pages() to use vmalloc_to_page(), and remove the redundant and misleading use of is_vmalloc_or_module_addr() in __kasan_unpoison_vmalloc(). Fixes: 6c2f761dad7851d8 ("kasan: fix zeroing vmalloc memory with HW_TAGS") Signed-off-by: Mark Rutland Cc: Alexander Potapenko Cc: Andrew Morton Cc: Andrey Konovalov Cc: Andrey Ryabinin Cc: Dmitry Vyukov Cc: Marco Elver Cc: kasan-dev@googlegroups.com Cc: linux-kernel@vger.kernel.org Cc: linux-mm@kvack.org --- mm/kasan/hw_tags.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/kasan/hw_tags.c b/mm/kasan/hw_tags.c index d1bcb0205327a..2f7ec2e1718ad 100644 --- a/mm/kasan/hw_tags.c +++ b/mm/kasan/hw_tags.c @@ -285,7 +285,7 @@ static void init_vmalloc_pages(const void *start, unsigned long size) const void *addr; for (addr = start; addr < start + size; addr += PAGE_SIZE) { - struct page *page = virt_to_page(addr); + struct page *page = vmalloc_to_page(addr); clear_highpage_kasan_tagged(page); } @@ -297,7 +297,7 @@ void *__kasan_unpoison_vmalloc(const void *start, unsigned long size, u8 tag; unsigned long redzone_start, redzone_size; - if (!kasan_vmalloc_enabled() || !is_vmalloc_or_module_addr(start)) { + if (!kasan_vmalloc_enabled()) { if (flags & KASAN_VMALLOC_INIT) init_vmalloc_pages(start, size); return (void *)start;