From patchwork Sun Feb 11 09:17:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Paul_Heidekr=C3=BCger?= X-Patchwork-Id: 199395 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp1842899dyd; Sun, 11 Feb 2024 01:18:31 -0800 (PST) X-Google-Smtp-Source: AGHT+IFAKxeY3fJ4g+K9xQr92xMfTq9PtI85DRd23EWbTaOoH8ySi0VDteNxvVFrBQY2MdO23BQV X-Received: by 2002:a92:d4ca:0:b0:363:cac1:644 with SMTP id o10-20020a92d4ca000000b00363cac10644mr4570235ilm.31.1707643111659; Sun, 11 Feb 2024 01:18:31 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707643111; cv=pass; d=google.com; s=arc-20160816; b=zJTk/uayrx5GqNaK6q0o3mzCgTUEhLf0I4XQCN+spF6fRLZ3dHa6EwpThocUhJiJXN bKlYcN8IGiYpKiarfLQ9yzrt7wN0iltOtLgrn8FKjXzx4cTYfC2Dx19UDj4+NpUBf2FC t4lovD0ps0M8NspRO/W06C8SzDExXRvygDWZfuPmztl2b2Q3h+Sss4LETGcTE99xN17h QomAsBulUqlXPg44vRfOcMOzJYNRGTy4ktvU0ZNuLp4VwQ/DlIAdiiWXjXnbGEhPa3Kg i1Lku904PlotySCE0fjQwzGU18Z9wq7Z8U6YhdQXn6wBK1J/68+Fx/eBLJFgP0aCo8yl yi2Q== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=nyUqcldidtnXWwbTceXwthhkZZm9TNzWOm9++Z2b+gM=; fh=l2Ye6tOysu6iCQ/cT/jNhnJhSAPQPv+ojsJd/ZdV9SI=; b=AjZhXGpk8iH7unU+Dp4UCmc22gLAsnCPVFR7QOc0tGDxiToPNzDUXtBC7UMY8BoXlM orrrHRxmG29zUmrS4ZVefIPiBAsyfSM04j0Fe50iomC3GJ9p5hEGmvDx9bNQoCZBnSUW Tjq457xOUzYekHnwP5oZvyTpUJcgtTYsMhBw4k2BSZE3zdvlNdXtCCleBi85W3TT4QaL vcnX1lj9Vpg8R/6UJYG4Cs+TvF1UIyNtVFJ2NMc0w2Jui1M4U4McilhlSSdE/AL7xN/m 8WRzxy8x2g8MQLwKyobFaROr3VkXWwWg8nVOj6ZzT/mPqBaZJYxI6Wh80PVO7qKC++0v Xidg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@tum.de header.s=tu-postout21 header.b=fXFBmetf; arc=pass (i=1 spf=pass spfdomain=tum.de dkim=pass dkdomain=tum.de dmarc=pass fromdomain=tum.de); spf=pass (google.com: domain of linux-kernel+bounces-60676-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-60676-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=tum.de X-Forwarded-Encrypted: i=2; AJvYcCW/KuDnC9pTxWwZciDEP1/ToT0Jz5frepa8sGLAS+vWOqV0ZN2UtmGaTr9gGN8Gv8n1pdcxJpcsIy6DhoRkwTxNj18ynQ== Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id bw28-20020a056a02049c00b005cf268638f4si4832800pgb.156.2024.02.11.01.18.31 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 11 Feb 2024 01:18:31 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-60676-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@tum.de header.s=tu-postout21 header.b=fXFBmetf; arc=pass (i=1 spf=pass spfdomain=tum.de dkim=pass dkdomain=tum.de dmarc=pass fromdomain=tum.de); spf=pass (google.com: domain of linux-kernel+bounces-60676-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-60676-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=tum.de Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 315E5B22775 for ; Sun, 11 Feb 2024 09:18:30 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8C45159B68; Sun, 11 Feb 2024 09:18:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=tum.de header.i=@tum.de header.b="fXFBmetf" Received: from postout1.mail.lrz.de (postout1.mail.lrz.de [129.187.255.137]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 464E359162 for ; Sun, 11 Feb 2024 09:18:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=129.187.255.137 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707643085; cv=none; b=o/xzVltZEliyRoZ7tYW27m0ZRJyeHikVrn6qVpKjwa9IPDKWzER93dkuPOWHwlQ9GTSaqzW2gxdLuYBXivGDmaDa0GFqeWCcJZraf/ZUGlpOOIAdxrGlsZLgjt0kwXvAs/vyfSI5BkE3TcRq1CmBKp6ncgANFuANPBxo644GCRI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707643085; c=relaxed/simple; bh=aEaq/TzcHg4rMQdODyuar0MImODB9bbF3bqWLrgPZ6Y=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=gLw1z4SrlMknkLdYYxcyFKu6eGhrb1/2KkPJMboVis/DOMWE3l2HYcae0NQ+psWMZOedZF4NeNMxdRgTQhmnCKP5tQ2MSP5vQl6zb4ucdonwBswu3cRw9NWeqYTLgKnljbK0i0H3bdWp7UvqsIuUK3n+XjwyaRYyBVNM2pDdPLY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=tum.de; spf=pass smtp.mailfrom=tum.de; dkim=pass (2048-bit key) header.d=tum.de header.i=@tum.de header.b=fXFBmetf; arc=none smtp.client-ip=129.187.255.137 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=tum.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=tum.de Received: from lxmhs51.srv.lrz.de (localhost [127.0.0.1]) by postout1.mail.lrz.de (Postfix) with ESMTP id 4TXhny4cG0zySP; Sun, 11 Feb 2024 10:17:58 +0100 (CET) Authentication-Results: postout.lrz.de (amavisd-new); dkim=pass (2048-bit key) reason="pass (just generated, assumed good)" header.d=tum.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tum.de; h= content-transfer-encoding:content-type:content-type:mime-version :references:in-reply-to:x-mailer:message-id:date:date:subject :subject:from:from:received:received; s=tu-postout21; t= 1707643077; bh=aEaq/TzcHg4rMQdODyuar0MImODB9bbF3bqWLrgPZ6Y=; b=f XFBmetfZhZDsxhHssUdJ4P4/rpNM0n5RT2MIBdcyB5bpqrqppaYsNOuzr/gGCkgS nTrGDgH/VL5I5MGiBKzSMHJSGI/5N5q+hekl2twLc6nhB0j2rre590B2OSQ2AAZ0 7AlxNkL9QA8DOGEbfNBAnDvG6h5yVLi5e3L8uAE7pVHUmO2xVKQaXnby9ij5Tivc VexJVFItZhwdYsfMSJsBC4SIS7dVMdhs6fP6IShahynj4Kg0g8d44t2LuwWb6FHH 1JPgLzXzkxaFnmrvSc06tf38Bm8v70CfZdCS+BxAgVwDB2SjVO4nqMx8RAv4E/Ij Rj8RHFknFAcndq+lJSD3w== X-Virus-Scanned: by amavisd-new at lrz.de in lxmhs51.srv.lrz.de X-Spam-Flag: NO X-Spam-Score: -2.88 X-Spam-Level: Received: from postout1.mail.lrz.de ([127.0.0.1]) by lxmhs51.srv.lrz.de (lxmhs51.srv.lrz.de [127.0.0.1]) (amavisd-new, port 20024) with LMTP id voYhHrpRVFxn; Sun, 11 Feb 2024 10:17:57 +0100 (CET) Received: from sienna.fritz.box (ppp-93-104-92-100.dynamic.mnet-online.de [93.104.92.100]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by postout1.mail.lrz.de (Postfix) with ESMTPSA id 4TXhnx1Vk2zySF; Sun, 11 Feb 2024 10:17:57 +0100 (CET) From: =?utf-8?q?Paul_Heidekr=C3=BCger?= To: paul.heidekrueger@tum.de Cc: akpm@linux-foundation.org, andreyknvl@gmail.com, dvyukov@google.com, elver@google.com, glider@google.com, kasan-dev@googlegroups.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org, ryabinin.a.a@gmail.com, vincenzo.frascino@arm.com, Mark Rutland Subject: [PATCH v2] kasan: add atomic tests Date: Sun, 11 Feb 2024 09:17:20 +0000 Message-Id: <20240211091720.145235-1-paul.heidekrueger@tum.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240202113259.3045705-1-paul.heidekrueger@tum.de> References: <20240202113259.3045705-1-paul.heidekrueger@tum.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789642201817570664 X-GMAIL-MSGID: 1790593583706663884 Test that KASan can detect some unsafe atomic accesses. As discussed in the linked thread below, these tests attempt to cover the most common uses of atomics and, therefore, aren't exhaustive. CC: Marco Elver CC: Andrey Konovalov Link: https://lore.kernel.org/all/20240131210041.686657-1-paul.heidekrueger@tum.de/T/#u Closes: https://bugzilla.kernel.org/show_bug.cgi?id=214055 Reviewed-by: Marco Elver Tested-by: Marco Elver Acked-by: Mark Rutland Signed-off-by: Paul Heidekrüger Reviewed-by: Andrey Konovalov --- Changes PATCH v1 -> PATCH v2: * Make explicit cast implicit as per Mark's feedback * Increase the size of the "a2" allocation as per Andrey's feedback * Add tags Changes PATCH RFC v2 -> PATCH v1: * Remove casts to void* * Remove i_safe variable * Add atomic_long_* test cases * Carry over comment from kasan_bitops_tags() Changes PATCH RFC v1 -> PATCH RFC v2: * Adjust size of allocations to make kasan_atomics() work with all KASan modes * Remove comments and move tests closer to the bitops tests * For functions taking two addresses as an input, test each address in a separate function call. * Rename variables for clarity * Add tests for READ_ONCE(), WRITE_ONCE(), smp_load_acquire() and smp_store_release() mm/kasan/kasan_test.c | 79 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/mm/kasan/kasan_test.c b/mm/kasan/kasan_test.c index 8281eb42464b..7bf09699b145 100644 --- a/mm/kasan/kasan_test.c +++ b/mm/kasan/kasan_test.c @@ -1150,6 +1150,84 @@ static void kasan_bitops_tags(struct kunit *test) kfree(bits); } +static void kasan_atomics_helper(struct kunit *test, void *unsafe, void *safe) +{ + int *i_unsafe = unsafe; + + KUNIT_EXPECT_KASAN_FAIL(test, READ_ONCE(*i_unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, WRITE_ONCE(*i_unsafe, 42)); + KUNIT_EXPECT_KASAN_FAIL(test, smp_load_acquire(i_unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, smp_store_release(i_unsafe, 42)); + + KUNIT_EXPECT_KASAN_FAIL(test, atomic_read(unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_set(unsafe, 42)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_add(42, unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_sub(42, unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_inc(unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_dec(unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_and(42, unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_andnot(42, unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_or(42, unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_xor(42, unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_xchg(unsafe, 42)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_cmpxchg(unsafe, 21, 42)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_try_cmpxchg(unsafe, safe, 42)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_try_cmpxchg(safe, unsafe, 42)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_sub_and_test(42, unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_dec_and_test(unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_inc_and_test(unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_add_negative(42, unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_add_unless(unsafe, 21, 42)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_inc_not_zero(unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_inc_unless_negative(unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_dec_unless_positive(unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_dec_if_positive(unsafe)); + + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_read(unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_set(unsafe, 42)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_add(42, unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_sub(42, unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_inc(unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_dec(unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_and(42, unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_andnot(42, unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_or(42, unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_xor(42, unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_xchg(unsafe, 42)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_cmpxchg(unsafe, 21, 42)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_try_cmpxchg(unsafe, safe, 42)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_try_cmpxchg(safe, unsafe, 42)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_sub_and_test(42, unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_dec_and_test(unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_inc_and_test(unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_add_negative(42, unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_add_unless(unsafe, 21, 42)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_inc_not_zero(unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_inc_unless_negative(unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_dec_unless_positive(unsafe)); + KUNIT_EXPECT_KASAN_FAIL(test, atomic_long_dec_if_positive(unsafe)); +} + +static void kasan_atomics(struct kunit *test) +{ + void *a1, *a2; + + /* + * Just as with kasan_bitops_tags(), we allocate 48 bytes of memory such + * that the following 16 bytes will make up the redzone. + */ + a1 = kzalloc(48, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, a1); + a2 = kzalloc(sizeof(atomic_long_t), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, a1); + + /* Use atomics to access the redzone. */ + kasan_atomics_helper(test, a1 + 48, a2); + + kfree(a1); + kfree(a2); +} + static void kmalloc_double_kzfree(struct kunit *test) { char *ptr; @@ -1553,6 +1631,7 @@ static struct kunit_case kasan_kunit_test_cases[] = { KUNIT_CASE(kasan_strings), KUNIT_CASE(kasan_bitops_generic), KUNIT_CASE(kasan_bitops_tags), + KUNIT_CASE(kasan_atomics), KUNIT_CASE(kmalloc_double_kzfree), KUNIT_CASE(rcu_uaf), KUNIT_CASE(workqueue_uaf),