From patchwork Mon Feb 12 08:33:42 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: 199621 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2302094dyd; Mon, 12 Feb 2024 00:35:46 -0800 (PST) X-Google-Smtp-Source: AGHT+IHMaBHvFO8gDiMzz19H3yQ+BsFIXaVMhqwvQCDvrlp6XUZBh/kMy/nsvHo1RWMCIehpH9mk X-Received: by 2002:a05:6870:ac88:b0:219:f2a3:d8ad with SMTP id ns8-20020a056870ac8800b00219f2a3d8admr9240028oab.42.1707726946462; Mon, 12 Feb 2024 00:35:46 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707726946; cv=pass; d=google.com; s=arc-20160816; b=IpsWUs0Vnw1aqNcXocL+BhK/YB4DQXIunleh/3iJqDDLjOve5S98DAQO2Pwm5P9p+l SeUcj7JCRaDweSzsNZeEBLEai5CsNV++w2Qo5QM5Mdo3yXwMmLWYbRcSPjbkMKCiAZAP HCwR0wi/tS68vm/xJDPttR3nfdTbaU/FejE1vJPYB8FmFm+ZhwHiM8yKyWYG4YP5kmyr 5H/YwCalNZs+2mfE4lIc4OcfuRygGQsPWwrOPnpQZS9sgbIce967or25tJ7tqP14Osw5 SJhaI9YXaUvV7rMSrip0iTpRbxQdNdupB0DYd7ucyceLX/YgmXrzhxEzoNclyJWJ2Jv4 K1ng== 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=4Vrq6pH7f9iGB8LwYV2/mtF1jhtmkM8pYMdQmJLjgFk=; fh=TZV2WEMtux6wKfM14j/wr8oa/KuOF80o1NXVnajTXQo=; b=KUZeXHDVfVl/1v0S6Z2a9XPUsdExwidgUW/tVWkzhKFCq415tuXOV9rrgrO7iD+hY8 gEajytqK0W73jCfXyCs+PVssEutaGU7ixKa88UWB8Xt/0byFoKuRJ8MeEsdduVEO9QJK Vk7eoyyoFwrEHBhwAS0xaeKMTH92Ldq3CGlsG6NtvbIbRUmvZpBxsZYkSnQ0t2Uisgnw /2VRB1ZB0D8BthsaMrWFQ1NRgan0+gf+atLDOsDW9NjHuQxmRFW9RITVelAfInHA3UVm 1UbNPfCsPw1oKmqDCG55w2XeLFcmWyLeHDdDyseU8uteShcQlKhZ6hLFwF8FjisOu/V9 Qk4Q==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@tum.de header.s=tu-postout21 header.b=eP+lL5so; 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-61208-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61208-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=tum.de X-Forwarded-Encrypted: i=2; AJvYcCU81/fDdGnJMKy7iHH0DBB3j7qW2vjaaC8PA8m7rVcSW5FLOUVw40t4JM2c8vYGG5HbSgfzAmZYn7WzK7MATD1lxj9Rvw== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id e30-20020a63745e000000b005dc4a7c2325si5917268pgn.824.2024.02.12.00.35.46 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 00:35:46 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61208-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@tum.de header.s=tu-postout21 header.b=eP+lL5so; 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-61208-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61208-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 sv.mirrors.kernel.org (Postfix) with ESMTPS id 602B12809C9 for ; Mon, 12 Feb 2024 08:35:43 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9B73FFBF5; Mon, 12 Feb 2024 08:34:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=tum.de header.i=@tum.de header.b="eP+lL5so" Received: from postout2.mail.lrz.de (postout2.mail.lrz.de [129.187.255.138]) (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 754AE10A1F for ; Mon, 12 Feb 2024 08:34:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=129.187.255.138 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707726875; cv=none; b=qP4qU8pQQh9mDBlOALy1xhP9sTuCB33lKfEsAJWaexeCOHj4DTAGAgDRNOctC+WLxvyau+4ZSHgdfjkvC8ZcYKlcSS2dRswnLf5kovluK/q4IMF7oXXGQH45SrePI/Zm3Wo4DBp3BQbd+yL6OSKsafFdIcVasAIuM7LTxVSyxeY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707726875; c=relaxed/simple; bh=63/KQ22XZagYlqAxmscXTKOnUwxan5bZ489uORJotHg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=Y7Bw+KLWLRjBDTtCg/swz2rmXmZa7Qf9+PdR9Ko2BKVG9Dmw1aTyc54jUhPxrjqWUkcl9wcnJVq1pWmYhgEEIe+Rpmi4+Qrf2atilanOi11eluJVpzzJ5p2W0/9aN2JpmTA3W50d+rqH+XMrbrYhLUwV1Hucke/PWl6GeTGz7Jk= 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=eP+lL5so; arc=none smtp.client-ip=129.187.255.138 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 lxmhs52.srv.lrz.de (localhost [127.0.0.1]) by postout2.mail.lrz.de (Postfix) with ESMTP id 4TYHnB5NqfzyV2; Mon, 12 Feb 2024 09:34:22 +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= 1707726862; bh=63/KQ22XZagYlqAxmscXTKOnUwxan5bZ489uORJotHg=; b=e P+lL5soTdN5dYXbkIZyhFde2t9wTh/6jG9u93h937pr9CBBE2G8s9bggKfzNKjFo ZwAAuhyWOGFkoIgI9klA9Hg1Vx9K/GPHYn/G4bAEgKYr+q5P9G+jfQEyWd9Hg9+Y WvCewye1kjmUHiDF9yOo0n8isZ/Oj5zL+VAN2JqICiZrcjRv3NQdP++1UAmLCJkB n90OHiI62UOlIeueycB0kMJyovvJHtDKn4JGSv2H8QMEk64Iu5GokCic2Ed9gIOy dYbCzjH5Jh6eoxQ/Nxla+QUzTiHRNXjDrRnLWYuqQczpKdHEPupIBgyjvNF7pXMC 0lqDnIyP8NpCBbochH4OQ== X-Virus-Scanned: by amavisd-new at lrz.de in lxmhs52.srv.lrz.de X-Spam-Flag: NO X-Spam-Score: -2.88 X-Spam-Level: Received: from postout2.mail.lrz.de ([127.0.0.1]) by lxmhs52.srv.lrz.de (lxmhs52.srv.lrz.de [127.0.0.1]) (amavisd-new, port 20024) with LMTP id MRHxCgA6u-EA; Mon, 12 Feb 2024 09:34:22 +0100 (CET) Received: from sienna.fritz.box (ppp-93-104-66-45.dynamic.mnet-online.de [93.104.66.45]) (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 postout2.mail.lrz.de (Postfix) with ESMTPSA id 4TYHn85xP7zyRX; Mon, 12 Feb 2024 09:34:20 +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, mark.rutland@arm.com, ryabinin.a.a@gmail.com, vincenzo.frascino@arm.com Subject: [PATCH v3] kasan: add atomic tests Date: Mon, 12 Feb 2024 08:33:42 +0000 Message-Id: <20240212083342.3075850-1-paul.heidekrueger@tum.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240211091720.145235-1-paul.heidekrueger@tum.de> References: <20240211091720.145235-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: 1790681490797302021 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 Reviewed-by: Andrey Konovalov Signed-off-by: Paul Heidekrüger --- Changes PATCH v2 -> PATCH v3: * Fix the wrong variable being used when checking a2 after allocation * Add Andrey's reviewed-by tag 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..7f0f87a2c3c4 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, a2); + + /* 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),