From patchwork Tue Oct 8 19:29:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sabyrzhan Tasbolatov X-Patchwork-Id: 13826880 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 7451FCEFC42 for ; Tue, 8 Oct 2024 19:28:25 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 0EEF06B0093; Tue, 8 Oct 2024 15:28:25 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 0511A6B0096; Tue, 8 Oct 2024 15:28:25 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id E0BFC6B0098; Tue, 8 Oct 2024 15:28:24 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id BFABD6B0093 for ; Tue, 8 Oct 2024 15:28:24 -0400 (EDT) Received: from smtpin04.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay01.hostedemail.com (Postfix) with ESMTP id F15FE1C4F03 for ; Tue, 8 Oct 2024 19:28:22 +0000 (UTC) X-FDA: 82651421328.04.D5FFE07 Received: from mail-wr1-f52.google.com (mail-wr1-f52.google.com [209.85.221.52]) by imf14.hostedemail.com (Postfix) with ESMTP id 9AF3410000D for ; Tue, 8 Oct 2024 19:28:22 +0000 (UTC) Authentication-Results: imf14.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=CHawoUgj; spf=pass (imf14.hostedemail.com: domain of snovitoll@gmail.com designates 209.85.221.52 as permitted sender) smtp.mailfrom=snovitoll@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1728415659; 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:in-reply-to:references:references:dkim-signature; bh=4YU80h+e3WqJR9RRP2zzYoIrqiryuhlMCUmmaZXckb4=; b=Xnv91xUhSmzaMMT/pSIdgyKHxzVXuXd1WbTzjfqCnomTRJp52iCjGbR/eqUq7AiuQhRCb4 Em3Xe4QN/IQSIhZbUEcmKSRBHG+wyMxLeskdTbELDzD1Yw9NUqfuO5bMZV6McaW5o7hKbm 75LWi0LoE0ODva7iZr6xmljG3hKLBnY= ARC-Authentication-Results: i=1; imf14.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=CHawoUgj; spf=pass (imf14.hostedemail.com: domain of snovitoll@gmail.com designates 209.85.221.52 as permitted sender) smtp.mailfrom=snovitoll@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1728415659; a=rsa-sha256; cv=none; b=wecxdCSv3Kwww5qADbDwuU7tGa5nUV/41bfEWqOlKVpgZhUbfPW4UkHAHZO3QWRgr2E3ya /dIrHB+HKRQxApaHifNUV8H0+W9BzINrxjC8hJ76oUCpZWg3iyEtARuUo2yQMwchJbYXkA q/VOSlJrwGksYgqZmy00NkhzLPDwq40= Received: by mail-wr1-f52.google.com with SMTP id ffacd0b85a97d-37d39d9f782so88810f8f.1 for ; Tue, 08 Oct 2024 12:28:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1728415701; x=1729020501; darn=kvack.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=4YU80h+e3WqJR9RRP2zzYoIrqiryuhlMCUmmaZXckb4=; b=CHawoUgjl6DQw1lhAsoRdUHgU52ICdLBPH3FDC5rC3IJibjyhxBoYHkShtMfXtVwNZ sH+m+G98DtZ9/MLPJrj+Rb+AHQ5zghVKZGPER2Z+5Q+yCKGoCJWDiRLwcfP8BpMtbiCB hksP8sDS1Hby6GZzd7uxy9skcohzzV3Tb0OJzW72ockmzjuyDgoTVFsbKsPUAzSTWIae rhC8WFWpLxP1VH3qNmt8eXjTiq27vabgSe83eABnyn5qCav1LhoxOvgADo1DcYuHwYbO H5HAGsw6uE6lBf2EowwmJ5Z8u8zeP9TP06vdvR+HATOMrfm1+61WVmovwPnfsSswNYUu 3hgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1728415701; x=1729020501; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4YU80h+e3WqJR9RRP2zzYoIrqiryuhlMCUmmaZXckb4=; b=N6NEdd0NjlmHQgQyjLtplx9zu75Kwo+oLPlS+3pdFRGl3kl5Kryi6hU05z42r9WGzt 3L52yd2xjXJk40ri9ZsH9m/sdHVmkR0d0ZLm19RVDAwlqsgnoZl12GTSE74UHv2lbS3+ 9EdyfS7PxGWYUvwhOM0gKJK2CkpL/kAE+ItlAZ2PiP7JUYY+nM+fEI2w/1C3zfIFBvxv IMUGKz5ei8NM9xsXw5TL9h4b9xRBm6P8BShvhAZ5LeIQgNMiVAiEICr28J3OLx7tg7Z/ kHhYicfGtk+pVFLr4WQjj13In9Qd5ZFXfcj2GUazcDipraUZ1gi6PFfPpoYKfqyUBpLI 5Pjg== X-Forwarded-Encrypted: i=1; AJvYcCUsjsgZmdBAdSsLN+SZKgcOg7DSC0CKEWf97xi+0bReZlIm5EQrXVVmBndg09oTBHYnBsgu43Y/nw==@kvack.org X-Gm-Message-State: AOJu0YxWJ/vlpD9CUATy2h3P5J+F6b5nffVfvPHedSNbpeN46YMyk2+W TkALk57lazkVSuPsekHvqLh/3N4wkEjLlLlR43I8vqqXx8EaFfy+ X-Google-Smtp-Source: AGHT+IF+l2nCX8ohR0udWzU8vUvvwxVBA+1g+7Q7QLi0/L6ruBDHyuNFJFp5VVyOjrIYQ/Vkpg4eAw== X-Received: by 2002:a05:6000:4590:b0:374:ca16:e09b with SMTP id ffacd0b85a97d-37d0e6dad03mr8291114f8f.9.1728415700750; Tue, 08 Oct 2024 12:28:20 -0700 (PDT) Received: from work.. ([94.200.20.179]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-37d39ea2eacsm181675f8f.15.2024.10.08.12.28.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Oct 2024 12:28:20 -0700 (PDT) From: Sabyrzhan Tasbolatov To: elver@google.com Cc: akpm@linux-foundation.org, andreyknvl@gmail.com, bpf@vger.kernel.org, dvyukov@google.com, glider@google.com, kasan-dev@googlegroups.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org, ryabinin.a.a@gmail.com, snovitoll@gmail.com, syzbot+61123a5daeb9f7454599@syzkaller.appspotmail.com, vincenzo.frascino@arm.com Subject: [PATCH v4] mm, kasan, kmsan: copy_from/to_kernel_nofault Date: Wed, 9 Oct 2024 00:29:10 +0500 Message-Id: <20241008192910.2823726-1-snovitoll@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Rspam-User: X-Stat-Signature: t1tuu3h1nyd3z9h3ymqzebqucddgzrzg X-Rspamd-Queue-Id: 9AF3410000D X-Rspamd-Server: rspam11 X-HE-Tag: 1728415702-376852 X-HE-Meta: U2FsdGVkX1+LRZHskPkVHqKDDBM2NOrjtxofaGw53ri5tMaWoHzLM02pc8xJ4uO0UPl+JAyLtVc/G64sVRv3z4EvkUiAkEBQr1mKBEkt50kN9BMdd7OLjADWNuFtoByccNaax14smX42UQ4b86qfJ0IgIOSeH2tkGA+1yvVa+MIkX70noCFm3+f1hWpM2SCC/Vo2oMmYwKH+B7+1c+ngmC8CraSkV2OIuaCZ8Tp8IVNSRIcCTWwvLg2UsPLvz/atmcRdOhWJzZvO8J3Wa7Rgcb4fj9c9qMOfVfqJ3CqinYqJIFwe8rsVvdqZaTQJKMsT/Wd4GdniM1UM1JhoB2YX2iM5emoduVCzA9efD/Mp/U6Sfy6fFvWwZ8X6nBipL7U8ZCkRGuD8av3rp4Cw4o+E+1oaGrOPmx5CUzoN0fllei7x9TGt97BRhzW6hiok023gVBicjO6Cl+tXDppdRmsJttERpGvDNoqG73JaPcnS0EY95z6lV9j8o9/qp6du+JJ5roC7iIAPbJclC+zmsJfcfWg+ZLP+WjJRj18GAH3PiRJYnkrtetX4EUEgy/Itz9bIRWK/6E8v/mMeVOAE1BM0BOQSC5v8g7kC4Wo2WBayG10NvVnQAJ/17xMv6iApRJTF/9hlYEkQZC/i5lLWYRRLO3tvP7X4U0VEnCoD+D9/TN8mZtiazPv+uV/zz8uy7/owNZfhRRMcUYoQSW4C7y9zilQHIt5Bue/IvuJM/44IF+2JmD5NvaDRNwlltOY36b/r1GWStnXn2blWHkQFVX4byThvPhrYuBaMDwNhBN75HIKodW4EDrvQ/zcRFI0RXNhuXwg9f7s1Ki6upAT6zVtqVjA8JhSYVOg2OZGz8G+6X76wJMWr8jtX+MtKFWwxz1rpeUbBqdpHaWKA00O3COQZB/pQ6BRFmNJjFulkCc7ihKRzI1TRaXAi5eZlKDtuH+VBB9fqMiGrx9dHZnmbHZZ 3RV/030g +deZYvvB2Y9oIzBuGOnTUm2HEsqT6m1dlrOEDL7XJjIEbEjUIhtsL3g18ViE1H6q4ZbemQXsj5YlvnEI4RNYT+60vfmwdGqUvJPU14gPchLMvteTdw+a2hI1sK7rNF9fDPL5qyLn4RiiihfXXXVsfNUIbIYyEXdgeMU84lC5nT6h7f8joNfA+SdsdK7D+Gyq2BGcg8SSbwxyWqGp0usAcXiRhD4RF9y2FUdZmvW+qFpMs3Zxu3cXaBLw0Epi9MtyVRGEd3Uq19ZC7WHKci5vNDkpn7HYD/HHhiMaQ3D78bNJ1B4EFSPV9ilVPxaB0tIwYjACQdKZM8h2SR2xSKtP+lLJrqc7GH5osnY1kGC06ORMbuip+USxQobs0TH+i1o/VxM7R8kxyzXeAgK16Eyniez1L3pxU+4XI4S1AHzvwrv6aKIXCUk/Sc8iMLiDwlPeNDXDrWb+kLE7ucezeDXOY5Kf+P3Sb7y5pXSJ4lkoRHjSyMmPkCsqYYca7QAoag/1VFt2cHZZ5fd2Y4MECJQNnEgik8Hx1JNZsgkeymziOnPDZfoFLVziq1+e9Rh1ReXHuMRvHmJLj2MniOv8RLkajjx02JHTM/uIvvB7dURCol3RUbC9UT5a/UfeVzEQY5Rx+MF6UZd5402EhtvKs33nebA4Kwp+hKTM5cU6516QOtDLRWIvY2DR2jMHYQw== 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: List-Subscribe: List-Unsubscribe: Instrument copy_from_kernel_nofault() with KMSAN for uninitialized kernel memory check and copy_to_kernel_nofault() with KASAN, KCSAN to detect the memory corruption. syzbot reported that bpf_probe_read_kernel() kernel helper triggered KASAN report via kasan_check_range() which is not the expected behaviour as copy_from_kernel_nofault() is meant to be a non-faulting helper. Solution is, suggested by Marco Elver, to replace KASAN, KCSAN check in copy_from_kernel_nofault() with KMSAN detection of copying uninitilaized kernel memory. In copy_to_kernel_nofault() we can retain instrument_write() explicitly for the memory corruption instrumentation. copy_to_kernel_nofault() is tested on x86_64 and arm64 with CONFIG_KASAN_SW_TAGS. On arm64 with CONFIG_KASAN_HW_TAGS, kunit test currently fails. Need more clarification on it - currently, disabled in kunit test. Link: https://lore.kernel.org/linux-mm/CANpmjNMAVFzqnCZhEity9cjiqQ9CVN1X7qeeeAp_6yKjwKo8iw@mail.gmail.com/ Reviewed-by: Marco Elver Reported-by: syzbot+61123a5daeb9f7454599@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=61123a5daeb9f7454599 Reported-by: Andrey Konovalov Closes: https://bugzilla.kernel.org/show_bug.cgi?id=210505 Signed-off-by: Sabyrzhan Tasbolatov Reviewed-by:. --- v2: - squashed previous submitted in -mm tree 2 patches based on Linus tree v3: - moved checks to *_nofault_loop macros per Marco's comments - edited the commit message v4: - replaced Suggested-By with Reviewed-By: Marco Elver --- mm/kasan/kasan_test_c.c | 27 +++++++++++++++++++++++++++ mm/kmsan/kmsan_test.c | 17 +++++++++++++++++ mm/maccess.c | 10 ++++++++-- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/mm/kasan/kasan_test_c.c b/mm/kasan/kasan_test_c.c index a181e4780d9d..5cff90f831db 100644 --- a/mm/kasan/kasan_test_c.c +++ b/mm/kasan/kasan_test_c.c @@ -1954,6 +1954,32 @@ static void rust_uaf(struct kunit *test) KUNIT_EXPECT_KASAN_FAIL(test, kasan_test_rust_uaf()); } +static void copy_to_kernel_nofault_oob(struct kunit *test) +{ + char *ptr; + char buf[128]; + size_t size = sizeof(buf); + + /* Not detecting fails currently with HW_TAGS */ + KASAN_TEST_NEEDS_CONFIG_OFF(test, CONFIG_KASAN_HW_TAGS); + + ptr = kmalloc(size - KASAN_GRANULE_SIZE, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); + OPTIMIZER_HIDE_VAR(ptr); + + if (IS_ENABLED(CONFIG_KASAN_SW_TAGS)) { + /* Check that the returned pointer is tagged. */ + KUNIT_EXPECT_GE(test, (u8)get_tag(ptr), (u8)KASAN_TAG_MIN); + KUNIT_EXPECT_LT(test, (u8)get_tag(ptr), (u8)KASAN_TAG_KERNEL); + } + + KUNIT_EXPECT_KASAN_FAIL(test, + copy_to_kernel_nofault(&buf[0], ptr, size)); + KUNIT_EXPECT_KASAN_FAIL(test, + copy_to_kernel_nofault(ptr, &buf[0], size)); + kfree(ptr); +} + static struct kunit_case kasan_kunit_test_cases[] = { KUNIT_CASE(kmalloc_oob_right), KUNIT_CASE(kmalloc_oob_left), @@ -2027,6 +2053,7 @@ static struct kunit_case kasan_kunit_test_cases[] = { KUNIT_CASE(match_all_not_assigned), KUNIT_CASE(match_all_ptr_tag), KUNIT_CASE(match_all_mem_tag), + KUNIT_CASE(copy_to_kernel_nofault_oob), KUNIT_CASE(rust_uaf), {} }; diff --git a/mm/kmsan/kmsan_test.c b/mm/kmsan/kmsan_test.c index 13236d579eba..9733a22c46c1 100644 --- a/mm/kmsan/kmsan_test.c +++ b/mm/kmsan/kmsan_test.c @@ -640,6 +640,22 @@ static void test_unpoison_memory(struct kunit *test) KUNIT_EXPECT_TRUE(test, report_matches(&expect)); } +static void test_copy_from_kernel_nofault(struct kunit *test) +{ + long ret; + char buf[4], src[4]; + size_t size = sizeof(buf); + + EXPECTATION_UNINIT_VALUE_FN(expect, "copy_from_kernel_nofault"); + kunit_info( + test, + "testing copy_from_kernel_nofault with uninitialized memory\n"); + + ret = copy_from_kernel_nofault((char *)&buf[0], (char *)&src[0], size); + USE(ret); + KUNIT_EXPECT_TRUE(test, report_matches(&expect)); +} + static struct kunit_case kmsan_test_cases[] = { KUNIT_CASE(test_uninit_kmalloc), KUNIT_CASE(test_init_kmalloc), @@ -664,6 +680,7 @@ static struct kunit_case kmsan_test_cases[] = { KUNIT_CASE(test_long_origin_chain), KUNIT_CASE(test_stackdepot_roundtrip), KUNIT_CASE(test_unpoison_memory), + KUNIT_CASE(test_copy_from_kernel_nofault), {}, }; diff --git a/mm/maccess.c b/mm/maccess.c index 518a25667323..3ca55ec63a6a 100644 --- a/mm/maccess.c +++ b/mm/maccess.c @@ -13,9 +13,14 @@ bool __weak copy_from_kernel_nofault_allowed(const void *unsafe_src, return true; } +/* + * The below only uses kmsan_check_memory() to ensure uninitialized kernel + * memory isn't leaked. + */ #define copy_from_kernel_nofault_loop(dst, src, len, type, err_label) \ while (len >= sizeof(type)) { \ - __get_kernel_nofault(dst, src, type, err_label); \ + __get_kernel_nofault(dst, src, type, err_label); \ + kmsan_check_memory(src, sizeof(type)); \ dst += sizeof(type); \ src += sizeof(type); \ len -= sizeof(type); \ @@ -49,7 +54,8 @@ EXPORT_SYMBOL_GPL(copy_from_kernel_nofault); #define copy_to_kernel_nofault_loop(dst, src, len, type, err_label) \ while (len >= sizeof(type)) { \ - __put_kernel_nofault(dst, src, type, err_label); \ + __put_kernel_nofault(dst, src, type, err_label); \ + instrument_write(dst, sizeof(type)); \ dst += sizeof(type); \ src += sizeof(type); \ len -= sizeof(type); \