From patchwork Mon May 5 15:15:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 888363 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 D77DF18132A; Mon, 5 May 2025 15:16:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458175; cv=none; b=ot5lEh1VD1JMd9858fLgvxtOgjNKFuV75HWkBP2ENKDwMr8DL0fXIcPN4ZKpYPkFyhtzAFAwIKAN9WoN/h3XY42cmBhSOnVAb1rDN9bCVO1UhrJLncK4szdSf1x5oMhAyQwKedCmgzOhz+W8gBhy0R4zQrE7XPJkpkzL/qgvfvY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458175; c=relaxed/simple; bh=SauQZZ+p7GlA36fyOdZJXpYGuTwHXfA3XWuABlOBRtw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UBaLqFoqRc5TQYc4jlJcgc1ig+PIoKhTpUqGLGeBDq39XxwxNSegmk1zidTGhxagl0BnYs3tGmZpJMfgUCHrz38McV7iOaf1SQyWPAHkqOMzepVFtc0UgP5XVQBdMBxbf53UJ+B/pF0a8UJ8vDLHButzMEWY+Kti0PU2C7v+64M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=ZsMiutJX; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=jA/Q+TQQ; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="ZsMiutJX"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="jA/Q+TQQ" From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1746458171; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4GB6hgAcmMAaVeNITwuKQN5e4eTVKo/B0NCsDcGXC+c=; b=ZsMiutJXGVINWTebeTNdfTtbFEO9nxf+xpnIh+ZADU/httaluDH7iaKDCd7AHV6Cynouyu BVp+MYPtE29J7gd6jgVWFRNLPS+BJdE8qAGK8ZEH3DNyW4/hN1bgAtecW/qp4u1ugBtP/q oxCfJlA8CgOHPz7IDzuO+GYP49/IHwqWWN5N91YLzIItdMiWCKZhWAJ54V4FnLQRCejh0q uBYFfkEJ5xliXBgxSerdLmxUZJ8l1qJdiKaKXARcgXZ7CXAEpIuyTWrTYDK213BWx+5yb+ W9Fi9WYtP4uhp5I49lLWKCI+FDD5ciWR1Wnecalqmpw+BzKICpZ39+iDJ/njug== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1746458171; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4GB6hgAcmMAaVeNITwuKQN5e4eTVKo/B0NCsDcGXC+c=; b=jA/Q+TQQMRrRFk0cMOYcd+PJKZlTrfV3Y2n3b2B0IXhvbIHxVT6IBzvxOhQOQlWAiCNolx Rp4kTyy6c92tNSDg== Date: Mon, 05 May 2025 17:15:19 +0200 Subject: [PATCH v4 01/14] selftests: harness: Add kselftest harness selftest Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250505-nolibc-kselftest-harness-v4-1-ee4dd5257135@linutronix.de> References: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> In-Reply-To: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> To: Shuah Khan , Shuah Khan , Willy Tarreau , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Kees Cook Cc: Andy Lutomirski , Will Drewry , Mark Brown , Muhammad Usama Anjum , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, =?utf-8?q?T?= =?utf-8?q?homas_Wei=C3=9Fschuh?= X-Developer-Signature: v=1; a=ed25519-sha256; t=1746458170; l=9202; i=thomas.weissschuh@linutronix.de; s=20240209; h=from:subject:message-id; bh=SauQZZ+p7GlA36fyOdZJXpYGuTwHXfA3XWuABlOBRtw=; b=2itMI4KC3KxWBg/aaOakkTTIGeHWCpravNnn0CLySf51UCAGhgSDGSNHcj1lCWaxvR40KnTuk okCohtBcXXYDL/kYgUckKvVPt+rhFDddzOgMeDbdZjA8wOFBedNyPVc X-Developer-Key: i=thomas.weissschuh@linutronix.de; a=ed25519; pk=pfvxvpFUDJV2h2nY0FidLUml22uGLSjByFbM6aqQQws= Add a selftest for the kselftest harness itself so any changes can be validated. Signed-off-by: Thomas Weißschuh Reviewed-by: Muhammad Usama Anjum Acked-by: Shuah Khan --- MAINTAINERS | 1 + tools/testing/selftests/Makefile | 1 + .../testing/selftests/kselftest_harness/.gitignore | 2 + tools/testing/selftests/kselftest_harness/Makefile | 7 ++ .../selftests/kselftest_harness/harness-selftest.c | 138 +++++++++++++++++++++ .../kselftest_harness/harness-selftest.expected | 64 ++++++++++ .../kselftest_harness/harness-selftest.sh | 13 ++ 7 files changed, 226 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 96b82704950184bd71623ff41fc4df31e4c7fe87..9d5278df33c8b63b3b08155991b789b3a998f80e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -21742,6 +21742,7 @@ F: include/linux/seccomp.h F: include/uapi/linux/seccomp.h F: kernel/seccomp.c F: tools/testing/selftests/kselftest_harness.h +F: tools/testing/selftests/kselftest_harness/ F: tools/testing/selftests/seccomp/* K: \bsecure_computing K: \bTIF_SECCOMP\b diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index c77c8c8e3d9bdd8047c9cb7722c3830447e504e5..27592909a5969da009d71be6c8330fe6779e7354 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -48,6 +48,7 @@ TARGETS += ipc TARGETS += ir TARGETS += kcmp TARGETS += kexec +TARGETS += kselftest_harness TARGETS += kvm TARGETS += landlock TARGETS += lib diff --git a/tools/testing/selftests/kselftest_harness/.gitignore b/tools/testing/selftests/kselftest_harness/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e4e476a333c912602161448bc61787732a6fa2e2 --- /dev/null +++ b/tools/testing/selftests/kselftest_harness/.gitignore @@ -0,0 +1,2 @@ +/harness-selftest +/harness-selftest.seen diff --git a/tools/testing/selftests/kselftest_harness/Makefile b/tools/testing/selftests/kselftest_harness/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..0617535a6ce424ff977e033b0a3a01c3117aefcf --- /dev/null +++ b/tools/testing/selftests/kselftest_harness/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 + +TEST_GEN_PROGS_EXTENDED := harness-selftest +TEST_PROGS := harness-selftest.sh +EXTRA_CLEAN := harness-selftest.seen + +include ../lib.mk diff --git a/tools/testing/selftests/kselftest_harness/harness-selftest.c b/tools/testing/selftests/kselftest_harness/harness-selftest.c new file mode 100644 index 0000000000000000000000000000000000000000..a0e3e89ae291f8d9f4f2ab9746a838fd1bfaf6c1 --- /dev/null +++ b/tools/testing/selftests/kselftest_harness/harness-selftest.c @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include + +#ifndef NOLIBC +#include +#include +#endif + +/* Avoid any inconsistencies */ +#define TH_LOG_STREAM stdout + +#include "../kselftest_harness.h" + +static void test_helper(struct __test_metadata *_metadata) +{ + ASSERT_EQ(0, 0); +} + +TEST(standalone_pass) { + TH_LOG("before"); + ASSERT_EQ(0, 0); + EXPECT_EQ(0, 0); + test_helper(_metadata); + TH_LOG("after"); +} + +TEST(standalone_fail) { + TH_LOG("before"); + EXPECT_EQ(0, 0); + EXPECT_EQ(0, 1); + ASSERT_EQ(0, 1); + TH_LOG("after"); +} + +TEST_SIGNAL(signal_pass, SIGUSR1) { + TH_LOG("before"); + ASSERT_EQ(0, 0); + TH_LOG("after"); + kill(getpid(), SIGUSR1); +} + +TEST_SIGNAL(signal_fail, SIGUSR1) { + TH_LOG("before"); + ASSERT_EQ(0, 1); + TH_LOG("after"); + kill(getpid(), SIGUSR1); +} + +FIXTURE(fixture) { + pid_t testpid; +}; + +FIXTURE_SETUP(fixture) { + TH_LOG("setup"); + self->testpid = getpid(); +} + +FIXTURE_TEARDOWN(fixture) { + TH_LOG("teardown same-process=%d", self->testpid == getpid()); +} + +TEST_F(fixture, pass) { + TH_LOG("before"); + ASSERT_EQ(0, 0); + test_helper(_metadata); + standalone_pass(_metadata); + TH_LOG("after"); +} + +TEST_F(fixture, fail) { + TH_LOG("before"); + ASSERT_EQ(0, 1); + fixture_pass(_metadata, self, variant); + TH_LOG("after"); +} + +TEST_F_TIMEOUT(fixture, timeout, 1) { + TH_LOG("before"); + sleep(2); + TH_LOG("after"); +} + +FIXTURE(fixture_parent) { + pid_t testpid; +}; + +FIXTURE_SETUP(fixture_parent) { + TH_LOG("setup"); + self->testpid = getpid(); +} + +FIXTURE_TEARDOWN_PARENT(fixture_parent) { + TH_LOG("teardown same-process=%d", self->testpid == getpid()); +} + +TEST_F(fixture_parent, pass) { + TH_LOG("before"); + ASSERT_EQ(0, 0); + TH_LOG("after"); +} + +FIXTURE(fixture_setup_failure) { + pid_t testpid; +}; + +FIXTURE_SETUP(fixture_setup_failure) { + TH_LOG("setup"); + self->testpid = getpid(); + ASSERT_EQ(0, 1); +} + +FIXTURE_TEARDOWN(fixture_setup_failure) { + TH_LOG("teardown same-process=%d", self->testpid == getpid()); +} + +TEST_F(fixture_setup_failure, pass) { + TH_LOG("before"); + ASSERT_EQ(0, 0); + TH_LOG("after"); +} + +int main(int argc, char **argv) +{ + /* + * The harness uses abort() to signal assertion failures, which triggers coredumps. + * This may be useful to debug real failures but not for this selftest, disable them. + */ + struct rlimit rlimit = { + .rlim_cur = 0, + .rlim_max = 0, + }; + + prctl(PR_SET_DUMPABLE, 0, 0, 0, 0); + setrlimit(RLIMIT_CORE, &rlimit); + + return test_harness_run(argc, argv); +} diff --git a/tools/testing/selftests/kselftest_harness/harness-selftest.expected b/tools/testing/selftests/kselftest_harness/harness-selftest.expected new file mode 100644 index 0000000000000000000000000000000000000000..61ba88d233f91d21b1e26a427c04092b8c37747d --- /dev/null +++ b/tools/testing/selftests/kselftest_harness/harness-selftest.expected @@ -0,0 +1,64 @@ +TAP version 13 +1..9 +# Starting 9 tests from 4 test cases. +# RUN global.standalone_pass ... +# harness-selftest.c:21:standalone_pass:before +# harness-selftest.c:25:standalone_pass:after +# OK global.standalone_pass +ok 1 global.standalone_pass +# RUN global.standalone_fail ... +# harness-selftest.c:29:standalone_fail:before +# harness-selftest.c:31:standalone_fail:Expected 0 (0) == 1 (1) +# harness-selftest.c:32:standalone_fail:Expected 0 (0) == 1 (1) +# standalone_fail: Test terminated by assertion +# FAIL global.standalone_fail +not ok 2 global.standalone_fail +# RUN global.signal_pass ... +# harness-selftest.c:37:signal_pass:before +# harness-selftest.c:39:signal_pass:after +# OK global.signal_pass +ok 3 global.signal_pass +# RUN global.signal_fail ... +# harness-selftest.c:44:signal_fail:before +# harness-selftest.c:45:signal_fail:Expected 0 (0) == 1 (1) +# signal_fail: Test terminated by assertion +# FAIL global.signal_fail +not ok 4 global.signal_fail +# RUN fixture.pass ... +# harness-selftest.c:55:pass:setup +# harness-selftest.c:64:pass:before +# harness-selftest.c:21:pass:before +# harness-selftest.c:25:pass:after +# harness-selftest.c:68:pass:after +# harness-selftest.c:60:pass:teardown same-process=1 +# OK fixture.pass +ok 5 fixture.pass +# RUN fixture.fail ... +# harness-selftest.c:55:fail:setup +# harness-selftest.c:72:fail:before +# harness-selftest.c:73:fail:Expected 0 (0) == 1 (1) +# harness-selftest.c:60:fail:teardown same-process=1 +# fail: Test terminated by assertion +# FAIL fixture.fail +not ok 6 fixture.fail +# RUN fixture.timeout ... +# harness-selftest.c:55:timeout:setup +# harness-selftest.c:79:timeout:before +# timeout: Test terminated by timeout +# FAIL fixture.timeout +not ok 7 fixture.timeout +# RUN fixture_parent.pass ... +# harness-selftest.c:89:pass:setup +# harness-selftest.c:98:pass:before +# harness-selftest.c:100:pass:after +# harness-selftest.c:94:pass:teardown same-process=0 +# OK fixture_parent.pass +ok 8 fixture_parent.pass +# RUN fixture_setup_failure.pass ... +# harness-selftest.c:108:pass:setup +# harness-selftest.c:110:pass:Expected 0 (0) == 1 (1) +# pass: Test terminated by assertion +# FAIL fixture_setup_failure.pass +not ok 9 fixture_setup_failure.pass +# FAILED: 4 / 9 tests passed. +# Totals: pass:4 fail:5 xfail:0 xpass:0 skip:0 error:0 diff --git a/tools/testing/selftests/kselftest_harness/harness-selftest.sh b/tools/testing/selftests/kselftest_harness/harness-selftest.sh new file mode 100755 index 0000000000000000000000000000000000000000..fe72d16370fe5bc16706289ff4e1ff44db180017 --- /dev/null +++ b/tools/testing/selftests/kselftest_harness/harness-selftest.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# +# Selftest for kselftest_harness.h +# + +set -e + +DIR="$(dirname $(readlink -f "$0"))" + +"$DIR"/harness-selftest > harness-selftest.seen || true + +diff -u "$DIR"/harness-selftest.expected harness-selftest.seen From patchwork Mon May 5 15:15:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 887660 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 D784C1F540F; Mon, 5 May 2025 15:16:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458175; cv=none; b=fOV3N4USwQNWMhW2rvL4bVL2UA+e96qN3sDM8qXEBTGSrVzZJd1+/oTwZdv2KHvGI8A50TgdXBr5m+O8t+o4ktYSR+wUY8Xag6XHiFyO6aIIOGNWtXKYzOtQtV/nI3MJ709wT43/8Ht5zGwjEjl8YSAHjcCZnNYRPqEYBxdxvHY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458175; c=relaxed/simple; bh=dBJ+kjSojaZBWuRgrqVpCDJvef04qbVQ19xoJvSt7WM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NAXD7Kf3tfisrNCDHI93Fhkk2/gk+JQ4vMDDbgzI1WSb7Q045lDlaYbStBxinxEfnTGNYNE8zJ9YSLguaBgli/T2QDteOqLMYQzBEKdBNtYcCwNcecnJjP5PE8UDi3oACD2oec0rvI9YiQtCgd6nJBrxEe04gQyeh8LxMlV9dZc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=2wlMvBYe; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=RMmOiMna; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="2wlMvBYe"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="RMmOiMna" From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1746458172; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rv8ssy8vQy9aS7DK21TTvdS2wQYdRPZo3tH/3whiiF4=; b=2wlMvBYeYqIOEwa34x4yf9wV8iKNsJ1M8ixbmGquK79KBVLimdSQFca/60ojgJhXg9Ik0e 25bTQe/9ZKhhPIOmkV5h2IZH+Y5KkcRbRdvO5wtjTeNp9Q0B66ArUPEDhqUUiO+WvAiZO+ BOaCVN8svImfh3yy3Wcd3V7Ebjkhj3PF/KKpNUOQW/wk+kPe8BjZabSVTl25Ky/2Y/PTU5 Som8C21WqEvwIZP10iFPhEqsNPKMqAs9H0kgsN1lL62F+JgjUfXkpL/oqP9AlHNn2gnTl5 CFkXwNU1/uti0VpZL4IfiKIaLyZcNLmY39M7k9cKqmTbEvxi/7DmfXOBqHdRnQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1746458172; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rv8ssy8vQy9aS7DK21TTvdS2wQYdRPZo3tH/3whiiF4=; b=RMmOiMnaRTgZP3GzPepl5QWLJILaSMuC54tVTAXFZuMR0DLZfQJnnc99K8lrxy9jDy0Eob xFHA+yYc7nHIQBBw== Date: Mon, 05 May 2025 17:15:20 +0200 Subject: [PATCH v4 02/14] selftests: harness: Use C89 comment style Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250505-nolibc-kselftest-harness-v4-2-ee4dd5257135@linutronix.de> References: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> In-Reply-To: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> To: Shuah Khan , Shuah Khan , Willy Tarreau , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Kees Cook Cc: Andy Lutomirski , Will Drewry , Mark Brown , Muhammad Usama Anjum , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, =?utf-8?q?T?= =?utf-8?q?homas_Wei=C3=9Fschuh?= X-Developer-Signature: v=1; a=ed25519-sha256; t=1746458170; l=892; i=thomas.weissschuh@linutronix.de; s=20240209; h=from:subject:message-id; bh=dBJ+kjSojaZBWuRgrqVpCDJvef04qbVQ19xoJvSt7WM=; b=xoFfdCynlPDtlHtZ7abHaSUqOSdrjj1cHd5jzBh8LoHcXX5oHYMlaWZHL3B3DPYTwPVoy0Lvc P4dS44uJrBLCVjBKm+s12+0qFq4PKYYMT8jarHDqnV830IqI3++b3y3 X-Developer-Key: i=thomas.weissschuh@linutronix.de; a=ed25519; pk=pfvxvpFUDJV2h2nY0FidLUml22uGLSjByFbM6aqQQws= All comments in this file use C89 comment style. Except for this one. Change it to get one step closer to C89 compatibility. Signed-off-by: Thomas Weißschuh Acked-by: Shuah Khan --- tools/testing/selftests/kselftest_harness.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h index 666c9fde76da9d25fe6e248a7f2143c113473fe1..bac4327775ea65dbe977e9b22ee548bedcbd33ff 100644 --- a/tools/testing/selftests/kselftest_harness.h +++ b/tools/testing/selftests/kselftest_harness.h @@ -983,7 +983,7 @@ static void __timeout_handler(int sig, siginfo_t *info, void *ucontext) } t->timed_out = true; - // signal process group + /* signal process group */ kill(-(t->pid), SIGKILL); } From patchwork Mon May 5 15:15:21 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 887659 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 E0CF92512E3; Mon, 5 May 2025 15:16:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458176; cv=none; b=clV2gBb0o6xRqMMXlq8ieVKuKHaljThw2qrQR+NLE2DpiSgalKg+XZ2HntlBdeQDkiwkfydS4IS8YhY4socXZL+U1JCv5t2kCysqqg/w+ovQ2GIrNZPk6Xi67vZiov0+0bnZilP9tHSc3V4O8g2adpCciaykbj7ZFu0/54jUE4o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458176; c=relaxed/simple; bh=yqkC7D613B/dIafgI34BREpd1HQGZ/eX+hozBTbheVU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=c4nzNlFCUJlnifAHVtXIlX6ggev2wCRhgWoGs5KQCv+h/8nJ3hOf8HuqSESmEfQF8X6w4WySadzl3O93Ut14xRpiF7OgxrX3jM701yZ41WvK3yA0irim35Z059/b9+8bIFeLV7aU3TlhmoklxAS0J4RSOk3RRGN0Jy5/I0pgXuA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Fn59vU+7; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=BbjHCEaa; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Fn59vU+7"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="BbjHCEaa" From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1746458172; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=//BGu/k3hlFFdQ3pWCz2mCX1lpc3aAigLFz9qVSnyGw=; b=Fn59vU+7fZBvcMMi59lVzisP7K+Te/kiy2lzjUfAllZ+hU5rbPKpv5v7N+0A65VrecNghh Bc6cIF5Phh5fWrF30HNWfsaf9r7LC1aQVD9ElhJi9/EGehqVVyboHFsaYZiR9mX0onwPZw 7zdY7aVgvWB3RUX1TLuKcxTPsrTs48xN/Sv0yx2vrbAWAb1ZEkKiVrdz3Q2YUmh3jcki15 4977ygfbJEHkTk470/yCgRh1LAmZW9PowXGi6smPmaWbY/OM4i0rUQY/SLp72+UUgvY+y+ K+fEp+ORlcbosQcSD6w03EeJ/3fF2l+WFj+6jXe86F6mX79NpEkEud9JZan1gg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1746458172; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=//BGu/k3hlFFdQ3pWCz2mCX1lpc3aAigLFz9qVSnyGw=; b=BbjHCEaaplrMokuA4qUSQVvjm+nm3gwqtZnhlnn7fQQkxLSLqi31sq8Mfkx2it1wWIb/c8 pNcWBoy5jJMSXAAw== Date: Mon, 05 May 2025 17:15:21 +0200 Subject: [PATCH v4 03/14] selftests: harness: Ignore unused variant argument warning Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250505-nolibc-kselftest-harness-v4-3-ee4dd5257135@linutronix.de> References: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> In-Reply-To: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> To: Shuah Khan , Shuah Khan , Willy Tarreau , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Kees Cook Cc: Andy Lutomirski , Will Drewry , Mark Brown , Muhammad Usama Anjum , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, =?utf-8?q?T?= =?utf-8?q?homas_Wei=C3=9Fschuh?= X-Developer-Signature: v=1; a=ed25519-sha256; t=1746458170; l=1751; i=thomas.weissschuh@linutronix.de; s=20240209; h=from:subject:message-id; bh=yqkC7D613B/dIafgI34BREpd1HQGZ/eX+hozBTbheVU=; b=LDKfqsixK1+BJpdn4ujnlFThBPlGBZsrApu61b5YAp0J6CbMwCAPuO3mCGDjEKML58DaOnS6b 8dVuCGrAeThD+n2dAVjDut1eIhalhWDtWfEuU4unOfKrHOUbUEWGVkA X-Developer-Key: i=thomas.weissschuh@linutronix.de; a=ed25519; pk=pfvxvpFUDJV2h2nY0FidLUml22uGLSjByFbM6aqQQws= For tests without fixtures the variant argument is unused. This is intentional, prevent to compiler from complaining. Example warning: harness-selftest.c: In function 'wrapper_standalone_pass': ../kselftest_harness.h:181:52: error: unused parameter 'variant' [-Werror=unused-parameter] 181 | struct __fixture_variant_metadata *variant) \ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~ ../kselftest_harness.h:156:25: note: in expansion of macro '__TEST_IMPL' 156 | #define TEST(test_name) __TEST_IMPL(test_name, -1) | ^~~~~~~~~~~ harness-selftest.c:15:1: note: in expansion of macro 'TEST' 15 | TEST(standalone_pass) { | ^~~~ Signed-off-by: Thomas Weißschuh Reviewed-by: Muhammad Usama Anjum Acked-by: Shuah Khan --- tools/testing/selftests/kselftest_harness.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h index bac4327775ea65dbe977e9b22ee548bedcbd33ff..2b350ed60b2bf1cbede8e3a9b4ac5fe716900144 100644 --- a/tools/testing/selftests/kselftest_harness.h +++ b/tools/testing/selftests/kselftest_harness.h @@ -174,7 +174,7 @@ static void test_name(struct __test_metadata *_metadata); \ static inline void wrapper_##test_name( \ struct __test_metadata *_metadata, \ - struct __fixture_variant_metadata *variant) \ + struct __fixture_variant_metadata __attribute__((unused)) *variant) \ { \ _metadata->setup_completed = true; \ if (setjmp(_metadata->env) == 0) \ From patchwork Mon May 5 15:15:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 888362 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 E0D6925A337; Mon, 5 May 2025 15:16:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458176; cv=none; b=XQEuXVK7VB4JNbVhnbPqL3ZeKAKKyArKjbtoV3okqpxWMx5GyvDmDbzHwmp1qCrQ4EcFBoUkGQtmV/cJV1/+CUy1DwA12tQWS2w8u5/FVgfFHPubkhxWJAXaNekdpV2MTNdOQu4LHU4VncMqh2kQlOyEVUCl28dC0ObSHyQHpyc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458176; c=relaxed/simple; bh=IgAv7u92b6nUp1dIoS5UQU29guGSB5ifPJxUKWCgMlc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Y90s5I21DxXKVtB6szquxRGiHVoxkd+5mYjm7LZkBt4895VhMt+fmAvhbkv/bX7foWfW1SAoflYJQxiZ9HW9A5lkOvvvJmdMkmvFm6JVwZ/OUs81+ZK0+2tlMfNXZ+Wm51PcWDGp0F/tcPVr6eKgWudHe1xXThxDClgKuuv/mX8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Guh4Kkmx; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=MIUSFRMT; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Guh4Kkmx"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="MIUSFRMT" From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1746458173; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cmAYGefQspjxqgFvHq08P1lvZ4L89NIXaIMkIe2Mb+Q=; b=Guh4KkmxF/IzNHCBFacQLH/PnGVpoG7mhuO+wvkhoBlM6+dWgnEc4UBRaj15zrTnRqJOar V1R3JZEV2r1phHnqHls0E86QFhgrFboxBhjC6Rj0/PuM0x8uNym84ZK08mIGogceiV8QMK 256SAmW8Lv9OwlhWU0wkfyekbgmKGRO9QOPmrTuJIfXcHHYADL6N4ZWjOwmUK9FhNdAWEq VtudER7pcyeRKNlh5YZJgpxm3pW8mOYhku3SXDJNpD76nvkWUZ1DB+jSaloMtoJp143ITX N6bEoX63XPZ8kD/8w3yhwZ/OtlK1ArPp6+h7RER0DM96W9gCx/Qei8LSLMtLhA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1746458173; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cmAYGefQspjxqgFvHq08P1lvZ4L89NIXaIMkIe2Mb+Q=; b=MIUSFRMTNCt79e3dzLnbyGOa3BrDUElDwSNp/7jj1/NamQdyqbw9KTq8Ugv60UHs2xw42k k4QpHbzkUvW/2EBg== Date: Mon, 05 May 2025 17:15:22 +0200 Subject: [PATCH v4 04/14] selftests: harness: Mark functions without prototypes static Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250505-nolibc-kselftest-harness-v4-4-ee4dd5257135@linutronix.de> References: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> In-Reply-To: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> To: Shuah Khan , Shuah Khan , Willy Tarreau , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Kees Cook Cc: Andy Lutomirski , Will Drewry , Mark Brown , Muhammad Usama Anjum , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, =?utf-8?q?T?= =?utf-8?q?homas_Wei=C3=9Fschuh?= X-Developer-Signature: v=1; a=ed25519-sha256; t=1746458170; l=2358; i=thomas.weissschuh@linutronix.de; s=20240209; h=from:subject:message-id; bh=IgAv7u92b6nUp1dIoS5UQU29guGSB5ifPJxUKWCgMlc=; b=/mmVq7ew3UzSTb7vLgQwpi7UV1YdurIkN57ULYLVPsnGyTisUzcpAHMzctOdnY5mShak322Sm YN+LqwkcJgLBQ+VOfa1YdZHSvkFUALj2DfD/4MN2+xdhkZyueW5O1QQ X-Developer-Key: i=thomas.weissschuh@linutronix.de; a=ed25519; pk=pfvxvpFUDJV2h2nY0FidLUml22uGLSjByFbM6aqQQws= With -Wmissing-prototypes the compiler will warn about non-static functions which don't have a prototype defined. As they are not used from a different compilation unit they don't need to be defined globally. Avoid the issue by marking the functions static. Signed-off-by: Thomas Weißschuh Reviewed-by: Muhammad Usama Anjum Acked-by: Shuah Khan --- tools/testing/selftests/kselftest_harness.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h index 2b350ed60b2bf1cbede8e3a9b4ac5fe716900144..5822bc0b86a3c623fd34830fb8b541b27672a00b 100644 --- a/tools/testing/selftests/kselftest_harness.h +++ b/tools/testing/selftests/kselftest_harness.h @@ -258,7 +258,7 @@ * A bare "return;" statement may be used to return early. */ #define FIXTURE_SETUP(fixture_name) \ - void fixture_name##_setup( \ + static void fixture_name##_setup( \ struct __test_metadata __attribute__((unused)) *_metadata, \ FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \ const FIXTURE_VARIANT(fixture_name) \ @@ -307,7 +307,7 @@ __FIXTURE_TEARDOWN(fixture_name) #define __FIXTURE_TEARDOWN(fixture_name) \ - void fixture_name##_teardown( \ + static void fixture_name##_teardown( \ struct __test_metadata __attribute__((unused)) *_metadata, \ FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \ const FIXTURE_VARIANT(fixture_name) \ @@ -987,7 +987,7 @@ static void __timeout_handler(int sig, siginfo_t *info, void *ucontext) kill(-(t->pid), SIGKILL); } -void __wait_for_test(struct __test_metadata *t) +static void __wait_for_test(struct __test_metadata *t) { struct sigaction action = { .sa_sigaction = __timeout_handler, @@ -1205,9 +1205,9 @@ static bool test_enabled(int argc, char **argv, return !has_positive; } -void __run_test(struct __fixture_metadata *f, - struct __fixture_variant_metadata *variant, - struct __test_metadata *t) +static void __run_test(struct __fixture_metadata *f, + struct __fixture_variant_metadata *variant, + struct __test_metadata *t) { struct __test_xfail *xfail; char test_name[1024]; From patchwork Mon May 5 15:15:23 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 887658 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 E3E5A25E450; Mon, 5 May 2025 15:16:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458178; cv=none; b=rj5yLqYEBGfjJ66pgKTHoyXXfubjnDdKoTDxzCR8COtj5JRzlErchUiu1VoIh2ic6/VDC47z1a4gxiPDP+b/vdxpmzViVrGg4zu9KPk+vYhvNz6hvoz6RMzVZvH4NGvYqw72YCRw6EPpCLT9UhauZicG47xlgr0tyliGgKS4kNo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458178; c=relaxed/simple; bh=KhW3lWKpfo/1/0mm9HHAp3CarDorGDqS8DcPzFcBpDw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mTjhfSezzvbRgne8Fjg80CSAuBVSIG9is0p+c8IRFVpLdozraFexw/LOtD4COnOIemR6jZyIUNk1JWC8AQqP3t9LXk6BNvdBM//GJZB4Xa4qB/Nnjpx72EXiqRKcKfusrdZTjHG7Kmstyn4F9T88f38RdsIf3R1QB+CB9rtlcsg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=eIZCcOfb; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Y93qr98Z; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="eIZCcOfb"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Y93qr98Z" From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1746458173; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=KJJ0rdSIAhSeUiLVcQzDlHj6elSkp5s1UP0V2E8oyAc=; b=eIZCcOfbzxUDB9LI+h46ceDGIqENozoalQOcGcO1bjmtbniyT81nImtjwPrsqxAv2P8bNZ lRFrFb9D7DCUMPDrqAXniGb0S888wtjf+Mqr7QD1Av5fCyo+AB5YuJ360V98gCn4N32jMp QU2pgdUR2ighWIYbcOcKw3XkXENO/A7QW1TL2TuF/+IN6LTddNQQ/98DYAuY1sL7lkq5uJ IbbtrBuPCVOjZJNWJnopQ5sYzDG65jSpMlCUEOucTr3So0sRGvQ1KSqbm+YtESnQQkZ7A0 HwhZclA757WO8idCXap98HH0pCtLz/ONERIyYmm7S5rpy2IOB20gBe8FFALIWQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1746458173; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=KJJ0rdSIAhSeUiLVcQzDlHj6elSkp5s1UP0V2E8oyAc=; b=Y93qr98Z3FeCXO6OSA/VOsIAkwRf4UiOSe9399hG6NAM9qLzK7DLHltNVEYUvbX8xY1ebr lkdLjzYF9nP4PRDg== Date: Mon, 05 May 2025 17:15:23 +0200 Subject: [PATCH v4 05/14] selftests: harness: Remove inline qualifier for wrappers Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250505-nolibc-kselftest-harness-v4-5-ee4dd5257135@linutronix.de> References: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> In-Reply-To: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> To: Shuah Khan , Shuah Khan , Willy Tarreau , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Kees Cook Cc: Andy Lutomirski , Will Drewry , Mark Brown , Muhammad Usama Anjum , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, =?utf-8?q?T?= =?utf-8?q?homas_Wei=C3=9Fschuh?= X-Developer-Signature: v=1; a=ed25519-sha256; t=1746458170; l=1532; i=thomas.weissschuh@linutronix.de; s=20240209; h=from:subject:message-id; bh=KhW3lWKpfo/1/0mm9HHAp3CarDorGDqS8DcPzFcBpDw=; b=cLNwrtp10OcEYLKPFfDyYrwsXW80rM3TTKW0WWAPuW3YR0Ymas2yT9wh9Yx5LvOrCpjhU4OOj JLepqH/lF4tAL/D+f3WVOb+tfC6ZrsUG4gx9g0B3DmkrEzSM5fV7x6X X-Developer-Key: i=thomas.weissschuh@linutronix.de; a=ed25519; pk=pfvxvpFUDJV2h2nY0FidLUml22uGLSjByFbM6aqQQws= The pointers to the wrappers are stored in function pointers, preventing them from actually being inlined. Remove the inline qualifier, aligning these wrappers with the other functions defined through macros. Signed-off-by: Thomas Weißschuh Reviewed-by: Muhammad Usama Anjum Acked-by: Shuah Khan --- tools/testing/selftests/kselftest_harness.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h index 5822bc0b86a3c623fd34830fb8b541b27672a00b..222a4f51a8d704c41597e09a241ad887ef787139 100644 --- a/tools/testing/selftests/kselftest_harness.h +++ b/tools/testing/selftests/kselftest_harness.h @@ -172,7 +172,7 @@ #define __TEST_IMPL(test_name, _signal) \ static void test_name(struct __test_metadata *_metadata); \ - static inline void wrapper_##test_name( \ + static void wrapper_##test_name( \ struct __test_metadata *_metadata, \ struct __fixture_variant_metadata __attribute__((unused)) *variant) \ { \ @@ -401,7 +401,7 @@ struct __test_metadata *_metadata, \ FIXTURE_DATA(fixture_name) *self, \ const FIXTURE_VARIANT(fixture_name) *variant); \ - static inline void wrapper_##fixture_name##_##test_name( \ + static void wrapper_##fixture_name##_##test_name( \ struct __test_metadata *_metadata, \ struct __fixture_variant_metadata *variant) \ { \ From patchwork Mon May 5 15:15:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 887657 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 E3DC925E44D; Mon, 5 May 2025 15:16:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458178; cv=none; b=JMUgfDLKJgybS2NU5hkpT4s1cy4f+ZebQ7BYTz6A/z0XMXnaMpIoCnzyQVCaeUd5O3Ij57JOiCQ78ehV+vyKbymSuUKhanp2EUUj603hxwCn/YTFR2dkVpM4mHe8zJyqkFB4jgOWN0fSFoT/E+i2qAZ7qXa/hUvZt/MdTtlEvBI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458178; c=relaxed/simple; bh=EcoIsakzwxxtqr1oW6zN3HUyXKmCSb1/2qQPJgbXT/Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=fZK7oY1hZ3vkgj2Xv3qwejd7AvNK2qcQW8VOZagcuAiyG6zrQxecHrDtm7rqrhezKmJszuQAzMcD0AxxUgvxiHAdVxzvZPZQlW5298T2wXXJ3YTPr8jZ9y3es0m1QYMfzUXh35q4/55lKpVIuD9x2sG25xiIBFyjqPQFhkmUFtY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=SxmuHd2/; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=GOCTMlts; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="SxmuHd2/"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="GOCTMlts" From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1746458174; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=P1cMkN+PUAmfn0XV9oyq76jSFHcdM8vUJ6DsamcpS9k=; b=SxmuHd2/+07D5ffZN16mk7JuR7pMNStXhDCWra3lEtkePfwENyNraLFO5azyRz6gHnGVwH avkhYC3PfUs87qzUDR1fB1F+yICSgibF4gfCCcoVZ5neJh0Dahh/CKqd+SbyPSmv1dwfM8 ynp/W9LFYh9ih2U+6tf1HomS7FHVUIclm56HI+Bd++9GFoiMxwZe/Mauojx/jPVJLIj5oL beW/3ZT7up2wyIogSbrq2B+rVSluw7LYWiVIbv7V0Hkhw2hyiA1Xh2OSbMFvPNmde104JU RU0YsV0PQey9Sfaa95PG0qlDv03DZ7YRMj1qJmsCMTQMo6qFkCkvOOjyVj6C8A== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1746458174; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=P1cMkN+PUAmfn0XV9oyq76jSFHcdM8vUJ6DsamcpS9k=; b=GOCTMltsLcBElqLS4SXCMHSlwGg2NawBQlqFkIIHcx/jQwfuVaHLOt3v2R55nolsQhbc7D 1llFeCoE0+DkBlDg== Date: Mon, 05 May 2025 17:15:24 +0200 Subject: [PATCH v4 06/14] selftests: harness: Remove dependency on libatomic Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250505-nolibc-kselftest-harness-v4-6-ee4dd5257135@linutronix.de> References: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> In-Reply-To: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> To: Shuah Khan , Shuah Khan , Willy Tarreau , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Kees Cook Cc: Andy Lutomirski , Will Drewry , Mark Brown , Muhammad Usama Anjum , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, =?utf-8?q?T?= =?utf-8?q?homas_Wei=C3=9Fschuh?= X-Developer-Signature: v=1; a=ed25519-sha256; t=1746458170; l=1522; i=thomas.weissschuh@linutronix.de; s=20240209; h=from:subject:message-id; bh=EcoIsakzwxxtqr1oW6zN3HUyXKmCSb1/2qQPJgbXT/Y=; b=nnDlfH69jdujv+9pK3GRPpZ87cHOyzBWiMKIHYIyvkqo+nDY+ODL1PokH3xSfTMOE5KFeN47a iGuYPxZqylvA0aZ7G13whDOx57RlH8DLhSX+0cUGbvwEaTeOYWRlzoN X-Developer-Key: i=thomas.weissschuh@linutronix.de; a=ed25519; pk=pfvxvpFUDJV2h2nY0FidLUml22uGLSjByFbM6aqQQws= __sync_bool_compare_and_swap() is deprecated and requires libatomic on GCC. Compiler toolchains don't necessarily have libatomic available, so avoid this requirement by using atomics that don't need libatomic. Signed-off-by: Thomas Weißschuh Reviewed-by: Muhammad Usama Anjum Acked-by: Shuah Khan --- tools/testing/selftests/kselftest_harness.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h index 222a4f51a8d704c41597e09a241ad887ef787139..7ec4f66d0e3d7f129f6c2a45ff58310dabe5d03f 100644 --- a/tools/testing/selftests/kselftest_harness.h +++ b/tools/testing/selftests/kselftest_harness.h @@ -439,12 +439,12 @@ } \ if (child == 0) { \ if (_metadata->setup_completed && !fixture_name##_teardown_parent && \ - __sync_bool_compare_and_swap(teardown, false, true)) \ + !__atomic_test_and_set(teardown, __ATOMIC_RELAXED)) \ fixture_name##_teardown(_metadata, self, variant->data); \ _exit(0); \ } \ if (_metadata->setup_completed && fixture_name##_teardown_parent && \ - __sync_bool_compare_and_swap(teardown, false, true)) \ + !__atomic_test_and_set(teardown, __ATOMIC_RELAXED)) \ fixture_name##_teardown(_metadata, self, variant->data); \ munmap(teardown, sizeof(*teardown)); \ if (self && fixture_name##_teardown_parent) \ From patchwork Mon May 5 15:15:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 888360 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 088B325E457; Mon, 5 May 2025 15:16:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458179; cv=none; b=S9ooJ0AKZkK907YZYB0n7OSgfhz3c0pmZXger8LvXeVIslXG07qsAwVrlbMeDzz045mcvzBbZGQzeNsKgl5W4R8TNnojSF70+mJo0zCoRXsma3tyT8rDRYKSAXYhDb56/aIZFigNdUcqAYyEe8aRejhZYpA6iBJe+I/ZtmOambM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458179; c=relaxed/simple; bh=Hzo5unfwpqoBkyl8kQlCKOzue+BWkvkpq74iyeq2U3U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Y+OU6fikaH4lYC5k0O4R0P9wb0AXvmzLJAqze02FKz7rB9RcY2XFNpWAiKN1fRgn7lXZK3ccnJ0ckH0J6o3hJkrlGv6yy80ttp2E0EXBDHyIE67sp0UmJNVIzBd2NNxzINpIFBnKAwz/I/f8BnbZ+PqT6zIbZjxidHOAjphduRc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=CZ8ftztd; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=qp7rGAAi; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="CZ8ftztd"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="qp7rGAAi" From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1746458174; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=v3U47u23p2Sw0B63287BdveipGhvw9w+TsOh+jWbam4=; b=CZ8ftztdVCxSewDt7MJpQKvYimjKFL5Lt8hoYkFM2/fs3wUZRT7yBVMT7LSD8mob2ISYY6 YGPvXe0RncC2RuKBkYbLGbjVg3UwiYdkt6xXoUlt0CVuT2k5r3cDhYqaKtbGd6n3DQTPnj rszB1NklNp0haq6Bwb5umdjOR5gqZoMGY06sgk13g4nlFT1ttjNRdRpHiL5EkQlLbCqOqm CQJfDpQql9yaeAnjCJjtf3b7vhbAP2KPngIDDEZ4CP+485RXtqxLtZ6FI0yG7kjOkvxjPe TqrbvQZODQDpGeuZjGu54FKZJHr+HY4Nc6/cU9MdYhTSFf+GnPx756gvSyAYUQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1746458174; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=v3U47u23p2Sw0B63287BdveipGhvw9w+TsOh+jWbam4=; b=qp7rGAAiktlPE+sb5tZCwCR4UmudtyopDm3yfprfgSn0u28SUqPSJpy962DqXWJpqKdng7 cVqZXAC4SpuRx0Dw== Date: Mon, 05 May 2025 17:15:25 +0200 Subject: [PATCH v4 07/14] selftests: harness: Implement test timeouts through pidfd Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250505-nolibc-kselftest-harness-v4-7-ee4dd5257135@linutronix.de> References: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> In-Reply-To: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> To: Shuah Khan , Shuah Khan , Willy Tarreau , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Kees Cook Cc: Andy Lutomirski , Will Drewry , Mark Brown , Muhammad Usama Anjum , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, =?utf-8?q?T?= =?utf-8?q?homas_Wei=C3=9Fschuh?= X-Developer-Signature: v=1; a=ed25519-sha256; t=1746458170; l=4131; i=thomas.weissschuh@linutronix.de; s=20240209; h=from:subject:message-id; bh=Hzo5unfwpqoBkyl8kQlCKOzue+BWkvkpq74iyeq2U3U=; b=kr60gWheJCInFJTh5O3krcBVoCxd7MTi81fZuBrApXanFqGLmXsMfhNRIcgx4itqejg87CWiR jwU80qHAn0gCvMIy4i03z6aTLCttgIdXwmFYmApaGKYno639EKl+OJD X-Developer-Key: i=thomas.weissschuh@linutronix.de; a=ed25519; pk=pfvxvpFUDJV2h2nY0FidLUml22uGLSjByFbM6aqQQws= Make the kselftest harness compatible with nolibc which does not implement signals by replacing the signal logic with pidfds. The code also becomes simpler. Signed-off-by: Thomas Weißschuh Acked-by: Shuah Khan --- tools/testing/selftests/kselftest_harness.h | 72 ++++++++++------------------- 1 file changed, 25 insertions(+), 47 deletions(-) diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h index 7ec4f66d0e3d7f129f6c2a45ff58310dabe5d03f..1e459619fe8657d7d213a7b16d7bcbc58e76e892 100644 --- a/tools/testing/selftests/kselftest_harness.h +++ b/tools/testing/selftests/kselftest_harness.h @@ -56,6 +56,8 @@ #include #include #include +#include +#include #include #include #include @@ -914,7 +916,6 @@ struct __test_metadata { int exit_code; int trigger; /* extra handler after the evaluation */ int timeout; /* seconds to wait for test timeout */ - bool timed_out; /* did this test timeout instead of exiting? */ bool aborted; /* stopped test due to failed ASSERT */ bool setup_completed; /* did setup finish? */ jmp_buf env; /* for exiting out of test early */ @@ -964,75 +965,52 @@ static inline void __test_check_assert(struct __test_metadata *t) abort(); } -struct __test_metadata *__active_test; -static void __timeout_handler(int sig, siginfo_t *info, void *ucontext) -{ - struct __test_metadata *t = __active_test; - - /* Sanity check handler execution environment. */ - if (!t) { - fprintf(TH_LOG_STREAM, - "# no active test in SIGALRM handler!?\n"); - abort(); - } - if (sig != SIGALRM || sig != info->si_signo) { - fprintf(TH_LOG_STREAM, - "# %s: SIGALRM handler caught signal %d!?\n", - t->name, sig != SIGALRM ? sig : info->si_signo); - abort(); - } - - t->timed_out = true; - /* signal process group */ - kill(-(t->pid), SIGKILL); -} - static void __wait_for_test(struct __test_metadata *t) { - struct sigaction action = { - .sa_sigaction = __timeout_handler, - .sa_flags = SA_SIGINFO, - }; - struct sigaction saved_action; /* * Sets status so that WIFEXITED(status) returns true and * WEXITSTATUS(status) returns KSFT_FAIL. This safe default value * should never be evaluated because of the waitpid(2) check and - * SIGALRM handling. + * timeout handling. */ int status = KSFT_FAIL << 8; - int child; + struct pollfd poll_child; + int ret, child, childfd; + bool timed_out = false; - if (sigaction(SIGALRM, &action, &saved_action)) { + childfd = syscall(__NR_pidfd_open, t->pid, 0); + if (childfd == -1) { t->exit_code = KSFT_FAIL; fprintf(TH_LOG_STREAM, - "# %s: unable to install SIGALRM handler\n", + "# %s: unable to open pidfd\n", t->name); return; } - __active_test = t; - t->timed_out = false; - alarm(t->timeout); - child = waitpid(t->pid, &status, 0); - if (child == -1 && errno != EINTR) { + + poll_child.fd = childfd; + poll_child.events = POLLIN; + ret = poll(&poll_child, 1, t->timeout * 1000); + if (ret == -1) { t->exit_code = KSFT_FAIL; fprintf(TH_LOG_STREAM, - "# %s: Failed to wait for PID %d (errno: %d)\n", - t->name, t->pid, errno); + "# %s: unable to wait on child pidfd\n", + t->name); return; + } else if (ret == 0) { + timed_out = true; + /* signal process group */ + kill(-(t->pid), SIGKILL); } - - alarm(0); - if (sigaction(SIGALRM, &saved_action, NULL)) { + child = waitpid(t->pid, &status, WNOHANG); + if (child == -1 && errno != EINTR) { t->exit_code = KSFT_FAIL; fprintf(TH_LOG_STREAM, - "# %s: unable to uninstall SIGALRM handler\n", - t->name); + "# %s: Failed to wait for PID %d (errno: %d)\n", + t->name, t->pid, errno); return; } - __active_test = NULL; - if (t->timed_out) { + if (timed_out) { t->exit_code = KSFT_FAIL; fprintf(TH_LOG_STREAM, "# %s: Test terminated by timeout\n", t->name); From patchwork Mon May 5 15:15:26 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 888361 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 E397825DD1E; Mon, 5 May 2025 15:16:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458178; cv=none; b=aVHd3FG6lvmItryRpgrI1lrDkQAhjarxniZwCJN0mouV22GOS9jmflZb5GqnAeiyBF5q134HTOidgwevpYuqi3RobFGJ6ctAzEx8zN8TUljTBpPk2GW4Uk66CADizjsiz2DqKtsNsF6bA0awpmjTfNuV7d/jaXYKW53VhirU4N4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458178; c=relaxed/simple; bh=1W401Ak+my+KrsBX7f3Aw19rJHwp1BqRjh0/vnd3peo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pthuINUSOvUnctb+QNYbS8XDg8ABL0PhTkOTBMFhp5uLpWDLlWEr7bcwgZ8i51VExUhV69uD1PCT2I/cy+mE1Kbg9mlRsgXk7iqKMTDq1xRPRNA46ELVofriN3vNMeN06DGQi7HvOaIzhTwHiASRucWSyKBY5T8bmthVvPY5erA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=4vmm6TiR; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=yOPagBY9; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="4vmm6TiR"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="yOPagBY9" From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1746458175; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xK0ENF64hgvN5Ncmrhe7VwWzY4Hg4XyaQVQW40BKa7Y=; b=4vmm6TiRoJIBU4e7l8jAL+NZMI0oY2NRPgOxw4s3bSLNtYRGOqxJ4rPrlXoEplEk1BERKa hVhnT9WH2QKsXQd1NElseUpk+fSSp6a/FUB4A1h8LLOvWSabUL+t6cIRovJXjOxFHkuCcU 9Mv1YN9Eoif77h1Lx4qTehWn89OoJCFA7CMh1SjJsh9um+2lDLpe9oDjNlKF645Qox3uJz VrNrYqf23KOaCEN85J8qcaUk9seyxv/c6YVAYpdhguIYZeC03w+oEElVG11/2GWu8e6zEz Sbjp5bjBbtCFe9V2lzwRGKdLhbfwhLeOMwM1bUlTKk384jAOrs0MgGbbGwgIxw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1746458175; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xK0ENF64hgvN5Ncmrhe7VwWzY4Hg4XyaQVQW40BKa7Y=; b=yOPagBY9nJUyYdIkZcQMDZglOnPkCVTbNMF2uykkaRatDYTd0ZmEiBbdA3XN3QFCcSGerM Nb6kuSmOD3iZq4Dg== Date: Mon, 05 May 2025 17:15:26 +0200 Subject: [PATCH v4 08/14] selftests: harness: Don't set setup_completed for fixtureless tests Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250505-nolibc-kselftest-harness-v4-8-ee4dd5257135@linutronix.de> References: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> In-Reply-To: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> To: Shuah Khan , Shuah Khan , Willy Tarreau , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Kees Cook Cc: Andy Lutomirski , Will Drewry , Mark Brown , Muhammad Usama Anjum , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, =?utf-8?q?T?= =?utf-8?q?homas_Wei=C3=9Fschuh?= X-Developer-Signature: v=1; a=ed25519-sha256; t=1746458170; l=912; i=thomas.weissschuh@linutronix.de; s=20240209; h=from:subject:message-id; bh=1W401Ak+my+KrsBX7f3Aw19rJHwp1BqRjh0/vnd3peo=; b=zt07AZE1iAqoB5RVwEkxe7/22hfOoledCRaUcfDAmuUJo1mBj/htfrbdma++4R63qGzsDEaEA SM70KprOYDADcpprJZ7DzZCczbaaAJkwW2zXNjU7DJewBGmCSqXrK6s X-Developer-Key: i=thomas.weissschuh@linutronix.de; a=ed25519; pk=pfvxvpFUDJV2h2nY0FidLUml22uGLSjByFbM6aqQQws= This field is unused and has no meaning for tests without fixtures. Don't set it for them. Signed-off-by: Thomas Weißschuh Acked-by: Shuah Khan --- tools/testing/selftests/kselftest_harness.h | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h index 1e459619fe8657d7d213a7b16d7bcbc58e76e892..905986debbfb0ce8c9659dbd52b6c67c6759cae7 100644 --- a/tools/testing/selftests/kselftest_harness.h +++ b/tools/testing/selftests/kselftest_harness.h @@ -178,7 +178,6 @@ struct __test_metadata *_metadata, \ struct __fixture_variant_metadata __attribute__((unused)) *variant) \ { \ - _metadata->setup_completed = true; \ if (setjmp(_metadata->env) == 0) \ test_name(_metadata); \ __test_check_assert(_metadata); \ From patchwork Mon May 5 15:15:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 888359 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 0B7A025FA05; Mon, 5 May 2025 15:16:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458179; cv=none; b=cPhBCWxoEYXZ4IQ6LOzPYchljDGQUEfUwEruQ/sanL+tGd1gEza3lWzI5ut3XcFYS6nq1DcHbsU1rHNJEZ1hVCqG95cGJ7JBeKBjjr06EmJFXtSFqx1W5KAiI/6VOkSiWKvFeFuE8SuNgTP2yUEzS1RSPEEyGmi5mk31qqR6iQ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458179; c=relaxed/simple; bh=cIAbiYAQCJHymzx2YQGvNcUZ4KQQgJzrrBBrgowF7y0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=L6XAO3dlrAzC4PUdor0okqgkdoPZgAr2ULQlGjzbVloqsuVzrQhT4NQbSkqExVy4qnpaFXQCkK9SIKIIoekD82o7VR94+HviNapSC36aFtThNPqL/7nDE3pYrTFrt3ec0tN2fqfSvrlcNJIKz6YTQdYm7jXrubjt+Jv8FP5ii7o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=qRT+tLf+; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=SlVaeGvG; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="qRT+tLf+"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="SlVaeGvG" From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1746458175; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=PMEjXYtOVelogEkWnB2vXLhzX+zDJWYDpEZ5D94Yo94=; b=qRT+tLf+oKx4L74EtcZzUTyE0xQngIOW3CLs7RAhA3Af0lEN0DJR9aFf1Bq2Fm6LcsujVa I1ZO/Q2KIeLXr8jvdGwWoL/AL9pbmjFvZwdTNsAb87m8vsFTwH/tq0oGvXKfnAonMe/6Mw kIY9ZpsO1IVRBJaVdzXAFRBxi4YgD7D7ErdooY4IeSaa9CUmJ3eRJJ1VD99kkCIykcCtzT d2Q3MVunTYBfjWd4c6QyOiEuv8BujUX8RsmT5z9zRigzOyrETe9fCsslMHr7wo+2E85A7V zYm6eqKvqGRVZuBCxYRVcTWlF4UYP4y4tzo7GgEz0nsyuNa3+oJ04Mbq36MPpg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1746458175; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=PMEjXYtOVelogEkWnB2vXLhzX+zDJWYDpEZ5D94Yo94=; b=SlVaeGvGc4buCQYGOlwXeUvfNEr8RYUO5hztm5nxESs6hzSw+VpZHDp8eYQ4mYPhT2EvIP +2sk9rkmRu1hroCQ== Date: Mon, 05 May 2025 17:15:27 +0200 Subject: [PATCH v4 09/14] selftests: harness: Move teardown conditional into test metadata Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250505-nolibc-kselftest-harness-v4-9-ee4dd5257135@linutronix.de> References: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> In-Reply-To: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> To: Shuah Khan , Shuah Khan , Willy Tarreau , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Kees Cook Cc: Andy Lutomirski , Will Drewry , Mark Brown , Muhammad Usama Anjum , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, =?utf-8?q?T?= =?utf-8?q?homas_Wei=C3=9Fschuh?= X-Developer-Signature: v=1; a=ed25519-sha256; t=1746458170; l=3493; i=thomas.weissschuh@linutronix.de; s=20240209; h=from:subject:message-id; bh=cIAbiYAQCJHymzx2YQGvNcUZ4KQQgJzrrBBrgowF7y0=; b=coa6dTM3UXD4w8mifRa2JBo0DI+5K6TNWjweDiWu9YSxYlbCg7roxnFyUY9HCIG5ZkiRq0Bta 8nYouNjdBUVBW2f49c/T+LPvE4ZUBOY8/aGB4uYaRsN1POohWNUVc2l X-Developer-Key: i=thomas.weissschuh@linutronix.de; a=ed25519; pk=pfvxvpFUDJV2h2nY0FidLUml22uGLSjByFbM6aqQQws= To get rid of setjmp()/longjmp(), the teardown logic needs to be usable from __bail(). To access the atomic teardown conditional from there, move it into the test metadata. This also allows the removal of "setup_completed". Signed-off-by: Thomas Weißschuh Acked-by: Shuah Khan --- tools/testing/selftests/kselftest_harness.h | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h index 905986debbfb0ce8c9659dbd52b6c67c6759cae7..895821af3e5c5752065561d0a108210d79e9eeee 100644 --- a/tools/testing/selftests/kselftest_harness.h +++ b/tools/testing/selftests/kselftest_harness.h @@ -411,9 +411,9 @@ pid_t child = 1; \ int status = 0; \ /* Makes sure there is only one teardown, even when child forks again. */ \ - bool *teardown = mmap(NULL, sizeof(*teardown), \ + _metadata->no_teardown = mmap(NULL, sizeof(*_metadata->no_teardown), \ PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); \ - *teardown = false; \ + *_metadata->no_teardown = true; \ if (sizeof(*self) > 0) { \ if (fixture_name##_teardown_parent) { \ self = mmap(NULL, sizeof(*self), PROT_READ | PROT_WRITE, \ @@ -431,7 +431,7 @@ /* Let setup failure terminate early. */ \ if (_metadata->exit_code) \ _exit(0); \ - _metadata->setup_completed = true; \ + *_metadata->no_teardown = false; \ fixture_name##_##test_name(_metadata, self, variant->data); \ } else if (child < 0 || child != waitpid(child, &status, 0)) { \ ksft_print_msg("ERROR SPAWNING TEST GRANDCHILD\n"); \ @@ -439,15 +439,16 @@ } \ } \ if (child == 0) { \ - if (_metadata->setup_completed && !fixture_name##_teardown_parent && \ - !__atomic_test_and_set(teardown, __ATOMIC_RELAXED)) \ + if (!fixture_name##_teardown_parent && \ + !__atomic_test_and_set(_metadata->no_teardown, __ATOMIC_RELAXED)) \ fixture_name##_teardown(_metadata, self, variant->data); \ _exit(0); \ } \ - if (_metadata->setup_completed && fixture_name##_teardown_parent && \ - !__atomic_test_and_set(teardown, __ATOMIC_RELAXED)) \ + if (fixture_name##_teardown_parent && \ + !__atomic_test_and_set(_metadata->no_teardown, __ATOMIC_RELAXED)) \ fixture_name##_teardown(_metadata, self, variant->data); \ - munmap(teardown, sizeof(*teardown)); \ + munmap(_metadata->no_teardown, sizeof(*_metadata->no_teardown)); \ + _metadata->no_teardown = NULL; \ if (self && fixture_name##_teardown_parent) \ munmap(self, sizeof(*self)); \ if (WIFEXITED(status)) { \ @@ -916,7 +917,7 @@ struct __test_metadata { int trigger; /* extra handler after the evaluation */ int timeout; /* seconds to wait for test timeout */ bool aborted; /* stopped test due to failed ASSERT */ - bool setup_completed; /* did setup finish? */ + bool *no_teardown; /* fixture needs teardown */ jmp_buf env; /* for exiting out of test early */ struct __test_results *results; struct __test_metadata *prev, *next; @@ -1195,7 +1196,7 @@ static void __run_test(struct __fixture_metadata *f, t->exit_code = KSFT_PASS; t->trigger = 0; t->aborted = false; - t->setup_completed = false; + t->no_teardown = NULL; memset(t->env, 0, sizeof(t->env)); memset(t->results->reason, 0, sizeof(t->results->reason)); From patchwork Mon May 5 15:15:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 887656 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 0B8372609DF; Mon, 5 May 2025 15:16:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458179; cv=none; b=uiwnNkPphPJNJ06w/r/D8O6q4xpKQA4zMXOMM/mW1a9jnRa/yHZt6rxPmkFWO7hNmNYfwf8OiWrSHjqTbO8M3+RLaXlfX/oeA4Q3h8KwbBPhFBXiI3MfKFBNZA557e6QOGDx/pOsQF4vEBdU5/cwRlt3feBSB8OwgnjPUSOLHdU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458179; c=relaxed/simple; bh=4EziIyuNtndmKe4I0VA1SvkCzM+7fFihUqiCilnzZyM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iBD2FYDnqfFc2uonpm0osHYLSDdeDM3jwEaYRNIzg6DuWWrPpP8cJiYsIvAsqFK3weMwKHZ69dOgJwBLpIkEvJqqbgCyzIpaGAPGgtKU4aCL78ax1yHN93BYCSWCkuoXT9FJYff6/0zKXyzSejAM7mWxVHhafNBNZeTbMQrwpmY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=0BO7ZlM7; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=TtRHjeGs; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="0BO7ZlM7"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="TtRHjeGs" From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1746458176; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=CRjOGqv37y13JtLIhuaeoavB7nfm6OGp7fisOHTFIKE=; b=0BO7ZlM7gOgRz3IOpb5wx/AxOGnhn1XBL/+mNvNSGNJcBIxAAaBrMpIA0Uu5eOToa5dieA QxnO4mOh2QylrwPhyS73wcwmVcWM5RvKFlZS55ligHe665Zg65o5ngJzyndCTKnpp4L9xK w4O0pkiVCyWG7TQxEDHO8/91GVycHTECkev1qkt8zrJ7wTyvF3SNrw8mzM9wTVLxpQ4+OL 44hQoID1w2QNPCVz+kRZVRTASmBdEXhWWJzsS/nIc2/IMjvwaOb/7mjXOEgA0MWmaOEQ/y pHaUNH9HzVdZ8E4u6RBba4VBwiiHZWZ0G14yF+aJn4d85aSSWE6o//FfEJxCCA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1746458176; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=CRjOGqv37y13JtLIhuaeoavB7nfm6OGp7fisOHTFIKE=; b=TtRHjeGsR4cUpXAmzddlmwcjqW0tS3bqo7q/1CaDq6OmAw8/x79ilhCOEMc3fo1uAVW3NY 9titQIrFyHPqf5CQ== Date: Mon, 05 May 2025 17:15:28 +0200 Subject: [PATCH v4 10/14] selftests: harness: Add teardown callback to test metadata Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250505-nolibc-kselftest-harness-v4-10-ee4dd5257135@linutronix.de> References: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> In-Reply-To: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> To: Shuah Khan , Shuah Khan , Willy Tarreau , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Kees Cook Cc: Andy Lutomirski , Will Drewry , Mark Brown , Muhammad Usama Anjum , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, =?utf-8?q?T?= =?utf-8?q?homas_Wei=C3=9Fschuh?= X-Developer-Signature: v=1; a=ed25519-sha256; t=1746458170; l=2808; i=thomas.weissschuh@linutronix.de; s=20240209; h=from:subject:message-id; bh=4EziIyuNtndmKe4I0VA1SvkCzM+7fFihUqiCilnzZyM=; b=rGYg0T7+Pz/BkXBpWkZILIHEDS//4/mlvrWD6+/nhgizcYbeM7FBiIAjXoTKTqm7WkESdxdtE 4zUxRFTQR7TAgfaNutPfMnpO3pEvXuV/ZLTXUFSYjPKuwwDAwp4MsPu X-Developer-Key: i=thomas.weissschuh@linutronix.de; a=ed25519; pk=pfvxvpFUDJV2h2nY0FidLUml22uGLSjByFbM6aqQQws= To get rid of setjmp()/longjmp(), the teardown logic needs to be usable from __bail(). Introduce a new callback for it. Signed-off-by: Thomas Weißschuh Acked-by: Shuah Khan --- tools/testing/selftests/kselftest_harness.h | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h index 895821af3e5c5752065561d0a108210d79e9eeee..acb476093b74968ecb71180ade9e5852b22da170 100644 --- a/tools/testing/selftests/kselftest_harness.h +++ b/tools/testing/selftests/kselftest_harness.h @@ -439,14 +439,10 @@ } \ } \ if (child == 0) { \ - if (!fixture_name##_teardown_parent && \ - !__atomic_test_and_set(_metadata->no_teardown, __ATOMIC_RELAXED)) \ - fixture_name##_teardown(_metadata, self, variant->data); \ + _metadata->teardown_fn(false, _metadata, self, variant->data); \ _exit(0); \ } \ - if (fixture_name##_teardown_parent && \ - !__atomic_test_and_set(_metadata->no_teardown, __ATOMIC_RELAXED)) \ - fixture_name##_teardown(_metadata, self, variant->data); \ + _metadata->teardown_fn(true, _metadata, self, variant->data); \ munmap(_metadata->no_teardown, sizeof(*_metadata->no_teardown)); \ _metadata->no_teardown = NULL; \ if (self && fixture_name##_teardown_parent) \ @@ -460,6 +456,14 @@ } \ __test_check_assert(_metadata); \ } \ + static void wrapper_##fixture_name##_##test_name##_teardown( \ + bool in_parent, struct __test_metadata *_metadata, \ + void *self, const void *variant) \ + { \ + if (fixture_name##_teardown_parent == in_parent && \ + !__atomic_test_and_set(_metadata->no_teardown, __ATOMIC_RELAXED)) \ + fixture_name##_teardown(_metadata, self, variant); \ + } \ static struct __test_metadata *_##fixture_name##_##test_name##_object; \ static void __attribute__((constructor)) \ _register_##fixture_name##_##test_name(void) \ @@ -469,6 +473,7 @@ object->name = #test_name; \ object->fn = &wrapper_##fixture_name##_##test_name; \ object->fixture = &_##fixture_name##_fixture_object; \ + object->teardown_fn = &wrapper_##fixture_name##_##test_name##_teardown; \ object->termsig = signal; \ object->timeout = tmout; \ _##fixture_name##_##test_name##_object = object; \ @@ -912,6 +917,8 @@ struct __test_metadata { struct __fixture_variant_metadata *); pid_t pid; /* pid of test when being run */ struct __fixture_metadata *fixture; + void (*teardown_fn)(bool in_parent, struct __test_metadata *_metadata, + void *self, const void *variant); int termsig; int exit_code; int trigger; /* extra handler after the evaluation */ From patchwork Mon May 5 15:15:29 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 887655 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 97A23262FCB; Mon, 5 May 2025 15:16:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458180; cv=none; b=m99RUoL20fDbezlMQFzZzksIgKoRsvnO/ltPhgtq3aIYme8RMUwh1Nz69mfre62Q0ndAtL0YRKH+XxYcse67NeoXvUvnktvnV5S8EwzQZsbU2QU5VwPfdQg7V8qX727qDV5JM9vUc8HoALwjwIr/70MpUo6Qy7MOjgmhb7/Ds2Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458180; c=relaxed/simple; bh=dZJe/GuY8DCD+P4SRvM/cXfTKtE8IWZ0aUq54fDachw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=EpdaIXHS8TYOIj/gYdETrfWl/U+10Vgai5m45xNgrgNIX6DW99B5jYrMjP4rOSQChKJYtQP4EiACbCiXKSMd4hWLnpXgAanSVA8siVXVNVomTZvkiqmY/T6UsA12EYUrThaGzNINlEa7SAsMTSnCv5l6IRVierLTCM2luIAhPEw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=IwjAJCMI; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=aIKJPVrY; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="IwjAJCMI"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="aIKJPVrY" From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1746458176; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7M/KT6c4m/HT5iZ05zmOXmbeyImB/lmz8pLtAGEhfbk=; b=IwjAJCMI5KJIWicZeGER3UcHdqvWr9n4piYR0UamnOFLH62HAsSa7qO4FZNAiuUnJEpd6x uSNduNtpCi257fnPqvY9FQ9p0R1SCatsbtcNN+6/bE8eLdgDlRCuHLZOwRm9IDjhQWBYn0 DBJaYGTG7UXST2fT3+UaVMoCIkixj3gt6ywfp+KJ+kTSlRDe/5jthxpfjcx2KtFFxk5ei9 QiD7MV3JRbRyhhMlB6dImJoh+AzZbgyur0tbYROWraQfTz8KWpvcobCQgOwNvxHFi61RJV VmEwFrkvwjUcT+FCWcZYsWCTzIKgE6f2amBLiv677TYNLRH+2A/O9oFRJSIzpg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1746458176; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7M/KT6c4m/HT5iZ05zmOXmbeyImB/lmz8pLtAGEhfbk=; b=aIKJPVrYMO2CzhdCTai+3EtpZZ0VuIxlpWTxa1w+uCHzgCZwQOylBqCPSX8Cf4ev2muzLf B0mhscSKx8VmD6Dw== Date: Mon, 05 May 2025 17:15:29 +0200 Subject: [PATCH v4 11/14] selftests: harness: Add "variant" and "self" to test metadata Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250505-nolibc-kselftest-harness-v4-11-ee4dd5257135@linutronix.de> References: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> In-Reply-To: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> To: Shuah Khan , Shuah Khan , Willy Tarreau , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Kees Cook Cc: Andy Lutomirski , Will Drewry , Mark Brown , Muhammad Usama Anjum , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, =?utf-8?q?T?= =?utf-8?q?homas_Wei=C3=9Fschuh?= X-Developer-Signature: v=1; a=ed25519-sha256; t=1746458170; l=1221; i=thomas.weissschuh@linutronix.de; s=20240209; h=from:subject:message-id; bh=dZJe/GuY8DCD+P4SRvM/cXfTKtE8IWZ0aUq54fDachw=; b=bs+1ZUlRgQtLqceT0FrYNlE+Jd7svhxW16EeK9XaAsiVeTdgTqilJc5eF3aEMB35ssj5Fflw9 BIWIoSpu5BQDyQj0CjPjZlHKDe4jAiJRP6UtRU9sPeqD7DmX0h0xvy+ X-Developer-Key: i=thomas.weissschuh@linutronix.de; a=ed25519; pk=pfvxvpFUDJV2h2nY0FidLUml22uGLSjByFbM6aqQQws= To get rid of setjmp()/longjmp(), the variant and self need to be usable from __bail(). Make them available from the test metadata. Signed-off-by: Thomas Weißschuh --- tools/testing/selftests/kselftest_harness.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h index acb476093b74968ecb71180ade9e5852b22da170..088c875df91a58f8760749b6047b246fb2a7891f 100644 --- a/tools/testing/selftests/kselftest_harness.h +++ b/tools/testing/selftests/kselftest_harness.h @@ -423,6 +423,8 @@ self = &self_private; \ } \ } \ + _metadata->variant = variant->data; \ + _metadata->self = self; \ if (setjmp(_metadata->env) == 0) { \ /* _metadata and potentially self are shared with all forks. */ \ child = fork(); \ @@ -926,6 +928,8 @@ struct __test_metadata { bool aborted; /* stopped test due to failed ASSERT */ bool *no_teardown; /* fixture needs teardown */ jmp_buf env; /* for exiting out of test early */ + void *self; + const void *variant; struct __test_results *results; struct __test_metadata *prev, *next; }; From patchwork Mon May 5 15:15:30 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 888358 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 026A5264F87; Mon, 5 May 2025 15:16:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458182; cv=none; b=JnHZjM1gAOcN1Ywppy4yjFOFesgQ30Ad9OPMhqKixTUkUvdADnXvYnmG8FCvfhB2mhNCuVYxD/LvL9yfEbJdjUWd8VhryY2/Y0bn9FjK5Tx80dysh5AuQuo5wIJ6TncMM6DEjN7PLTcBEKnoyKFg20isab3Xko4R2Wwyh1hyG84= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458182; c=relaxed/simple; bh=6PXX0RPavfD0BJDHtEI33ME+xSL0lQUIgGhs4+WRGfM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KTDBOGanAjOu/2Tg183fpn7u9uQRbvFO+x/LgebDYLZdRsp7awRN54LIWKwYaKxTFKMVRFQu57TwFJudvb54loEj4HL6CXVHtItp/xqJFbwNqvPrJOVO6B7bCpZAXf1tKhh2VsAJYYbMObVhSlUeHaY+MWp30ESjIiKN1O+8vXI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=zGVAGUz3; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=niXve+jX; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="zGVAGUz3"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="niXve+jX" From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1746458177; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Gpw6KDVkngaoQltUTXFxgfCAMehnBq4/rT28mSBJ5PI=; b=zGVAGUz37bQzKsVlQaI3iwQDr5mMJeVgDfUNBFWRvPN6SINStYiEnbtRUziOVPDBqCgZNm Y5I3A1C9K6yEQMFX6lm6QFY15ZwORbVfDcEP0WkuDx+162IYTGdoaGshnZcr7AAHU6cg+6 WZ7D+EQW/Ugqq744pTiwf703boeHMWIMpMUqIe4Kp31dByF7T1BmN6o8njBW6AprOVD+px 48Jgio2eIO5+pFC94BgxRLWTuI04cJwezz1YyYuP+guWesed9qIkNCZVE71EQQnCofjIlr RanoCUKWb8ulEBRQ2lPs/0xYE//mkspS70+H480L1dagXc2N+2h0sQZMw1ZUXQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1746458177; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Gpw6KDVkngaoQltUTXFxgfCAMehnBq4/rT28mSBJ5PI=; b=niXve+jXGCFUvlAEuzcqpweAyytW3MG3m9B1FL+P+ZwoSYeTtUeYBnSZ4yB+X+aWRtyj95 NTsP6W8gletH8UDQ== Date: Mon, 05 May 2025 17:15:30 +0200 Subject: [PATCH v4 12/14] selftests: harness: Stop using setjmp()/longjmp() Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250505-nolibc-kselftest-harness-v4-12-ee4dd5257135@linutronix.de> References: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> In-Reply-To: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> To: Shuah Khan , Shuah Khan , Willy Tarreau , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Kees Cook Cc: Andy Lutomirski , Will Drewry , Mark Brown , Muhammad Usama Anjum , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, =?utf-8?q?T?= =?utf-8?q?homas_Wei=C3=9Fschuh?= X-Developer-Signature: v=1; a=ed25519-sha256; t=1746458170; l=4602; i=thomas.weissschuh@linutronix.de; s=20240209; h=from:subject:message-id; bh=6PXX0RPavfD0BJDHtEI33ME+xSL0lQUIgGhs4+WRGfM=; b=bcb6sDDsuok2fryt9+FDUQ8Kd00SmLVRLwK81fL5PE+J86edkboaoxl+YNKKvna9oXatMsLkv XjewX119zqgBfepOIFC631ZloGnIhp+WALWh61ZHF8Ep9KbIbrIl1Hb X-Developer-Key: i=thomas.weissschuh@linutronix.de; a=ed25519; pk=pfvxvpFUDJV2h2nY0FidLUml22uGLSjByFbM6aqQQws= Usage of longjmp() was added to ensure that teardown is always run in commit 63e6b2a42342 ("selftests/harness: Run TEARDOWN for ASSERT failures") However instead of calling longjmp() to the teardown handler it is easier to just call the teardown handler directly from __bail(). Any potential duplicate teardown invocations are harmless as the actual handler will only ever be executed once since commit fff37bd32c76 ("selftests/harness: Fix fixture teardown"). Additionally this removes a incompatibility with nolibc, which does not support setjmp()/longjmp(). Signed-off-by: Thomas Weißschuh --- tools/testing/selftests/kselftest_harness.h | 45 ++++++++++------------------- 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h index 088c875df91a58f8760749b6047b246fb2a7891f..2925e47db995d7197ed1f55bd9cc657669df9bd3 100644 --- a/tools/testing/selftests/kselftest_harness.h +++ b/tools/testing/selftests/kselftest_harness.h @@ -67,7 +67,6 @@ #include #include #include -#include #include "kselftest.h" @@ -178,9 +177,7 @@ struct __test_metadata *_metadata, \ struct __fixture_variant_metadata __attribute__((unused)) *variant) \ { \ - if (setjmp(_metadata->env) == 0) \ - test_name(_metadata); \ - __test_check_assert(_metadata); \ + test_name(_metadata); \ } \ static struct __test_metadata _##test_name##_object = \ { .name = #test_name, \ @@ -425,24 +422,20 @@ } \ _metadata->variant = variant->data; \ _metadata->self = self; \ - if (setjmp(_metadata->env) == 0) { \ - /* _metadata and potentially self are shared with all forks. */ \ - child = fork(); \ - if (child == 0) { \ - fixture_name##_setup(_metadata, self, variant->data); \ - /* Let setup failure terminate early. */ \ - if (_metadata->exit_code) \ - _exit(0); \ - *_metadata->no_teardown = false; \ - fixture_name##_##test_name(_metadata, self, variant->data); \ - } else if (child < 0 || child != waitpid(child, &status, 0)) { \ - ksft_print_msg("ERROR SPAWNING TEST GRANDCHILD\n"); \ - _metadata->exit_code = KSFT_FAIL; \ - } \ - } \ + /* _metadata and potentially self are shared with all forks. */ \ + child = fork(); \ if (child == 0) { \ + fixture_name##_setup(_metadata, self, variant->data); \ + /* Let setup failure terminate early. */ \ + if (_metadata->exit_code) \ + _exit(0); \ + *_metadata->no_teardown = false; \ + fixture_name##_##test_name(_metadata, self, variant->data); \ _metadata->teardown_fn(false, _metadata, self, variant->data); \ _exit(0); \ + } else if (child < 0 || child != waitpid(child, &status, 0)) { \ + ksft_print_msg("ERROR SPAWNING TEST GRANDCHILD\n"); \ + _metadata->exit_code = KSFT_FAIL; \ } \ _metadata->teardown_fn(true, _metadata, self, variant->data); \ munmap(_metadata->no_teardown, sizeof(*_metadata->no_teardown)); \ @@ -456,7 +449,6 @@ /* Forward signal to __wait_for_test(). */ \ kill(getpid(), WTERMSIG(status)); \ } \ - __test_check_assert(_metadata); \ } \ static void wrapper_##fixture_name##_##test_name##_teardown( \ bool in_parent, struct __test_metadata *_metadata, \ @@ -927,7 +919,6 @@ struct __test_metadata { int timeout; /* seconds to wait for test timeout */ bool aborted; /* stopped test due to failed ASSERT */ bool *no_teardown; /* fixture needs teardown */ - jmp_buf env; /* for exiting out of test early */ void *self; const void *variant; struct __test_results *results; @@ -963,19 +954,14 @@ static inline int __bail(int for_realz, struct __test_metadata *t) { /* if this is ASSERT, return immediately. */ if (for_realz) { - t->aborted = true; - longjmp(t->env, 1); + if (t->teardown_fn) + t->teardown_fn(false, t, t->self, t->variant); + abort(); } /* otherwise, end the for loop and continue. */ return 0; } -static inline void __test_check_assert(struct __test_metadata *t) -{ - if (t->aborted) - abort(); -} - static void __wait_for_test(struct __test_metadata *t) { /* @@ -1208,7 +1194,6 @@ static void __run_test(struct __fixture_metadata *f, t->trigger = 0; t->aborted = false; t->no_teardown = NULL; - memset(t->env, 0, sizeof(t->env)); memset(t->results->reason, 0, sizeof(t->results->reason)); snprintf(test_name, sizeof(test_name), "%s%s%s.%s", From patchwork Mon May 5 15:15:31 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 887654 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 B5BF22673AA; Mon, 5 May 2025 15:16:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458183; cv=none; b=CY6Y8hzcjUS4i9p5pkRMYvC8sZ2SC/YqBnB/UPYz8foEK+tnhd7UvbdkVzeGuZx4O4SZZ8XVgArxNg+xXWuMWorpa5BEMo1YFJIoI425mPae/E+FKMa/NPIUlixm5K3+22jkiw+32Rr1WpaDZ+A/RbxnGl7f1Q9wlHJqhreXMA8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458183; c=relaxed/simple; bh=q3F6Jm+0/xfrIArvrhazQ5Nby929J/SsWkb7TXkAHgk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DcKtrE+ho3JzfyyIQOP6vPQ15yMmRodjI/uCJOJp/IoCs+uqkCpSiOlKs5gyWO6yT2n05MxtMeqcJDE1tSypMrhgLsPEXfaVutXLtDXtepNDiTMPkyDXxSPNQzH9T+kmJkpN5bMFDX9VgQj9k8K0CNa/1LdxQWsDNwrU2EAoaD0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=O0tqN8Jh; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=kN6Ner6/; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="O0tqN8Jh"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="kN6Ner6/" From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1746458177; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=AiNSxZF++ED923SbPZg8cZpQ/pm2Fkr2e/nA7wxrkFA=; b=O0tqN8JhxHGO9Gi8EIgdK2PaRxm2DFcc+pthAid0tlxChjul1GKtAQ4S1+jMCzNVYYd48L LC2q4tDGFgzI/SKPyovuBQk77ENRELgMOEjp8W+z0GFa7BgT3NQM+zKWjOX9Wdh6pZrdLu fit1ZUdwUKsznf2mWGdBGSyBwNHcfTJl23cWzA46B3S+rxvpecIBV+rbVJxmTrD8XC6dY1 AxijNyOTnt4o0kxdNK3d6LMTUVYaiWea4h3vcON/NOqfYDPDBLhGpgnmTwiF052EThWRV2 6vcMCIX5lHEY256APvfC8DWNx9zzHMpVQQ+/iifQVjQmAq1ZoqPBEfoHieneHg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1746458177; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=AiNSxZF++ED923SbPZg8cZpQ/pm2Fkr2e/nA7wxrkFA=; b=kN6Ner6/LYRPf8C9CxSHqzhmU1OGzYilv6KCWLNdxFMi7X5Gxn1XuN5bcE3HVyxFWo3vD/ /QUIz6M0O5Lss3CA== Date: Mon, 05 May 2025 17:15:31 +0200 Subject: [PATCH v4 13/14] selftests: harness: Guard includes on nolibc Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250505-nolibc-kselftest-harness-v4-13-ee4dd5257135@linutronix.de> References: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> In-Reply-To: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> To: Shuah Khan , Shuah Khan , Willy Tarreau , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Kees Cook Cc: Andy Lutomirski , Will Drewry , Mark Brown , Muhammad Usama Anjum , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, =?utf-8?q?T?= =?utf-8?q?homas_Wei=C3=9Fschuh?= X-Developer-Signature: v=1; a=ed25519-sha256; t=1746458170; l=1132; i=thomas.weissschuh@linutronix.de; s=20240209; h=from:subject:message-id; bh=q3F6Jm+0/xfrIArvrhazQ5Nby929J/SsWkb7TXkAHgk=; b=9ePNhLKywEPYAlUA0cza6UimkIEdmFvdXj1Uhl9bOJ5jFla+1s4NHEGdReKQM7u44ow0NJ+0J TcafEgy0dKQC40hY4+VYE8KBYKZ8FnUVljiWJ3kWLJPDnxUNKiZMXKB X-Developer-Key: i=thomas.weissschuh@linutronix.de; a=ed25519; pk=pfvxvpFUDJV2h2nY0FidLUml22uGLSjByFbM6aqQQws= Nolibc doesn't provide all normal header files. Don't try to include these non-existent header files, as the symbols are available unconditionally anyways. Signed-off-by: Thomas Weißschuh Acked-by: Shuah Khan --- tools/testing/selftests/kselftest_harness.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h index 2925e47db995d7197ed1f55bd9cc657669df9bd3..3fa92860cb25f399e27b25385d9de5b54359b93b 100644 --- a/tools/testing/selftests/kselftest_harness.h +++ b/tools/testing/selftests/kselftest_harness.h @@ -57,16 +57,19 @@ #include #include #include -#include #include #include #include #include #include +#include + +#ifndef NOLIBC +#include #include #include #include -#include +#endif #include "kselftest.h" From patchwork Mon May 5 15:15:32 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Patchwork-Id: 888357 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 CB37D264A7C; Mon, 5 May 2025 15:16:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458184; cv=none; b=O7wQnv5Gbbz903O8gJoAYRW56l6BS6YqKXx+hEZgVWPaHoC0rojn+G+iei/NPluVLLi/EyXyw/t7LxPz0LnGeySfVVPuHMkAqT4UvZTb9Veu2dKy8Pz/SuDDbbHtwb2gyIspTErOL+U4x5WjvSHZYgx98z/c3881hXQgi+xPTFw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746458184; c=relaxed/simple; bh=qh0vQlZ9hubosVL32oNqvWQK5UEfSC/f8Z40B8jF3Aw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ViWeDnkCxGc32Op5SNKR0zBalI43qBiT97CHy1X36sD9+J86aSYW7djm82o4HJRr4qxABPcpTDvvkgl1Rh2QQea+xwQH/EcyD8vxtdm5aX69l55RQqv5Uj7Ys0R9AtO6nS2dzkrBXwDxnGpM71VSuf1IUABJZzTmXv/zcTGXFa0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=fcj4OutV; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=qkszeFgb; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="fcj4OutV"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="qkszeFgb" From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1746458178; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=n8aeeXdZ2Lralu6rE8UHC3uK5cPOYXFR3Akm9cDko9A=; b=fcj4OutV86bMxYIr4huHZ0G9h79VQTe00H8yQIq6mZ5uAudbNo03swR02PLEhCzNiu8jsb T8lWQnpYtX5xZnS2jGjbj8EdzhWzywtaci3cPtgyXmKMxYrWAPPGc2stxgeKCWCYKQh20X IJLfT7HylN24PLArozXdH5wkU+A8K1nizYNE4TMy26cf5BM91H8EPtLsgXRzMir7bQfIae i2bGqJZLXKUv258z/DAk8EyFQoPfTKl+iFV82mSYPmp1pCGeuCjJ27K3j9RJKks46C996c v7CAIRGd9JxrbYmKRMWwgBBdYzNOQRYlk1xRfDHMxC5wFhDMqa7md8mfgXVcCA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1746458178; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=n8aeeXdZ2Lralu6rE8UHC3uK5cPOYXFR3Akm9cDko9A=; b=qkszeFgbVa9MLS8mi+ya6bZ0+VaKEqYyekOv4ewuewk/xwDVrCOu4oYUdxpD+iyE7suq+m yR4I/y02Ip55vwBA== Date: Mon, 05 May 2025 17:15:32 +0200 Subject: [PATCH v4 14/14] HACK: selftests/nolibc: demonstrate usage of the kselftest harness Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250505-nolibc-kselftest-harness-v4-14-ee4dd5257135@linutronix.de> References: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> In-Reply-To: <20250505-nolibc-kselftest-harness-v4-0-ee4dd5257135@linutronix.de> To: Shuah Khan , Shuah Khan , Willy Tarreau , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Kees Cook Cc: Andy Lutomirski , Will Drewry , Mark Brown , Muhammad Usama Anjum , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, =?utf-8?q?T?= =?utf-8?q?homas_Wei=C3=9Fschuh?= X-Developer-Signature: v=1; a=ed25519-sha256; t=1746458170; l=61534; i=thomas.weissschuh@linutronix.de; s=20240209; h=from:subject:message-id; bh=qh0vQlZ9hubosVL32oNqvWQK5UEfSC/f8Z40B8jF3Aw=; b=arNgn47CZXDfb/9SWycG6CKopjqhC6ux9cUCw3oYwvbhoJbUDIY+Q8zFy06Q1ij0+EvvqgbOL YvheeVRcVTHCgu+FOqLxu65lzFS1JaYyzayZ8ep+fn9uWOWLy4klFoS X-Developer-Key: i=thomas.weissschuh@linutronix.de; a=ed25519; pk=pfvxvpFUDJV2h2nY0FidLUml22uGLSjByFbM6aqQQws= Show how to use the kselftest harness together with nolibc. This just runs the existing harness selftest by crudely replacing the regular nolibc-test.c with the harness-selftest.c to get that wired up easily. To use it: $ cd tools/testing/selftests/nolibc/ $ ./run-tests -m user In the future nolibc-test can use the harness for itself. Not-Signed-off-by: Thomas Weißschuh Acked-by: Shuah Khan --- .../selftests/kselftest_harness/harness-selftest.c | 2 +- tools/testing/selftests/nolibc/Makefile | 15 +- tools/testing/selftests/nolibc/harness-selftest.c | 1 + tools/testing/selftests/nolibc/nolibc-test.c | 1715 +------------------- tools/testing/selftests/nolibc/run-tests.sh | 2 +- 5 files changed, 12 insertions(+), 1723 deletions(-) diff --git a/tools/testing/selftests/kselftest_harness/harness-selftest.c b/tools/testing/selftests/kselftest_harness/harness-selftest.c index a0e3e89ae291f8d9f4f2ab9746a838fd1bfaf6c1..c522a18b95cf070b9c0323db2b4fb4f79e2d8788 100644 --- a/tools/testing/selftests/kselftest_harness/harness-selftest.c +++ b/tools/testing/selftests/kselftest_harness/harness-selftest.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ #include diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile index 2671383045dbb51682fd62ac8c8df9c317157317..af350f1dd584eb917a2e20f7caa6748f0ce12b67 100644 --- a/tools/testing/selftests/nolibc/Makefile +++ b/tools/testing/selftests/nolibc/Makefile @@ -180,8 +180,8 @@ Q=@ endif CFLAGS_i386 = $(call cc-option,-m32) -CFLAGS_arm = -marm -CFLAGS_armthumb = -mthumb -march=armv6t2 +CFLAGS_arm = -marm -march=armv7-a +CFLAGS_armthumb = -mthumb -march=armv7 CFLAGS_ppc = -m32 -mbig-endian -mno-vsx $(call cc-option,-mmultiple) CFLAGS_ppc64 = -m64 -mbig-endian -mno-vsx $(call cc-option,-mmultiple) CFLAGS_ppc64le = -m64 -mlittle-endian -mno-vsx $(call cc-option,-mabi=elfv2) @@ -195,9 +195,11 @@ CFLAGS_XARCH = $(CFLAGS_$(XARCH)) endif CFLAGS_STACKPROTECTOR ?= $(call cc-option,-mstack-protector-guard=global $(call cc-option,-fstack-protector-all)) CFLAGS_SANITIZER ?= $(call cc-option,-fsanitize=undefined -fsanitize-trap=all) -CFLAGS ?= -Os -fno-ident -fno-asynchronous-unwind-tables -std=c89 -W -Wall -Wextra \ +CFLAGS ?= -Os -fno-ident -fno-asynchronous-unwind-tables -std=c89 -W -Wall -Wextra -ggdb -ffreestanding \ + -ffile-prefix-map=./= \ $(call cc-option,-fno-stack-protector) $(call cc-option,-Wmissing-prototypes) \ - $(CFLAGS_XARCH) $(CFLAGS_STACKPROTECTOR) $(CFLAGS_SANITIZER) $(CFLAGS_EXTRA) + $(call cc-option,-mno-outline-atomics) \ + $(CFLAGS_$(XARCH)) $(CFLAGS_STACKPROTECTOR) $(CFLAGS_SANITIZER) $(CFLAGS_EXTRA) LDFLAGS := LIBGCC := -lgcc @@ -213,10 +215,7 @@ include $(srctree)/tools/scripts/Makefile.include # GCC uses "s390", clang "systemz" CLANG_CROSS_FLAGS := $(subst --target=s390-linux,--target=systemz-linux,$(CLANG_CROSS_FLAGS)) -REPORT ?= awk '/\[OK\][\r]*$$/{p++} /\[FAIL\][\r]*$$/{if (!f) printf("\n"); f++; print;} /\[SKIPPED\][\r]*$$/{s++} \ - END{ printf("\n%3d test(s): %3d passed, %3d skipped, %3d failed => status: ", p+s+f, p, s, f); \ - if (f || !p) printf("failure\n"); else if (s) printf("warning\n"); else printf("success\n");; \ - printf("\nSee all results in %s\n", ARGV[1]); }' +REPORT = sed -i -e '/^\[/d' -e 's/\x0d//' run.out; cmp ../kselftest_harness/harness-selftest.expected run.out && echo ok; true help: @echo "Supported targets under selftests/nolibc:" diff --git a/tools/testing/selftests/nolibc/harness-selftest.c b/tools/testing/selftests/nolibc/harness-selftest.c new file mode 120000 index 0000000000000000000000000000000000000000..a086839bc322efb070b8f03363ef2874d9f44c17 --- /dev/null +++ b/tools/testing/selftests/nolibc/harness-selftest.c @@ -0,0 +1 @@ +../kselftest_harness/harness-selftest.c \ No newline at end of file diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c index 1ad0db92f0ed47f708363b2e558717fa0e686b8f..9a074d2b24c99d86bf27f8399f2e7dc719dbcd24 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -1,1716 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#define _GNU_SOURCE -#define _LARGEFILE64_SOURCE +#define inline __inline__ -/* libc-specific include files - * The program may be built in 3 ways: - * $(CC) -nostdlib -include /path/to/nolibc.h => NOLIBC already defined - * $(CC) -nostdlib -I/path/to/nolibc/sysroot => _NOLIBC_* guards are present - * $(CC) with default libc => NOLIBC* never defined - */ -#ifndef NOLIBC -#include -#include -#include -#ifndef _NOLIBC_STDIO_H -/* standard libcs need more includes */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif -#endif - -#pragma GCC diagnostic ignored "-Wmissing-prototypes" - -#include "nolibc-test-linkage.h" - -/* for the type of int_fast16_t and int_fast32_t, musl differs from glibc and nolibc */ -#define SINT_MAX_OF_TYPE(type) (((type)1 << (sizeof(type) * 8 - 2)) - (type)1 + ((type)1 << (sizeof(type) * 8 - 2))) -#define SINT_MIN_OF_TYPE(type) (-SINT_MAX_OF_TYPE(type) - 1) - -/* will be used to test initialization of environ */ -static char **test_envp; - -/* will be used to test initialization of argv */ -static char **test_argv; - -/* will be used to test initialization of argc */ -static int test_argc; - -/* will be used by some test cases as readable file, please don't write it */ -static const char *argv0; - -/* will be used by constructor tests */ -static int constructor_test_value; - -static const int is_nolibc = -#ifdef NOLIBC - 1 -#else - 0 -#endif -; - -/* definition of a series of tests */ -struct test { - const char *name; /* test name */ - int (*func)(int min, int max); /* handler */ -}; - -#ifndef _NOLIBC_STDLIB_H -char *itoa(int i) -{ - static char buf[12]; - int ret; - - ret = snprintf(buf, sizeof(buf), "%d", i); - return (ret >= 0 && ret < sizeof(buf)) ? buf : "#err"; -} -#endif - -#define CASE_ERR(err) \ - case err: return #err - -/* returns the error name (e.g. "ENOENT") for common errors, "SUCCESS" for 0, - * or the decimal value for less common ones. - */ -static const char *errorname(int err) -{ - switch (err) { - case 0: return "SUCCESS"; - CASE_ERR(EPERM); - CASE_ERR(ENOENT); - CASE_ERR(ESRCH); - CASE_ERR(EINTR); - CASE_ERR(EIO); - CASE_ERR(ENXIO); - CASE_ERR(E2BIG); - CASE_ERR(ENOEXEC); - CASE_ERR(EBADF); - CASE_ERR(ECHILD); - CASE_ERR(EAGAIN); - CASE_ERR(ENOMEM); - CASE_ERR(EACCES); - CASE_ERR(EFAULT); - CASE_ERR(ENOTBLK); - CASE_ERR(EBUSY); - CASE_ERR(EEXIST); - CASE_ERR(EXDEV); - CASE_ERR(ENODEV); - CASE_ERR(ENOTDIR); - CASE_ERR(EISDIR); - CASE_ERR(EINVAL); - CASE_ERR(ENFILE); - CASE_ERR(EMFILE); - CASE_ERR(ENOTTY); - CASE_ERR(ETXTBSY); - CASE_ERR(EFBIG); - CASE_ERR(ENOSPC); - CASE_ERR(ESPIPE); - CASE_ERR(EROFS); - CASE_ERR(EMLINK); - CASE_ERR(EPIPE); - CASE_ERR(EDOM); - CASE_ERR(ERANGE); - CASE_ERR(ENOSYS); - CASE_ERR(EOVERFLOW); - default: - return itoa(err); - } -} - -static void align_result(size_t llen) -{ - const size_t align = 64; - char buf[align]; - size_t n; - - if (llen >= align) - return; - - n = align - llen; - memset(buf, ' ', n); - buf[n] = '\0'; - fputs(buf, stdout); -} - -enum RESULT { - OK, - FAIL, - SKIPPED, -}; - -static void result(int llen, enum RESULT r) -{ - const char *msg; - - if (r == OK) - msg = " [OK]"; - else if (r == SKIPPED) - msg = "[SKIPPED]"; - else - msg = " [FAIL]"; - - align_result(llen); - puts(msg); -} - -/* The tests below are intended to be used by the macroes, which evaluate - * expression , print the status to stdout, and update the "ret" - * variable to count failures. The functions themselves return the number - * of failures, thus either 0 or 1. - */ - -#define EXPECT_ZR(cond, expr) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_zr(expr, llen); } while (0) - -static __attribute__((unused)) -int expect_zr(int expr, int llen) -{ - int ret = !(expr == 0); - - llen += printf(" = %d ", expr); - result(llen, ret ? FAIL : OK); - return ret; -} - - -#define EXPECT_NZ(cond, expr, val) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_nz(expr, llen; } while (0) - -static __attribute__((unused)) -int expect_nz(int expr, int llen) -{ - int ret = !(expr != 0); - - llen += printf(" = %d ", expr); - result(llen, ret ? FAIL : OK); - return ret; -} - - -#define EXPECT_EQ(cond, expr, val) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_eq(expr, llen, val); } while (0) - -static __attribute__((unused)) -int expect_eq(uint64_t expr, int llen, uint64_t val) -{ - int ret = !(expr == val); - - llen += printf(" = %lld ", (long long)expr); - result(llen, ret ? FAIL : OK); - return ret; -} - - -#define EXPECT_NE(cond, expr, val) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ne(expr, llen, val); } while (0) - -static __attribute__((unused)) -int expect_ne(int expr, int llen, int val) -{ - int ret = !(expr != val); - - llen += printf(" = %d ", expr); - result(llen, ret ? FAIL : OK); - return ret; -} - - -#define EXPECT_GE(cond, expr, val) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ge(expr, llen, val); } while (0) - -static __attribute__((unused)) -int expect_ge(int expr, int llen, int val) -{ - int ret = !(expr >= val); - - llen += printf(" = %d ", expr); - result(llen, ret ? FAIL : OK); - return ret; -} - - -#define EXPECT_GT(cond, expr, val) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_gt(expr, llen, val); } while (0) - -static __attribute__((unused)) -int expect_gt(int expr, int llen, int val) -{ - int ret = !(expr > val); - - llen += printf(" = %d ", expr); - result(llen, ret ? FAIL : OK); - return ret; -} - - -#define EXPECT_LE(cond, expr, val) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_le(expr, llen, val); } while (0) - -static __attribute__((unused)) -int expect_le(int expr, int llen, int val) -{ - int ret = !(expr <= val); - - llen += printf(" = %d ", expr); - result(llen, ret ? FAIL : OK); - return ret; -} - - -#define EXPECT_LT(cond, expr, val) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_lt(expr, llen, val); } while (0) - -static __attribute__((unused)) -int expect_lt(int expr, int llen, int val) -{ - int ret = !(expr < val); - - llen += printf(" = %d ", expr); - result(llen, ret ? FAIL : OK); - return ret; -} - - -#define EXPECT_SYSZR(cond, expr) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_syszr(expr, llen); } while (0) - -static __attribute__((unused)) -int expect_syszr(int expr, int llen) -{ - int ret = 0; - - if (errno == ENOSYS) { - llen += printf(" = ENOSYS"); - result(llen, SKIPPED); - } else if (expr) { - ret = 1; - llen += printf(" = %d %s ", expr, errorname(errno)); - result(llen, FAIL); - } else { - llen += printf(" = %d ", expr); - result(llen, OK); - } - return ret; -} - - -#define EXPECT_SYSEQ(cond, expr, val) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_syseq(expr, llen, val); } while (0) - -static __attribute__((unused)) -int expect_syseq(int expr, int llen, int val) -{ - int ret = 0; - - if (expr != val) { - ret = 1; - llen += printf(" = %d %s ", expr, errorname(errno)); - result(llen, FAIL); - } else { - llen += printf(" = %d ", expr); - result(llen, OK); - } - return ret; -} - - -#define EXPECT_SYSNE(cond, expr, val) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_sysne(expr, llen, val); } while (0) - -static __attribute__((unused)) -int expect_sysne(int expr, int llen, int val) -{ - int ret = 0; - - if (errno == ENOSYS) { - llen += printf(" = ENOSYS"); - result(llen, SKIPPED); - } else if (expr == val) { - ret = 1; - llen += printf(" = %d %s ", expr, errorname(errno)); - result(llen, FAIL); - } else { - llen += printf(" = %d ", expr); - result(llen, OK); - } - return ret; -} - - -#define EXPECT_SYSER2(cond, expr, expret, experr1, experr2) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_syserr2(expr, expret, experr1, experr2, llen); } while (0) - -#define EXPECT_SYSER(cond, expr, expret, experr) \ - EXPECT_SYSER2(cond, expr, expret, experr, 0) - -static __attribute__((unused)) -int expect_syserr2(int expr, int expret, int experr1, int experr2, int llen) -{ - int ret = 0; - int _errno = errno; - - llen += printf(" = %d %s ", expr, errorname(_errno)); - if (errno == ENOSYS) { - result(llen, SKIPPED); - } else if (expr != expret || (_errno != experr1 && _errno != experr2)) { - ret = 1; - if (experr2 == 0) - llen += printf(" != (%d %s) ", expret, errorname(experr1)); - else - llen += printf(" != (%d %s %s) ", expret, errorname(experr1), errorname(experr2)); - result(llen, FAIL); - } else { - result(llen, OK); - } - return ret; -} - - -#define EXPECT_PTRZR(cond, expr) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrzr(expr, llen); } while (0) - -static __attribute__((unused)) -int expect_ptrzr(const void *expr, int llen) -{ - int ret = 0; - - llen += printf(" = <%p> ", expr); - if (expr) { - ret = 1; - result(llen, FAIL); - } else { - result(llen, OK); - } - return ret; -} - - -#define EXPECT_PTRNZ(cond, expr) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrnz(expr, llen); } while (0) - -static __attribute__((unused)) -int expect_ptrnz(const void *expr, int llen) -{ - int ret = 0; - - llen += printf(" = <%p> ", expr); - if (!expr) { - ret = 1; - result(llen, FAIL); - } else { - result(llen, OK); - } - return ret; -} - -#define EXPECT_PTREQ(cond, expr, cmp) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptreq(expr, llen, cmp); } while (0) - -static __attribute__((unused)) -int expect_ptreq(const void *expr, int llen, const void *cmp) -{ - int ret = 0; - - llen += printf(" = <%p> ", expr); - if (expr != cmp) { - ret = 1; - result(llen, FAIL); - } else { - result(llen, OK); - } - return ret; -} - -#define EXPECT_PTRNE(cond, expr, cmp) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrne(expr, llen, cmp); } while (0) - -static __attribute__((unused)) -int expect_ptrne(const void *expr, int llen, const void *cmp) -{ - int ret = 0; - - llen += printf(" = <%p> ", expr); - if (expr == cmp) { - ret = 1; - result(llen, FAIL); - } else { - result(llen, OK); - } - return ret; -} - -#define EXPECT_PTRGE(cond, expr, cmp) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrge(expr, llen, cmp); } while (0) - -static __attribute__((unused)) -int expect_ptrge(const void *expr, int llen, const void *cmp) -{ - int ret = !(expr >= cmp); - - llen += printf(" = <%p> ", expr); - result(llen, ret ? FAIL : OK); - return ret; -} - -#define EXPECT_PTRGT(cond, expr, cmp) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrgt(expr, llen, cmp); } while (0) - -static __attribute__((unused)) -int expect_ptrgt(const void *expr, int llen, const void *cmp) -{ - int ret = !(expr > cmp); - - llen += printf(" = <%p> ", expr); - result(llen, ret ? FAIL : OK); - return ret; -} - - -#define EXPECT_PTRLE(cond, expr, cmp) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrle(expr, llen, cmp); } while (0) - -static __attribute__((unused)) -int expect_ptrle(const void *expr, int llen, const void *cmp) -{ - int ret = !(expr <= cmp); - - llen += printf(" = <%p> ", expr); - result(llen, ret ? FAIL : OK); - return ret; -} - - -#define EXPECT_PTRLT(cond, expr, cmp) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrlt(expr, llen, cmp); } while (0) - -static __attribute__((unused)) -int expect_ptrlt(const void *expr, int llen, const void *cmp) -{ - int ret = !(expr < cmp); - - llen += printf(" = <%p> ", expr); - result(llen, ret ? FAIL : OK); - return ret; -} - -#define EXPECT_PTRER2(cond, expr, expret, experr1, experr2) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrerr2(expr, expret, experr1, experr2, llen); } while (0) - -#define EXPECT_PTRER(cond, expr, expret, experr) \ - EXPECT_PTRER2(cond, expr, expret, experr, 0) - -static __attribute__((unused)) -int expect_ptrerr2(const void *expr, const void *expret, int experr1, int experr2, int llen) -{ - int ret = 0; - int _errno = errno; - - llen += printf(" = <%p> %s ", expr, errorname(_errno)); - if (expr != expret || (_errno != experr1 && _errno != experr2)) { - ret = 1; - if (experr2 == 0) - llen += printf(" != (<%p> %s) ", expret, errorname(experr1)); - else - llen += printf(" != (<%p> %s %s) ", expret, errorname(experr1), errorname(experr2)); - result(llen, FAIL); - } else { - result(llen, OK); - } - return ret; -} - -#define EXPECT_STRZR(cond, expr) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_strzr(expr, llen); } while (0) - -static __attribute__((unused)) -int expect_strzr(const char *expr, int llen) -{ - int ret = 0; - - llen += printf(" = <%s> ", expr ? expr : "(null)"); - if (expr) { - ret = 1; - result(llen, FAIL); - } else { - result(llen, OK); - } - return ret; -} - - -#define EXPECT_STRNZ(cond, expr) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_strnz(expr, llen); } while (0) - -static __attribute__((unused)) -int expect_strnz(const char *expr, int llen) -{ - int ret = 0; - - llen += printf(" = <%s> ", expr ? expr : "(null)"); - if (!expr) { - ret = 1; - result(llen, FAIL); - } else { - result(llen, OK); - } - return ret; -} - - -#define EXPECT_STREQ(cond, expr, cmp) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_streq(expr, llen, cmp); } while (0) - -static __attribute__((unused)) -int expect_streq(const char *expr, int llen, const char *cmp) -{ - int ret = 0; - - llen += printf(" = <%s> ", expr); - if (strcmp(expr, cmp) != 0) { - ret = 1; - result(llen, FAIL); - } else { - result(llen, OK); - } - return ret; -} - - -#define EXPECT_STRNE(cond, expr, cmp) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_strne(expr, llen, cmp); } while (0) - -static __attribute__((unused)) -int expect_strne(const char *expr, int llen, const char *cmp) -{ - int ret = 0; - - llen += printf(" = <%s> ", expr); - if (strcmp(expr, cmp) == 0) { - ret = 1; - result(llen, FAIL); - } else { - result(llen, OK); - } - return ret; -} - -#define EXPECT_STRBUFEQ(cond, expr, buf, val, cmp) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_str_buf_eq(expr, buf, val, llen, cmp); } while (0) - -static __attribute__((unused)) -int expect_str_buf_eq(size_t expr, const char *buf, size_t val, int llen, const char *cmp) -{ - llen += printf(" = %lu <%s> ", (unsigned long)expr, buf); - if (strcmp(buf, cmp) != 0) { - result(llen, FAIL); - return 1; - } - if (expr != val) { - result(llen, FAIL); - return 1; - } - - result(llen, OK); - return 0; -} - -#define EXPECT_STRTOX(cond, func, input, base, expected, chars, expected_errno) \ - do { if (!(cond)) result(llen, SKIPPED); else ret += expect_strtox(llen, func, input, base, expected, chars, expected_errno); } while (0) - -static __attribute__((unused)) -int expect_strtox(int llen, void *func, const char *input, int base, intmax_t expected, int expected_chars, int expected_errno) -{ - char *endptr; - int actual_errno, actual_chars; - intmax_t r; - - errno = 0; - if (func == strtol) { - r = strtol(input, &endptr, base); - } else if (func == strtoul) { - r = strtoul(input, &endptr, base); - } else { - result(llen, FAIL); - return 1; - } - actual_errno = errno; - actual_chars = endptr - input; - - llen += printf(" %lld = %lld", (long long)expected, (long long)r); - if (r != expected) { - result(llen, FAIL); - return 1; - } - if (expected_chars == -1) { - if (*endptr != '\0') { - result(llen, FAIL); - return 1; - } - } else if (expected_chars != actual_chars) { - result(llen, FAIL); - return 1; - } - if (actual_errno != expected_errno) { - result(llen, FAIL); - return 1; - } - - result(llen, OK); - return 0; -} - -/* declare tests based on line numbers. There must be exactly one test per line. */ -#define CASE_TEST(name) \ - case __LINE__: llen += printf("%d %s", test, #name); - -/* constructors validate that they are executed in definition order */ -__attribute__((constructor)) -static void constructor1(void) -{ - constructor_test_value |= 1 << 0; -} - -__attribute__((constructor)) -static void constructor2(int argc, char **argv, char **envp) -{ - if (argc && argv && envp) - constructor_test_value |= 1 << 1; -} - -int run_startup(int min, int max) -{ - int test; - int ret = 0; - /* kernel at least passes HOME and TERM, shell passes more */ - int env_total = 2; - /* checking NULL for argv/argv0, environ and _auxv is not enough, let's compare with sbrk(0) or &end */ - extern char end; - char *brk = sbrk(0) != (void *)-1 ? sbrk(0) : &end; - /* differ from nolibc, both glibc and musl have no global _auxv */ - const unsigned long *test_auxv = (void *)-1; -#ifdef NOLIBC - test_auxv = _auxv; -#endif - - for (test = min; test >= 0 && test <= max; test++) { - int llen = 0; /* line length */ - - /* avoid leaving empty lines below, this will insert holes into - * test numbers. - */ - switch (test + __LINE__ + 1) { - CASE_TEST(argc); EXPECT_GE(1, test_argc, 1); break; - CASE_TEST(argv_addr); EXPECT_PTRGT(1, test_argv, brk); break; - CASE_TEST(argv_environ); EXPECT_PTRLT(1, test_argv, environ); break; - CASE_TEST(argv_total); EXPECT_EQ(1, environ - test_argv - 1, test_argc ?: 1); break; - CASE_TEST(argv0_addr); EXPECT_PTRGT(1, argv0, brk); break; - CASE_TEST(argv0_str); EXPECT_STRNZ(1, argv0 > brk ? argv0 : NULL); break; - CASE_TEST(argv0_len); EXPECT_GE(1, argv0 > brk ? strlen(argv0) : 0, 1); break; - CASE_TEST(environ_addr); EXPECT_PTRGT(1, environ, brk); break; - CASE_TEST(environ_envp); EXPECT_PTREQ(1, environ, test_envp); break; - CASE_TEST(environ_auxv); EXPECT_PTRLT(test_auxv != (void *)-1, environ, test_auxv); break; - CASE_TEST(environ_total); EXPECT_GE(test_auxv != (void *)-1, (void *)test_auxv - (void *)environ - 1, env_total); break; - CASE_TEST(environ_HOME); EXPECT_PTRNZ(1, getenv("HOME")); break; - CASE_TEST(auxv_addr); EXPECT_PTRGT(test_auxv != (void *)-1, test_auxv, brk); break; - CASE_TEST(auxv_AT_UID); EXPECT_EQ(1, getauxval(AT_UID), getuid()); break; - CASE_TEST(constructor); EXPECT_EQ(is_nolibc, constructor_test_value, 0x3); break; - CASE_TEST(linkage_errno); EXPECT_PTREQ(1, linkage_test_errno_addr(), &errno); break; - CASE_TEST(linkage_constr); EXPECT_EQ(1, linkage_test_constructor_test_value, 0x3); break; - case __LINE__: - return ret; /* must be last */ - /* note: do not set any defaults so as to permit holes above */ - } - } - return ret; -} - - -/* used by some syscall tests below */ -int test_getdents64(const char *dir) -{ - char buffer[4096]; - int fd, ret; - int err; - - ret = fd = open(dir, O_RDONLY | O_DIRECTORY, 0); - if (ret < 0) - return ret; - - ret = getdents64(fd, (void *)buffer, sizeof(buffer)); - err = errno; - close(fd); - - errno = err; - return ret; -} - -static int test_dirent(void) -{ - int comm = 0, cmdline = 0; - struct dirent dirent, *result; - DIR *dir; - int ret; - - dir = opendir("/proc/self"); - if (!dir) - return 1; - - while (1) { - errno = 0; - ret = readdir_r(dir, &dirent, &result); - if (ret != 0) - return 1; - if (!result) - break; - - if (strcmp(dirent.d_name, "comm") == 0) - comm++; - else if (strcmp(dirent.d_name, "cmdline") == 0) - cmdline++; - } - - if (errno) - return 1; - - ret = closedir(dir); - if (ret) - return 1; - - if (comm != 1 || cmdline != 1) - return 1; - - return 0; -} - -int test_getpagesize(void) -{ - int x = getpagesize(); - int c; - - if (x < 0) - return x; - -#if defined(__x86_64__) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) - /* - * x86 family is always 4K page. - */ - c = (x == 4096); -#elif defined(__aarch64__) - /* - * Linux aarch64 supports three values of page size: 4K, 16K, and 64K - * which are selected at kernel compilation time. - */ - c = (x == 4096 || x == (16 * 1024) || x == (64 * 1024)); -#else - /* - * Assuming other architectures must have at least 4K page. - */ - c = (x >= 4096); -#endif - - return !c; -} - -int test_fork(void) -{ - int status; - pid_t pid; - - /* flush the printf buffer to avoid child flush it */ - fflush(stdout); - fflush(stderr); - - pid = fork(); - - switch (pid) { - case -1: - return 1; - - case 0: - exit(123); - - default: - pid = waitpid(pid, &status, 0); - - return pid == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 123; - } -} - -int test_stat_timestamps(void) -{ - struct stat st; - - if (sizeof(st.st_atim.tv_sec) != sizeof(st.st_atime)) - return 1; - - if (stat("/proc/self/", &st) && stat(argv0, &st) && stat("/", &st)) - return 1; - - if (st.st_atim.tv_sec != st.st_atime || st.st_atim.tv_nsec > 1000000000) - return 1; - - if (st.st_mtim.tv_sec != st.st_mtime || st.st_mtim.tv_nsec > 1000000000) - return 1; - - if (st.st_ctim.tv_sec != st.st_ctime || st.st_ctim.tv_nsec > 1000000000) - return 1; - - return 0; -} - -int test_uname(void) -{ - struct utsname buf; - char osrelease[sizeof(buf.release)]; - ssize_t r; - int fd; - - memset(&buf.domainname, 'P', sizeof(buf.domainname)); - - if (uname(&buf)) - return 1; - - if (strncmp("Linux", buf.sysname, sizeof(buf.sysname))) - return 1; - - fd = open("/proc/sys/kernel/osrelease", O_RDONLY); - if (fd == -1) - return 1; - - r = read(fd, osrelease, sizeof(osrelease)); - if (r == -1) - return 1; - - close(fd); - - if (osrelease[r - 1] == '\n') - r--; - - /* Validate one of the later fields to ensure field sizes are correct */ - if (strncmp(osrelease, buf.release, r)) - return 1; - - /* Ensure the field domainname is set, it is missing from struct old_utsname */ - if (strnlen(buf.domainname, sizeof(buf.domainname)) == sizeof(buf.domainname)) - return 1; - - return 0; -} - -int test_mmap_munmap(void) -{ - int ret, fd, i, page_size; - void *mem; - size_t file_size, length; - off_t offset, pa_offset; - struct stat stat_buf; - const char * const files[] = { - "/dev/zero", - "/proc/1/exe", "/proc/self/exe", - argv0, - NULL - }; - - page_size = getpagesize(); - if (page_size < 0) - return 1; - - /* find a right file to mmap, existed and accessible */ - for (i = 0; files[i] != NULL; i++) { - ret = fd = open(files[i], O_RDONLY); - if (ret == -1) - continue; - else - break; - } - if (ret == -1) - return 1; - - ret = stat(files[i], &stat_buf); - if (ret == -1) - goto end; - - /* file size of the special /dev/zero is 0, let's assign one manually */ - if (i == 0) - file_size = 3*page_size; - else - file_size = stat_buf.st_size; - - offset = file_size - 1; - if (offset < 0) - offset = 0; - length = file_size - offset; - pa_offset = offset & ~(page_size - 1); - - mem = mmap(NULL, length + offset - pa_offset, PROT_READ, MAP_SHARED, fd, pa_offset); - if (mem == MAP_FAILED) { - ret = 1; - goto end; - } - - ret = munmap(mem, length + offset - pa_offset); - -end: - close(fd); - return !!ret; -} - -int test_pipe(void) -{ - const char *const msg = "hello, nolibc"; - int pipefd[2]; - char buf[32]; - size_t len; - - if (pipe(pipefd) == -1) - return 1; - - write(pipefd[1], msg, strlen(msg)); - close(pipefd[1]); - len = read(pipefd[0], buf, sizeof(buf)); - close(pipefd[0]); - - if (len != strlen(msg)) - return 1; - - return !!memcmp(buf, msg, len); -} - -int test_rlimit(void) -{ - struct rlimit rlim = { - .rlim_cur = 1 << 20, - .rlim_max = 1 << 21, - }; - int ret; - - ret = setrlimit(RLIMIT_CORE, &rlim); - if (ret) - return -1; - - rlim.rlim_cur = 0; - rlim.rlim_max = 0; - - ret = getrlimit(RLIMIT_CORE, &rlim); - if (ret) - return -1; - - if (rlim.rlim_cur != 1 << 20) - return -1; - if (rlim.rlim_max != 1 << 21) - return -1; - - return 0; -} - -int test_openat(void) -{ - int dev, null; - - dev = openat(AT_FDCWD, "/dev", O_DIRECTORY); - if (dev < 0) - return -1; - - null = openat(dev, "null", O_RDONLY); - close(dev); - if (null < 0) - return -1; - - close(null); - return 0; -} - -/* Run syscall tests between IDs and . - * Return 0 on success, non-zero on failure. - */ -int run_syscall(int min, int max) -{ - struct timeval tv; - struct timezone tz; - struct stat stat_buf; - int euid0; - int proc; - int test; - int tmp; - int ret = 0; - void *p1, *p2; - int has_gettid = 1; - int has_brk; - - /* indicates whether or not /proc is mounted */ - proc = stat("/proc", &stat_buf) == 0; - - /* this will be used to skip certain tests that can't be run unprivileged */ - euid0 = geteuid() == 0; - - /* from 2.30, glibc provides gettid() */ -#if defined(__GLIBC_MINOR__) && defined(__GLIBC__) - has_gettid = __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 30); -#endif - - /* on musl setting brk()/sbrk() always fails */ - has_brk = brk(0) == 0; - - for (test = min; test >= 0 && test <= max; test++) { - int llen = 0; /* line length */ - - /* avoid leaving empty lines below, this will insert holes into - * test numbers. - */ - switch (test + __LINE__ + 1) { - CASE_TEST(getpid); EXPECT_SYSNE(1, getpid(), -1); break; - CASE_TEST(getppid); EXPECT_SYSNE(1, getppid(), -1); break; - CASE_TEST(gettid); EXPECT_SYSNE(has_gettid, gettid(), -1); break; - CASE_TEST(getpgid_self); EXPECT_SYSNE(1, getpgid(0), -1); break; - CASE_TEST(getpgid_bad); EXPECT_SYSER(1, getpgid(-1), -1, ESRCH); break; - CASE_TEST(kill_0); EXPECT_SYSZR(1, kill(getpid(), 0)); break; - CASE_TEST(kill_CONT); EXPECT_SYSZR(1, kill(getpid(), 0)); break; - CASE_TEST(kill_BADPID); EXPECT_SYSER(1, kill(INT_MAX, 0), -1, ESRCH); break; - CASE_TEST(sbrk_0); EXPECT_PTRNE(has_brk, sbrk(0), (void *)-1); break; - CASE_TEST(sbrk); if ((p1 = p2 = sbrk(4096)) != (void *)-1) p2 = sbrk(-4096); EXPECT_SYSZR(has_brk, (p2 == (void *)-1) || p2 == p1); break; - CASE_TEST(brk); EXPECT_SYSZR(has_brk, brk(sbrk(0))); break; - CASE_TEST(chdir_root); EXPECT_SYSZR(1, chdir("/")); chdir(getenv("PWD")); break; - CASE_TEST(chdir_dot); EXPECT_SYSZR(1, chdir(".")); break; - CASE_TEST(chdir_blah); EXPECT_SYSER(1, chdir("/blah"), -1, ENOENT); break; - CASE_TEST(chmod_argv0); EXPECT_SYSZR(1, chmod(argv0, 0555)); break; - CASE_TEST(chmod_self); EXPECT_SYSER(proc, chmod("/proc/self", 0555), -1, EPERM); break; - CASE_TEST(chown_self); EXPECT_SYSER(proc, chown("/proc/self", 0, 0), -1, EPERM); break; - CASE_TEST(chroot_root); EXPECT_SYSZR(euid0, chroot("/")); break; - CASE_TEST(chroot_blah); EXPECT_SYSER(1, chroot("/proc/self/blah"), -1, ENOENT); break; - CASE_TEST(chroot_exe); EXPECT_SYSER(1, chroot(argv0), -1, ENOTDIR); break; - CASE_TEST(close_m1); EXPECT_SYSER(1, close(-1), -1, EBADF); break; - CASE_TEST(close_dup); EXPECT_SYSZR(1, close(dup(0))); break; - CASE_TEST(dup_0); tmp = dup(0); EXPECT_SYSNE(1, tmp, -1); close(tmp); break; - CASE_TEST(dup_m1); tmp = dup(-1); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break; - CASE_TEST(dup2_0); tmp = dup2(0, 100); EXPECT_SYSNE(1, tmp, -1); close(tmp); break; - CASE_TEST(dup2_m1); tmp = dup2(-1, 100); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break; - CASE_TEST(dup3_0); tmp = dup3(0, 100, 0); EXPECT_SYSNE(1, tmp, -1); close(tmp); break; - CASE_TEST(dup3_m1); tmp = dup3(-1, 100, 0); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break; - CASE_TEST(execve_root); EXPECT_SYSER(1, execve("/", (char*[]){ [0] = "/", [1] = NULL }, NULL), -1, EACCES); break; - CASE_TEST(fork); EXPECT_SYSZR(1, test_fork()); break; - CASE_TEST(getdents64_root); EXPECT_SYSNE(1, test_getdents64("/"), -1); break; - CASE_TEST(getdents64_null); EXPECT_SYSER(1, test_getdents64("/dev/null"), -1, ENOTDIR); break; - CASE_TEST(directories); EXPECT_SYSZR(proc, test_dirent()); break; - CASE_TEST(gettimeofday_tv); EXPECT_SYSZR(1, gettimeofday(&tv, NULL)); break; - CASE_TEST(gettimeofday_tv_tz);EXPECT_SYSZR(1, gettimeofday(&tv, &tz)); break; - CASE_TEST(getpagesize); EXPECT_SYSZR(1, test_getpagesize()); break; - CASE_TEST(ioctl_tiocinq); EXPECT_SYSZR(1, ioctl(0, TIOCINQ, &tmp)); break; - CASE_TEST(link_root1); EXPECT_SYSER(1, link("/", "/"), -1, EEXIST); break; - CASE_TEST(link_blah); EXPECT_SYSER(1, link("/proc/self/blah", "/blah"), -1, ENOENT); break; - CASE_TEST(link_dir); EXPECT_SYSER(euid0, link("/", "/blah"), -1, EPERM); break; - CASE_TEST(link_cross); EXPECT_SYSER(proc, link("/proc/self/cmdline", "/blah"), -1, EXDEV); break; - CASE_TEST(lseek_m1); EXPECT_SYSER(1, lseek(-1, 0, SEEK_SET), -1, EBADF); break; - CASE_TEST(lseek_0); EXPECT_SYSER(1, lseek(0, 0, SEEK_SET), -1, ESPIPE); break; - CASE_TEST(mkdir_root); EXPECT_SYSER(1, mkdir("/", 0755), -1, EEXIST); break; - CASE_TEST(mmap_bad); EXPECT_PTRER(1, mmap(NULL, 0, PROT_READ, MAP_PRIVATE, 0, 0), MAP_FAILED, EINVAL); break; - CASE_TEST(munmap_bad); EXPECT_SYSER(1, munmap(NULL, 0), -1, EINVAL); break; - CASE_TEST(mmap_munmap_good); EXPECT_SYSZR(1, test_mmap_munmap()); break; - CASE_TEST(open_tty); EXPECT_SYSNE(1, tmp = open("/dev/null", O_RDONLY), -1); if (tmp != -1) close(tmp); break; - CASE_TEST(open_blah); EXPECT_SYSER(1, tmp = open("/proc/self/blah", O_RDONLY), -1, ENOENT); if (tmp != -1) close(tmp); break; - CASE_TEST(openat_dir); EXPECT_SYSZR(1, test_openat()); break; - CASE_TEST(pipe); EXPECT_SYSZR(1, test_pipe()); break; - CASE_TEST(poll_null); EXPECT_SYSZR(1, poll(NULL, 0, 0)); break; - CASE_TEST(poll_stdout); EXPECT_SYSNE(1, ({ struct pollfd fds = { 1, POLLOUT, 0}; poll(&fds, 1, 0); }), -1); break; - CASE_TEST(poll_fault); EXPECT_SYSER(1, poll(NULL, 1, 0), -1, EFAULT); break; - CASE_TEST(prctl); EXPECT_SYSER(1, prctl(PR_SET_NAME, (unsigned long)NULL, 0, 0, 0), -1, EFAULT); break; - CASE_TEST(read_badf); EXPECT_SYSER(1, read(-1, &tmp, 1), -1, EBADF); break; - CASE_TEST(rlimit); EXPECT_SYSZR(1, test_rlimit()); break; - CASE_TEST(rmdir_blah); EXPECT_SYSER(1, rmdir("/blah"), -1, ENOENT); break; - CASE_TEST(sched_yield); EXPECT_SYSZR(1, sched_yield()); break; - CASE_TEST(select_null); EXPECT_SYSZR(1, ({ struct timeval tv = { 0 }; select(0, NULL, NULL, NULL, &tv); })); break; - CASE_TEST(select_stdout); EXPECT_SYSNE(1, ({ fd_set fds; FD_ZERO(&fds); FD_SET(1, &fds); select(2, NULL, &fds, NULL, NULL); }), -1); break; - CASE_TEST(select_fault); EXPECT_SYSER(1, select(1, (void *)1, NULL, NULL, 0), -1, EFAULT); break; - CASE_TEST(stat_blah); EXPECT_SYSER(1, stat("/proc/self/blah", &stat_buf), -1, ENOENT); break; - CASE_TEST(stat_fault); EXPECT_SYSER(1, stat(NULL, &stat_buf), -1, EFAULT); break; - CASE_TEST(stat_timestamps); EXPECT_SYSZR(1, test_stat_timestamps()); break; - CASE_TEST(symlink_root); EXPECT_SYSER(1, symlink("/", "/"), -1, EEXIST); break; - CASE_TEST(uname); EXPECT_SYSZR(proc, test_uname()); break; - CASE_TEST(uname_fault); EXPECT_SYSER(1, uname(NULL), -1, EFAULT); break; - CASE_TEST(unlink_root); EXPECT_SYSER(1, unlink("/"), -1, EISDIR); break; - CASE_TEST(unlink_blah); EXPECT_SYSER(1, unlink("/proc/self/blah"), -1, ENOENT); break; - CASE_TEST(wait_child); EXPECT_SYSER(1, wait(&tmp), -1, ECHILD); break; - CASE_TEST(waitpid_min); EXPECT_SYSER(1, waitpid(INT_MIN, &tmp, WNOHANG), -1, ESRCH); break; - CASE_TEST(waitpid_child); EXPECT_SYSER(1, waitpid(getpid(), &tmp, WNOHANG), -1, ECHILD); break; - CASE_TEST(write_badf); EXPECT_SYSER(1, write(-1, &tmp, 1), -1, EBADF); break; - CASE_TEST(write_zero); EXPECT_SYSZR(1, write(1, &tmp, 0)); break; - CASE_TEST(syscall_noargs); EXPECT_SYSEQ(1, syscall(__NR_getpid), getpid()); break; - CASE_TEST(syscall_args); EXPECT_SYSER(1, syscall(__NR_statx, 0, NULL, 0, 0, NULL), -1, EFAULT); break; - case __LINE__: - return ret; /* must be last */ - /* note: do not set any defaults so as to permit holes above */ - } - } - return ret; -} - -int run_stdlib(int min, int max) -{ - int test; - int ret = 0; - - for (test = min; test >= 0 && test <= max; test++) { - int llen = 0; /* line length */ - - /* For functions that take a long buffer, like strlcat() - * Add some more chars after the \0, to test functions that overwrite the buffer set - * the \0 at the exact right position. - */ - char buf[10] = "test123456"; - buf[4] = '\0'; - - - /* avoid leaving empty lines below, this will insert holes into - * test numbers. - */ - switch (test + __LINE__ + 1) { - CASE_TEST(getenv_TERM); EXPECT_STRNZ(1, getenv("TERM")); break; - CASE_TEST(getenv_blah); EXPECT_STRZR(1, getenv("blah")); break; - CASE_TEST(setcmp_blah_blah); EXPECT_EQ(1, strcmp("blah", "blah"), 0); break; - CASE_TEST(setcmp_blah_blah2); EXPECT_NE(1, strcmp("blah", "blah2"), 0); break; - CASE_TEST(setncmp_blah_blah); EXPECT_EQ(1, strncmp("blah", "blah", 10), 0); break; - CASE_TEST(setncmp_blah_blah4); EXPECT_EQ(1, strncmp("blah", "blah4", 4), 0); break; - CASE_TEST(setncmp_blah_blah5); EXPECT_NE(1, strncmp("blah", "blah5", 5), 0); break; - CASE_TEST(setncmp_blah_blah6); EXPECT_NE(1, strncmp("blah", "blah6", 6), 0); break; - CASE_TEST(strchr_foobar_o); EXPECT_STREQ(1, strchr("foobar", 'o'), "oobar"); break; - CASE_TEST(strchr_foobar_z); EXPECT_STRZR(1, strchr("foobar", 'z')); break; - CASE_TEST(strrchr_foobar_o); EXPECT_STREQ(1, strrchr("foobar", 'o'), "obar"); break; - CASE_TEST(strrchr_foobar_z); EXPECT_STRZR(1, strrchr("foobar", 'z')); break; - CASE_TEST(strlcat_0); EXPECT_STRBUFEQ(is_nolibc, strlcat(buf, "bar", 0), buf, 3, "test"); break; - CASE_TEST(strlcat_1); EXPECT_STRBUFEQ(is_nolibc, strlcat(buf, "bar", 1), buf, 4, "test"); break; - CASE_TEST(strlcat_5); EXPECT_STRBUFEQ(is_nolibc, strlcat(buf, "bar", 5), buf, 7, "test"); break; - CASE_TEST(strlcat_6); EXPECT_STRBUFEQ(is_nolibc, strlcat(buf, "bar", 6), buf, 7, "testb"); break; - CASE_TEST(strlcat_7); EXPECT_STRBUFEQ(is_nolibc, strlcat(buf, "bar", 7), buf, 7, "testba"); break; - CASE_TEST(strlcat_8); EXPECT_STRBUFEQ(is_nolibc, strlcat(buf, "bar", 8), buf, 7, "testbar"); break; - CASE_TEST(strlcpy_0); EXPECT_STRBUFEQ(is_nolibc, strlcpy(buf, "bar", 0), buf, 3, "test"); break; - CASE_TEST(strlcpy_1); EXPECT_STRBUFEQ(is_nolibc, strlcpy(buf, "bar", 1), buf, 3, ""); break; - CASE_TEST(strlcpy_2); EXPECT_STRBUFEQ(is_nolibc, strlcpy(buf, "bar", 2), buf, 3, "b"); break; - CASE_TEST(strlcpy_3); EXPECT_STRBUFEQ(is_nolibc, strlcpy(buf, "bar", 3), buf, 3, "ba"); break; - CASE_TEST(strlcpy_4); EXPECT_STRBUFEQ(is_nolibc, strlcpy(buf, "bar", 4), buf, 3, "bar"); break; - CASE_TEST(memcmp_20_20); EXPECT_EQ(1, memcmp("aaa\x20", "aaa\x20", 4), 0); break; - CASE_TEST(memcmp_20_60); EXPECT_LT(1, memcmp("aaa\x20", "aaa\x60", 4), 0); break; - CASE_TEST(memcmp_60_20); EXPECT_GT(1, memcmp("aaa\x60", "aaa\x20", 4), 0); break; - CASE_TEST(memcmp_20_e0); EXPECT_LT(1, memcmp("aaa\x20", "aaa\xe0", 4), 0); break; - CASE_TEST(memcmp_e0_20); EXPECT_GT(1, memcmp("aaa\xe0", "aaa\x20", 4), 0); break; - CASE_TEST(memcmp_80_e0); EXPECT_LT(1, memcmp("aaa\x80", "aaa\xe0", 4), 0); break; - CASE_TEST(memcmp_e0_80); EXPECT_GT(1, memcmp("aaa\xe0", "aaa\x80", 4), 0); break; - CASE_TEST(limit_int8_max); EXPECT_EQ(1, INT8_MAX, (int8_t) 0x7f); break; - CASE_TEST(limit_int8_min); EXPECT_EQ(1, INT8_MIN, (int8_t) 0x80); break; - CASE_TEST(limit_uint8_max); EXPECT_EQ(1, UINT8_MAX, (uint8_t) 0xff); break; - CASE_TEST(limit_int16_max); EXPECT_EQ(1, INT16_MAX, (int16_t) 0x7fff); break; - CASE_TEST(limit_int16_min); EXPECT_EQ(1, INT16_MIN, (int16_t) 0x8000); break; - CASE_TEST(limit_uint16_max); EXPECT_EQ(1, UINT16_MAX, (uint16_t) 0xffff); break; - CASE_TEST(limit_int32_max); EXPECT_EQ(1, INT32_MAX, (int32_t) 0x7fffffff); break; - CASE_TEST(limit_int32_min); EXPECT_EQ(1, INT32_MIN, (int32_t) 0x80000000); break; - CASE_TEST(limit_uint32_max); EXPECT_EQ(1, UINT32_MAX, (uint32_t) 0xffffffff); break; - CASE_TEST(limit_int64_max); EXPECT_EQ(1, INT64_MAX, (int64_t) 0x7fffffffffffffff); break; - CASE_TEST(limit_int64_min); EXPECT_EQ(1, INT64_MIN, (int64_t) 0x8000000000000000); break; - CASE_TEST(limit_uint64_max); EXPECT_EQ(1, UINT64_MAX, (uint64_t) 0xffffffffffffffff); break; - CASE_TEST(limit_int_least8_max); EXPECT_EQ(1, INT_LEAST8_MAX, (int_least8_t) 0x7f); break; - CASE_TEST(limit_int_least8_min); EXPECT_EQ(1, INT_LEAST8_MIN, (int_least8_t) 0x80); break; - CASE_TEST(limit_uint_least8_max); EXPECT_EQ(1, UINT_LEAST8_MAX, (uint_least8_t) 0xff); break; - CASE_TEST(limit_int_least16_max); EXPECT_EQ(1, INT_LEAST16_MAX, (int_least16_t) 0x7fff); break; - CASE_TEST(limit_int_least16_min); EXPECT_EQ(1, INT_LEAST16_MIN, (int_least16_t) 0x8000); break; - CASE_TEST(limit_uint_least16_max); EXPECT_EQ(1, UINT_LEAST16_MAX, (uint_least16_t) 0xffff); break; - CASE_TEST(limit_int_least32_max); EXPECT_EQ(1, INT_LEAST32_MAX, (int_least32_t) 0x7fffffff); break; - CASE_TEST(limit_int_least32_min); EXPECT_EQ(1, INT_LEAST32_MIN, (int_least32_t) 0x80000000); break; - CASE_TEST(limit_uint_least32_max); EXPECT_EQ(1, UINT_LEAST32_MAX, (uint_least32_t) 0xffffffffU); break; - CASE_TEST(limit_int_least64_min); EXPECT_EQ(1, INT_LEAST64_MIN, (int_least64_t) 0x8000000000000000LL); break; - CASE_TEST(limit_int_least64_max); EXPECT_EQ(1, INT_LEAST64_MAX, (int_least64_t) 0x7fffffffffffffffLL); break; - CASE_TEST(limit_uint_least64_max); EXPECT_EQ(1, UINT_LEAST64_MAX, (uint_least64_t) 0xffffffffffffffffULL); break; - CASE_TEST(limit_int_fast8_max); EXPECT_EQ(1, INT_FAST8_MAX, (int_fast8_t) 0x7f); break; - CASE_TEST(limit_int_fast8_min); EXPECT_EQ(1, INT_FAST8_MIN, (int_fast8_t) 0x80); break; - CASE_TEST(limit_uint_fast8_max); EXPECT_EQ(1, UINT_FAST8_MAX, (uint_fast8_t) 0xff); break; - CASE_TEST(limit_int_fast16_min); EXPECT_EQ(1, INT_FAST16_MIN, (int_fast16_t) SINT_MIN_OF_TYPE(int_fast16_t)); break; - CASE_TEST(limit_int_fast16_max); EXPECT_EQ(1, INT_FAST16_MAX, (int_fast16_t) SINT_MAX_OF_TYPE(int_fast16_t)); break; - CASE_TEST(limit_uint_fast16_max); EXPECT_EQ(1, UINT_FAST16_MAX, (uint_fast16_t) UINTPTR_MAX); break; - CASE_TEST(limit_int_fast32_min); EXPECT_EQ(1, INT_FAST32_MIN, (int_fast32_t) SINT_MIN_OF_TYPE(int_fast32_t)); break; - CASE_TEST(limit_int_fast32_max); EXPECT_EQ(1, INT_FAST32_MAX, (int_fast32_t) SINT_MAX_OF_TYPE(int_fast32_t)); break; - CASE_TEST(limit_uint_fast32_max); EXPECT_EQ(1, UINT_FAST32_MAX, (uint_fast32_t) UINTPTR_MAX); break; - CASE_TEST(limit_int_fast64_min); EXPECT_EQ(1, INT_FAST64_MIN, (int_fast64_t) INT64_MIN); break; - CASE_TEST(limit_int_fast64_max); EXPECT_EQ(1, INT_FAST64_MAX, (int_fast64_t) INT64_MAX); break; - CASE_TEST(limit_uint_fast64_max); EXPECT_EQ(1, UINT_FAST64_MAX, (uint_fast64_t) UINT64_MAX); break; - CASE_TEST(sizeof_long_sane); EXPECT_EQ(1, sizeof(long) == 8 || sizeof(long) == 4, 1); break; - CASE_TEST(limit_intptr_min); EXPECT_EQ(1, INTPTR_MIN, sizeof(long) == 8 ? (intptr_t) 0x8000000000000000LL : (intptr_t) 0x80000000); break; - CASE_TEST(limit_intptr_max); EXPECT_EQ(1, INTPTR_MAX, sizeof(long) == 8 ? (intptr_t) 0x7fffffffffffffffLL : (intptr_t) 0x7fffffff); break; - CASE_TEST(limit_uintptr_max); EXPECT_EQ(1, UINTPTR_MAX, sizeof(long) == 8 ? (uintptr_t) 0xffffffffffffffffULL : (uintptr_t) 0xffffffffU); break; - CASE_TEST(limit_ptrdiff_min); EXPECT_EQ(1, PTRDIFF_MIN, sizeof(long) == 8 ? (ptrdiff_t) 0x8000000000000000LL : (ptrdiff_t) 0x80000000); break; - CASE_TEST(limit_ptrdiff_max); EXPECT_EQ(1, PTRDIFF_MAX, sizeof(long) == 8 ? (ptrdiff_t) 0x7fffffffffffffffLL : (ptrdiff_t) 0x7fffffff); break; - CASE_TEST(limit_size_max); EXPECT_EQ(1, SIZE_MAX, sizeof(long) == 8 ? (size_t) 0xffffffffffffffffULL : (size_t) 0xffffffffU); break; - CASE_TEST(strtol_simple); EXPECT_STRTOX(1, strtol, "35", 10, 35, -1, 0); break; - CASE_TEST(strtol_positive); EXPECT_STRTOX(1, strtol, "+35", 10, 35, -1, 0); break; - CASE_TEST(strtol_negative); EXPECT_STRTOX(1, strtol, "-35", 10, -35, -1, 0); break; - CASE_TEST(strtol_hex_auto); EXPECT_STRTOX(1, strtol, "0xFF", 0, 255, -1, 0); break; - CASE_TEST(strtol_base36); EXPECT_STRTOX(1, strtol, "12yZ", 36, 50507, -1, 0); break; - CASE_TEST(strtol_cutoff); EXPECT_STRTOX(1, strtol, "1234567890", 8, 342391, 7, 0); break; - CASE_TEST(strtol_octal_auto); EXPECT_STRTOX(1, strtol, "011", 0, 9, -1, 0); break; - CASE_TEST(strtol_hex_00); EXPECT_STRTOX(1, strtol, "0x00", 16, 0, -1, 0); break; - CASE_TEST(strtol_hex_FF); EXPECT_STRTOX(1, strtol, "FF", 16, 255, -1, 0); break; - CASE_TEST(strtol_hex_ff); EXPECT_STRTOX(1, strtol, "ff", 16, 255, -1, 0); break; - CASE_TEST(strtol_hex_prefix); EXPECT_STRTOX(1, strtol, "0xFF", 16, 255, -1, 0); break; - CASE_TEST(strtol_trailer); EXPECT_STRTOX(1, strtol, "35foo", 10, 35, 2, 0); break; - CASE_TEST(strtol_overflow); EXPECT_STRTOX(1, strtol, "0x8000000000000000", 16, LONG_MAX, -1, ERANGE); break; - CASE_TEST(strtol_underflow); EXPECT_STRTOX(1, strtol, "-0x8000000000000001", 16, LONG_MIN, -1, ERANGE); break; - CASE_TEST(strtoul_negative); EXPECT_STRTOX(1, strtoul, "-0x1", 16, ULONG_MAX, 4, 0); break; - CASE_TEST(strtoul_overflow); EXPECT_STRTOX(1, strtoul, "0x10000000000000000", 16, ULONG_MAX, -1, ERANGE); break; - CASE_TEST(strerror_success); EXPECT_STREQ(is_nolibc, strerror(0), "errno=0"); break; - CASE_TEST(strerror_EINVAL); EXPECT_STREQ(is_nolibc, strerror(EINVAL), "errno=22"); break; - CASE_TEST(strerror_int_max); EXPECT_STREQ(is_nolibc, strerror(INT_MAX), "errno=2147483647"); break; - CASE_TEST(strerror_int_min); EXPECT_STREQ(is_nolibc, strerror(INT_MIN), "errno=-2147483648"); break; - CASE_TEST(tolower); EXPECT_EQ(1, tolower('A'), 'a'); break; - CASE_TEST(tolower_noop); EXPECT_EQ(1, tolower('a'), 'a'); break; - CASE_TEST(toupper); EXPECT_EQ(1, toupper('a'), 'A'); break; - CASE_TEST(toupper_noop); EXPECT_EQ(1, toupper('A'), 'A'); break; - - case __LINE__: - return ret; /* must be last */ - /* note: do not set any defaults so as to permit holes above */ - } - } - return ret; -} - -#define EXPECT_VFPRINTF(c, expected, fmt, ...) \ - ret += expect_vfprintf(llen, c, expected, fmt, ##__VA_ARGS__) - -static int expect_vfprintf(int llen, int c, const char *expected, const char *fmt, ...) -{ - char buf[100]; - va_list args; - ssize_t w; - int ret; - - - va_start(args, fmt); - /* Only allow writing 21 bytes, to test truncation */ - w = vsnprintf(buf, 21, fmt, args); - va_end(args); - - if (w != c) { - llen += printf(" written(%d) != %d", (int)w, c); - result(llen, FAIL); - return 1; - } - - llen += printf(" \"%s\" = \"%s\"", expected, buf); - ret = strncmp(expected, buf, c); - - result(llen, ret ? FAIL : OK); - return ret; -} - -static int test_scanf(void) -{ - unsigned long long ull; - unsigned long ul; - unsigned int u; - long long ll; - long l; - void *p; - int i; - - /* return __LINE__ to point to the specific failure */ - - /* test EOF */ - if (sscanf("", "foo") != EOF) - return __LINE__; - - /* test simple literal without placeholder */ - if (sscanf("foo", "foo") != 0) - return __LINE__; - - /* test single placeholder */ - if (sscanf("123", "%d", &i) != 1) - return __LINE__; - - if (i != 123) - return __LINE__; - - /* test multiple place holders and separators */ - if (sscanf("a123b456c0x90", "a%db%uc%p", &i, &u, &p) != 3) - return __LINE__; - - if (i != 123) - return __LINE__; - - if (u != 456) - return __LINE__; - - if (p != (void *)0x90) - return __LINE__; - - /* test space handling */ - if (sscanf("a b1", "a b%d", &i) != 1) - return __LINE__; - - if (i != 1) - return __LINE__; - - /* test literal percent */ - if (sscanf("a%1", "a%%%d", &i) != 1) - return __LINE__; - - if (i != 1) - return __LINE__; - - /* test stdint.h types */ - if (sscanf("1|2|3|4|5|6", - "%d|%ld|%lld|%u|%lu|%llu", - &i, &l, &ll, &u, &ul, &ull) != 6) - return __LINE__; - - if (i != 1 || l != 2 || ll != 3 || - u != 4 || ul != 5 || ull != 6) - return __LINE__; - - return 0; -} - -static int run_printf(int min, int max) -{ - int test; - int ret = 0; - - for (test = min; test >= 0 && test <= max; test++) { - int llen = 0; /* line length */ - - /* avoid leaving empty lines below, this will insert holes into - * test numbers. - */ - switch (test + __LINE__ + 1) { - CASE_TEST(empty); EXPECT_VFPRINTF(0, "", ""); break; - CASE_TEST(simple); EXPECT_VFPRINTF(3, "foo", "foo"); break; - CASE_TEST(string); EXPECT_VFPRINTF(3, "foo", "%s", "foo"); break; - CASE_TEST(number); EXPECT_VFPRINTF(4, "1234", "%d", 1234); break; - CASE_TEST(negnumber); EXPECT_VFPRINTF(5, "-1234", "%d", -1234); break; - CASE_TEST(unsigned); EXPECT_VFPRINTF(5, "12345", "%u", 12345); break; - CASE_TEST(char); EXPECT_VFPRINTF(1, "c", "%c", 'c'); break; - CASE_TEST(hex); EXPECT_VFPRINTF(1, "f", "%x", 0xf); break; - CASE_TEST(pointer); EXPECT_VFPRINTF(3, "0x1", "%p", (void *) 0x1); break; - CASE_TEST(uintmax_t); EXPECT_VFPRINTF(20, "18446744073709551615", "%ju", 0xffffffffffffffffULL); break; - CASE_TEST(intmax_t); EXPECT_VFPRINTF(20, "-9223372036854775807", "%jd", 0x8000000000000001LL); break; - CASE_TEST(truncation); EXPECT_VFPRINTF(25, "01234567890123456789", "%s", "0123456789012345678901234"); break; - CASE_TEST(string_width); EXPECT_VFPRINTF(10, " 1", "%10s", "1"); break; - CASE_TEST(number_width); EXPECT_VFPRINTF(10, " 1", "%10d", 1); break; - CASE_TEST(width_trunc); EXPECT_VFPRINTF(25, " ", "%25d", 1); break; - CASE_TEST(scanf); EXPECT_ZR(1, test_scanf()); break; - case __LINE__: - return ret; /* must be last */ - /* note: do not set any defaults so as to permit holes above */ - } - } - return ret; -} - -__attribute__((no_sanitize("undefined"))) -static int smash_stack(void) -{ - char buf[100]; - volatile char *ptr = buf; - size_t i; - - for (i = 0; i < 200; i++) - ptr[i] = 'P'; - - return 1; -} - -static int run_protection(int min __attribute__((unused)), - int max __attribute__((unused))) -{ - pid_t pid; - int llen = 0, status; - struct rlimit rlimit = { 0, 0 }; - - llen += printf("0 -fstackprotector "); - -#if !defined(_NOLIBC_STACKPROTECTOR) - llen += printf("not supported"); - result(llen, SKIPPED); - return 0; -#endif - -#if defined(_NOLIBC_STACKPROTECTOR) - if (!__stack_chk_guard) { - llen += printf("__stack_chk_guard not initialized"); - result(llen, FAIL); - return 1; - } -#endif - - pid = -1; - pid = fork(); - - switch (pid) { - case -1: - llen += printf("fork()"); - result(llen, FAIL); - return 1; - - case 0: - close(STDOUT_FILENO); - close(STDERR_FILENO); - - prctl(PR_SET_DUMPABLE, 0, 0, 0, 0); - setrlimit(RLIMIT_CORE, &rlimit); - smash_stack(); - return 1; - - default: - pid = waitpid(pid, &status, 0); - - if (pid == -1 || !WIFSIGNALED(status) || WTERMSIG(status) != SIGABRT) { - llen += printf("waitpid()"); - result(llen, FAIL); - return 1; - } - result(llen, OK); - return 0; - } -} - -/* prepare what needs to be prepared for pid 1 (stdio, /dev, /proc, etc) */ -int prepare(void) -{ - struct stat stat_buf; - - /* It's possible that /dev doesn't even exist or was not mounted, so - * we'll try to create it, mount it, or create minimal entries into it. - * We want at least /dev/null and /dev/console. - */ - if (stat("/dev/.", &stat_buf) == 0 || mkdir("/dev", 0755) == 0) { - if (stat("/dev/console", &stat_buf) != 0 || - stat("/dev/null", &stat_buf) != 0 || - stat("/dev/zero", &stat_buf) != 0) { - /* try devtmpfs first, otherwise fall back to manual creation */ - if (mount("/dev", "/dev", "devtmpfs", 0, 0) != 0) { - mknod("/dev/console", 0600 | S_IFCHR, makedev(5, 1)); - mknod("/dev/null", 0666 | S_IFCHR, makedev(1, 3)); - mknod("/dev/zero", 0666 | S_IFCHR, makedev(1, 5)); - } - } - } - - /* If no /dev/console was found before calling init, stdio is closed so - * we need to reopen it from /dev/console. If it failed above, it will - * still fail here and we cannot emit a message anyway. - */ - if (close(dup(1)) == -1) { - int fd = open("/dev/console", O_RDWR); - - if (fd >= 0) { - if (fd != 0) - dup2(fd, 0); - if (fd != 1) - dup2(fd, 1); - if (fd != 2) - dup2(fd, 2); - if (fd > 2) - close(fd); - puts("\nSuccessfully reopened /dev/console."); - } - } - - /* try to mount /proc if not mounted. Silently fail otherwise */ - if (stat("/proc/.", &stat_buf) == 0 || mkdir("/proc", 0755) == 0) { - if (stat("/proc/self", &stat_buf) != 0) { - /* If not mountable, remove /proc completely to avoid misuse */ - if (mount("none", "/proc", "proc", 0, 0) != 0) - rmdir("/proc"); - } - } - - /* some tests rely on a writable /tmp */ - mkdir("/tmp", 0755); - - return 0; -} - -/* This is the definition of known test names, with their functions */ -static const struct test test_names[] = { - /* add new tests here */ - { .name = "startup", .func = run_startup }, - { .name = "syscall", .func = run_syscall }, - { .name = "stdlib", .func = run_stdlib }, - { .name = "printf", .func = run_printf }, - { .name = "protection", .func = run_protection }, - { 0 } -}; - -static int is_setting_valid(char *test) -{ - int idx, len, test_len, valid = 0; - char delimiter; - - if (!test) - return valid; - - test_len = strlen(test); - - for (idx = 0; test_names[idx].name; idx++) { - len = strlen(test_names[idx].name); - if (test_len < len) - continue; - - if (strncmp(test, test_names[idx].name, len) != 0) - continue; - - delimiter = test[len]; - if (delimiter != ':' && delimiter != ',' && delimiter != '\0') - continue; - - valid = 1; - break; - } - - return valid; -} - -int main(int argc, char **argv, char **envp) -{ - int min = 0; - int max = INT_MAX; - int ret = 0; - int err; - int idx; - char *test; - - argv0 = argv[0]; - test_argc = argc; - test_argv = argv; - test_envp = envp; - - /* when called as init, it's possible that no console was opened, for - * example if no /dev file system was provided. We'll check that fd#1 - * was opened, and if not we'll attempt to create and open /dev/console - * and /dev/null that we'll use for later tests. - */ - if (getpid() == 1) - prepare(); - - /* the definition of a series of tests comes from either argv[1] or the - * "NOLIBC_TEST" environment variable. It's made of a comma-delimited - * series of test names and optional ranges: - * syscall:5-15[:.*],stdlib:8-10 - */ - test = argv[1]; - if (!is_setting_valid(test)) - test = getenv("NOLIBC_TEST"); - - if (is_setting_valid(test)) { - char *comma, *colon, *dash, *value; - - do { - comma = strchr(test, ','); - if (comma) - *(comma++) = '\0'; - - colon = strchr(test, ':'); - if (colon) - *(colon++) = '\0'; - - for (idx = 0; test_names[idx].name; idx++) { - if (strcmp(test, test_names[idx].name) == 0) - break; - } - - if (test_names[idx].name) { - /* The test was named, it will be called at least - * once. We may have an optional range at - * here, which defaults to the full range. - */ - do { - min = 0; max = INT_MAX; - value = colon; - if (value && *value) { - colon = strchr(value, ':'); - if (colon) - *(colon++) = '\0'; - - dash = strchr(value, '-'); - if (dash) - *(dash++) = '\0'; - - /* support :val: :min-max: :min-: :-max: */ - if (*value) - min = atoi(value); - if (!dash) - max = min; - else if (*dash) - max = atoi(dash); - - value = colon; - } - - /* now's time to call the test */ - printf("Running test '%s'\n", test_names[idx].name); - err = test_names[idx].func(min, max); - ret += err; - printf("Errors during this test: %d\n\n", err); - } while (colon && *colon); - } else - printf("Ignoring unknown test name '%s'\n", test); - - test = comma; - } while (test && *test); - } else { - /* no test mentioned, run everything */ - for (idx = 0; test_names[idx].name; idx++) { - printf("Running test '%s'\n", test_names[idx].name); - err = test_names[idx].func(min, max); - ret += err; - printf("Errors during this test: %d\n\n", err); - } - } - - printf("Total number of errors: %d\n", ret); - - if (getpid() == 1) { - /* we're running as init, there's no other process on the - * system, thus likely started from a VM for a quick check. - * Exiting will provoke a kernel panic that may be reported - * as an error by Qemu or the hypervisor, while stopping - * cleanly will often be reported as a success. This allows - * to use the output of this program for bisecting kernels. - */ - printf("Leaving init with final status: %d\n", !!ret); - if (ret == 0) - reboot(RB_POWER_OFF); -#if defined(__x86_64__) - /* QEMU started with "-device isa-debug-exit -no-reboot" will - * exit with status code 2N+1 when N is written to 0x501. We - * hard-code the syscall here as it's arch-dependent. - */ - else if (syscall(__NR_ioperm, 0x501, 1, 1) == 0) - __asm__ volatile ("outb %%al, %%dx" :: "d"(0x501), "a"(0)); - /* if it does nothing, fall back to the regular panic */ -#endif - } - - printf("Exiting with status %d\n", !!ret); - return !!ret; -} +#include "harness-selftest.c" diff --git a/tools/testing/selftests/nolibc/run-tests.sh b/tools/testing/selftests/nolibc/run-tests.sh index 8277599e6441a933d9c1ec5003acf49b06df226f..8ac447e8547c2aa67615a4dc8a37fa4d853ce92a 100755 --- a/tools/testing/selftests/nolibc/run-tests.sh +++ b/tools/testing/selftests/nolibc/run-tests.sh @@ -196,7 +196,7 @@ test_arch() { swallow_output "${MAKE[@]}" defconfig swallow_output "${MAKE[@]}" CFLAGS_EXTRA="$CFLAGS_EXTRA" "$test_target" V=1 cp run.out run.out."${arch}" - "${MAKE[@]}" report | grep passed + "${MAKE[@]}" report } if [ "$perform_download" -ne 0 ]; then