From patchwork Fri Feb 2 11:32:59 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: 195819 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp363897dyc; Fri, 2 Feb 2024 03:36:17 -0800 (PST) X-Google-Smtp-Source: AGHT+IHfP9eI0q6X9WzaKIW5Y4IbTJYKs+9QdS6Yy5eCzP+ZlKR6k2Zjzcp0N9Y4ay8PpZYNmNE3 X-Received: by 2002:ad4:5cc1:0:b0:68c:8b5c:9d29 with SMTP id iu1-20020ad45cc1000000b0068c8b5c9d29mr79468qvb.62.1706873777072; Fri, 02 Feb 2024 03:36:17 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706873777; cv=pass; d=google.com; s=arc-20160816; b=o2S+RNXrcbXItcqyhb4N+IwXJJH6uN7Mwe2MWWa6WtnZrpVvHY4CQiO8nKMjUze+90 Idx324PicXjjHAEZg9HNWA9j5YuO4GTLCywSJX5IQF4EwtLBXHjqkIEeb6nm53n617ek RZHkfLdpp323CPKXndWQLIUQgre+jXzimbmswXFw+gq7uKznEuDA7sdj5UW5rsLdjuYI WpStcAfNBuMyC388r4E5VAUD8N4zvbugQakf095g9D3shAEXZ9Uqxkkn9vBiUGeMCJLx prdCvbKeDlj50SZlhkUo2QXeyW2O8fdE3XxPBSFGESmRpb9sx8S+diXWehHA+Th9Ytlp 8H5A== 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=CFqy2ux5XUG9htHw0BliWENPoh369TclIQ8YDIpQUic=; fh=JpH2ouXsPUwHqOABCUusvvf81r6w6bjdVdRZhkdG8bE=; b=dBEsBQq2NZQSR9WUbRx6YFMFCyT20x1nb01zupNjaFJi/e/pBtGyCmn2jPR9dsbPL8 PKb9uhHfhLBhu8fhIcxxD2U9gm83LGrKbJlLldOnI77hx1VUNv7G/LQuhFYe5iuj2zsU 8bQpPRGuqdB2Bl/tsg4W2DTyiyRTYNfHBG8rHMKQbBsOoaJBmly6u5KEbUnkBwNZDEfQ n6RwtjWfbvJgZfUPf2jfAza2g0EICSB0lfoZyFpuWCd7uEwWmmTK9VN+APzEoNXu6Qm+ tC0Q9mOeSyGUaola2i+RXpV73HDiqm8y9sGRDpxJRE+lQcncwWMSb2qBTkC4Wa96MCBI zhcA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@tum.de header.s=tu-postout21 header.b="LH/t7DFy"; 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-49760-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49760-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=tum.de X-Forwarded-Encrypted: i=1; AJvYcCWMnywlF0qmyGCdJGeVcRcKIkvHgB9+Xko8sWzfKSUcrLpazGbwEahx84UTRKvg9kF4+7UI8P0gIkja9w+J5Es2al9dNg== Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id c14-20020a0ceb4e000000b006850fa27ff0si1836573qvq.244.2024.02.02.03.36.16 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Feb 2024 03:36:17 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49760-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@tum.de header.s=tu-postout21 header.b="LH/t7DFy"; 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-49760-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49760-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 ny.mirrors.kernel.org (Postfix) with ESMTPS id 997261C24D8B for ; Fri, 2 Feb 2024 11:35:27 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 60A8077620; Fri, 2 Feb 2024 11:33:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=tum.de header.i=@tum.de header.b="LH/t7DFy" 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 ECF6179DB2 for ; Fri, 2 Feb 2024 11:33:34 +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=1706873618; cv=none; b=MHLVfXazxReWmYfrJ1uGLbwzMqTyahlrDkxfhzkAZKpL/TTmQGEEzwbb8xBj7+TdnKmKA9UtVa7XlpR0OdV1rnBUNagh2sHEXG19rMOSkvhtZU0gwlrsepjOzvIlLAX9szTURlguL9/zSZOXcrF6gxk1IPEykoSRHNUjUrjj9Oc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706873618; c=relaxed/simple; bh=xKnSOdlNYW4s3a0bxtmbV1BvcFyip1inL+1UdO0HLPQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=lV+5r9zvO7xAPd3TuvGQ9/GiYhjCctg22s9NvJiUw3KM0t5u4TAa8elq19PP7Z2e5mK/rM50SePUZgxKiaD6xDbgOV1aLeAdj5l6RwNrG/b3+Gzm8xR510cXKuyHZ7K4tffkafhklpQ7t+66LxkOrZ3F+oDsnbZ/LVc4NRhocuU= 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=LH/t7DFy; 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 4TRDDW1kRjzyYQ; Fri, 2 Feb 2024 12:33:31 +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= 1706873609; bh=xKnSOdlNYW4s3a0bxtmbV1BvcFyip1inL+1UdO0HLPQ=; b=L H/t7DFyFL199T3kRDqDacsJpvv5q+9Nd8sxepGlLgm8HLKMT2aPoirqcApySJpuu OpIeuNdMH5sbQTr3XqzoRu6T/oKVD63gYPZMDpKQAJRXpuAxfP7+Z9BAmUF1IQFP HRHeifkXtlBSTE5t5UnEdbU//s0+vZ5D3ZcIybdFPaK2pZZjYmB99d0nAVFISAe+ oeOhP/wkQtyGFHOHiTkmjhgb0g3GLhq5gFKnHV/VhLCZZyoQn0WeEIYmxXq8iKsO qY49jhR7PfXmi6TUE9N2w8c2f7b76ar3NOpfL0cbrlsfGdwQXV3prwRoymAJYa+4 +EezUplbVGYU62BcXvBCQ== X-Virus-Scanned: by amavisd-new at lrz.de in lxmhs52.srv.lrz.de X-Spam-Flag: NO X-Spam-Score: -2.881 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 1ecYqzhVSBKZ; Fri, 2 Feb 2024 12:33:29 +0100 (CET) Received: from sienna.fritz.box (ppp-93-104-92-119.dynamic.mnet-online.de [93.104.92.119]) (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 4TRDDQ4z8xzyYX; Fri, 2 Feb 2024 12:33:26 +0100 (CET) From: =?utf-8?q?Paul_Heidekr=C3=BCger?= To: elver@google.com Cc: akpm@linux-foundation.org, andreyknvl@gmail.com, dvyukov@google.com, glider@google.com, kasan-dev@googlegroups.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org, paul.heidekrueger@tum.de, ryabinin.a.a@gmail.com, vincenzo.frascino@arm.com Subject: [PATCH] kasan: add atomic tests Date: Fri, 2 Feb 2024 11:32:59 +0000 Message-Id: <20240202113259.3045705-1-paul.heidekrueger@tum.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: References: 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: 1789786877283554661 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 Signed-off-by: Paul Heidekrüger Reviewed-by: Marco Elver Tested-by: Marco Elver Acked-by: Mark Rutland --- 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..4ef2280c322c 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 = (int *)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(int), 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),