Received: by 2002:a05:6a10:2726:0:0:0:0 with SMTP id ib38csp2133562pxb; Fri, 25 Mar 2022 11:40:46 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwFmwfSBh+2IBw7ekfD4ZmE2EoQoIuJeMCfLWxZapJruZDDndxvutWSK/iB/eISg4dLk/n+ X-Received: by 2002:a17:90b:4b45:b0:1c7:cc71:fdf7 with SMTP id mi5-20020a17090b4b4500b001c7cc71fdf7mr9646609pjb.33.1648233646799; Fri, 25 Mar 2022 11:40:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648233646; cv=none; d=google.com; s=arc-20160816; b=SnKAeJ/fFZqO8n1NnlDyWdu6P+gLEXzIHbv+T3RRuu5B6U3btIc4ggh1HnCw+vZOUG WONQnezIjC2BS0og59PfcfF9Lmgf4/fXgFBIdaFFVnvDR0dLX/DwMiLuJ+wXwINaTSu7 NY2q4qflnYQFisfEZbHVaepzQEoz8S9B/ky3+JkCP6SFdLBUptT0cu70HA4q8krGuShM 3tpkUkcg6cxQ3BehPpVnWLbpRR5M3hPoByMPp5vw5DTqcmegus+fXHBitW1MDq2FC8nl MKyy06BIsJc/wpQeuwwj+T7kUFuGS3dxPtFLZhccC3dR5HgiVhX3Oa52y6Wp+7JbAxWx nl1Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=hHqHFFpa5oC69fP2FCgHGpOKvKQX1YCTBf3TwuzqoNE=; b=CjAA/S259J6o4o+B4qEIwGOa4KXkwaupC0U8Lu5c0QhdcXJZdcUNFZ1IwdFdsfRxAy qseeaQtdTtnQ7V+8rvysCvOxI+nVbPdmp4kVqe3kZtMBxL9lfj91tpgFZXNmOgGBwTgO yo9DVW9BOqR8Qm1qlD9vob2QIkrYztvxPhX9PP7mVn7lFo1kbFEDpsIzIKSgMSDt7T35 Ef0X8cGE+3tLSIwYLo6xvSF1puWT/WBkE0OQ4BZG57S6l8xB/pmZuAjvi2KyiKaKZQDL s+QkBMBP0pOqA7iw1UsWzonY/sPgcZBOISQKN5r5avfIf1WVMO9dTd1a7hOBdQ3DMBxq IaDg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=fbPYArlQ; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [23.128.96.19]) by mx.google.com with ESMTPS id u10-20020a170903124a00b001541b329c25si3209979plh.611.2022.03.25.11.40.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Mar 2022 11:40:46 -0700 (PDT) Received-SPF: softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) client-ip=23.128.96.19; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=fbPYArlQ; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 3AA8319951D; Fri, 25 Mar 2022 10:58:01 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353682AbiCXXUx (ORCPT + 99 others); Thu, 24 Mar 2022 19:20:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39534 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355729AbiCXXUq (ORCPT ); Thu, 24 Mar 2022 19:20:46 -0400 Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C1A1D53A6F for ; Thu, 24 Mar 2022 16:19:12 -0700 (PDT) Received: by mail-pj1-x1030.google.com with SMTP id v4so6022837pjh.2 for ; Thu, 24 Mar 2022 16:19:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=hHqHFFpa5oC69fP2FCgHGpOKvKQX1YCTBf3TwuzqoNE=; b=fbPYArlQx50iamshoEvn1TUlzgo8nWqHeGT1DZrpWtdbibFNTV6wW8L8MN+mUwu78D j7P2ArS6H90s7rwUyr0sxDKM9fsF1WYahCHQ7azDJj9iWysPgN+3SlUgNK5M2AHrc81M ttdYc+utjjAxAxTilwOxhrxnbY4W3GIr5grwM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=hHqHFFpa5oC69fP2FCgHGpOKvKQX1YCTBf3TwuzqoNE=; b=WFrMPx1Wnpu9jgRJUikEbx+1nrVCCraYJ9W1Qh6MrU7DaqakOsm1uo1Ia7VPGFg+si RYiZ2a3ljWuhwspqcPSs1ud7MCSczHfXfARnd4/p/UZEagBX7k+gDWQ5Z5wtizBXfEZO 7bEDSvWWNaT407qoE9+9SbAOeApY3UGoLammmejp65kTfQ+M5gj1ewNaYZdpvUOHGafp 5u/8CG2kov7+sf6zEREgdOfPKuvTbS1ayesbVsNG1GeGbDgfNzgaaOWhF59Bfb7ROVkq x0bSGF3YPLQEsftpDs5MtIg/uoF7rrej+YBUoO/oK1jNFCBf3dczyFOro8iIZKImpcfc XPoQ== X-Gm-Message-State: AOAM53283+THkUD7Mq3WHFE9v21kEEn09SXlbGXNcylCmvogws7+IY3U 0wlIPBH3TFgp6z4CKkjbZp5GDA== X-Received: by 2002:a17:90b:4c09:b0:1c7:6c8:43c8 with SMTP id na9-20020a17090b4c0900b001c706c843c8mr9032037pjb.208.1648163952166; Thu, 24 Mar 2022 16:19:12 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id h2-20020a056a00218200b004f6519ce666sm4532608pfi.170.2022.03.24.16.19.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 16:19:11 -0700 (PDT) From: Kees Cook To: shuah@kernel.org Cc: Kees Cook , Andy Lutomirski , Will Drewry , linux-kselftest@vger.kernel.org, Willem de Bruijn , Jakub Kicinski , linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH 1/2] selftests/harness: Run TEARDOWN for ASSERT failures Date: Thu, 24 Mar 2022 16:19:06 -0700 Message-Id: <20220324231907.1363887-2-keescook@chromium.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220324231907.1363887-1-keescook@chromium.org> References: <20220324231907.1363887-1-keescook@chromium.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4758; h=from:subject; bh=0T38HzU8+bm6Q63KaidvXUMnrp8eZqY57zLg3zH/o/A=; b=owEBbQKS/ZANAwAKAYly9N/cbcAmAcsmYgBiPPxqSDr1CXvbwH34M5fSblmZaNneFSzMpiTGM0d/ 90+F5zOJAjMEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCYjz8agAKCRCJcvTf3G3AJvTkEA CiPMfWYC5z46AFuK+F0bbhaBC7z8ty/oP2ut2DxuQ9zJF5vCCWzPy8utegmyQzqLf2G0eVtyqOGLA9 z9R9IsyvhdqahTqCs4CnSQM+1ExmovNFrvnxVm2MPTC4Hw4HOrEXQ147p6fAyWRHJXku5oFEicURd8 +Zav83ohj2PSDwsvr/O7zOcbXlCptbA9XeyFUqoFbGRK3knG7QFNXnePKxARzYFkCiwemV+3RnC2eZ r+f8i8t+E1Z74jecj/DYjKuhRsdi7sx7YuwJ6SfmOfSt89ajcL/MDUMfBVday5TkZmsCw74zvi+8pA xSfHgm/rTyrCU68weOtWsZrr9mQ5kI9lFA/aISU/JWE/zf4vJwDwc/8jeU/W/Nf+YFnLo4Q0Su+2LJ MfywZYFxT8F1GLSpi6ncvYYtE4kxAmCztIu1lHc7o7ZKWX6OTj/MwQsHB5JZNw1W0J2HjJHzKzHdUM GwNTfZO9OBUqsk1YcIn/vK/NcjdTLFG5rlOTct+BXr4wH5SKU+vorUrHFUi8Eb8HeoW5ARNLN+4CrH TuXaXLkeDaI3rmiXb3dztoHGv9DQwncJ8OoYZXDdt+8W3BKZq1kHvSptD1ILQDf2LcU8l2eMnsSvqB 2pmEvJ+17rfn/4DFUN/oLJehWqghehI/Pgx8U/7OqYsr3S+7+DdQVs9kj78g== X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The kselftest test harness has traditionally not run the registered TEARDOWN handler when a test encountered an ASSERT. This creates unexpected situations and tests need to be very careful about using ASSERT, which seems a needless hurdle for test writers. Because of the harness's design for optional failure handlers, the original implementation of ASSERT used an abort() to immediately stop execution, but that meant the context for running teardown was lost. Instead, use setjmp/longjmp so that teardown can be done. Failed SETUP routines continue to not be followed by TEARDOWN, though. Cc: Andy Lutomirski Cc: Will Drewry Cc: Shuah Khan Cc: linux-kselftest@vger.kernel.org Signed-off-by: Kees Cook --- tools/testing/selftests/kselftest_harness.h | 49 ++++++++++++++------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h index 471eaa7b3a3f..bef08f824eb5 100644 --- a/tools/testing/selftests/kselftest_harness.h +++ b/tools/testing/selftests/kselftest_harness.h @@ -64,6 +64,7 @@ #include #include #include +#include #include "kselftest.h" @@ -183,7 +184,10 @@ struct __test_metadata *_metadata, \ struct __fixture_variant_metadata *variant) \ { \ - test_name(_metadata); \ + _metadata->setup_completed = true; \ + if (setjmp(_metadata->env) == 0) \ + test_name(_metadata); \ + __test_check_assert(_metadata); \ } \ static struct __test_metadata _##test_name##_object = \ { .name = #test_name, \ @@ -356,10 +360,7 @@ * Defines a test that depends on a fixture (e.g., is part of a test case). * Very similar to TEST() except that *self* is the setup instance of fixture's * datatype exposed for use by the implementation. - * - * Warning: use of ASSERT_* here will skip TEARDOWN. */ -/* TODO(wad) register fixtures on dedicated test lists. */ #define TEST_F(fixture_name, test_name) \ __TEST_F_IMPL(fixture_name, test_name, -1, TEST_TIMEOUT_DEFAULT) @@ -381,12 +382,17 @@ /* fixture data is alloced, setup, and torn down per call. */ \ FIXTURE_DATA(fixture_name) self; \ memset(&self, 0, sizeof(FIXTURE_DATA(fixture_name))); \ - fixture_name##_setup(_metadata, &self, variant->data); \ - /* Let setup failure terminate early. */ \ - if (!_metadata->passed) \ - return; \ - fixture_name##_##test_name(_metadata, &self, variant->data); \ - fixture_name##_teardown(_metadata, &self); \ + if (setjmp(_metadata->env) == 0) { \ + fixture_name##_setup(_metadata, &self, variant->data); \ + /* Let setup failure terminate early. */ \ + if (!_metadata->passed) \ + return; \ + _metadata->setup_completed = true; \ + fixture_name##_##test_name(_metadata, &self, variant->data); \ + } \ + if (_metadata->setup_completed) \ + fixture_name##_teardown(_metadata, &self); \ + __test_check_assert(_metadata); \ } \ static struct __test_metadata \ _##fixture_name##_##test_name##_object = { \ @@ -683,7 +689,7 @@ */ #define OPTIONAL_HANDLER(_assert) \ for (; _metadata->trigger; _metadata->trigger = \ - __bail(_assert, _metadata->no_print, _metadata->step)) + __bail(_assert, _metadata)) #define __INC_STEP(_metadata) \ /* Keep "step" below 255 (which is used for "SKIP" reporting). */ \ @@ -830,6 +836,9 @@ struct __test_metadata { bool timed_out; /* did this test timeout instead of exiting? */ __u8 step; bool no_print; /* manual trigger when TH_LOG_STREAM is not available */ + bool aborted; /* stopped test due to failed ASSERT */ + bool setup_completed; /* did setup finish? */ + jmp_buf env; /* for exiting out of test early */ struct __test_results *results; struct __test_metadata *prev, *next; }; @@ -848,16 +857,26 @@ static inline void __register_test(struct __test_metadata *t) __LIST_APPEND(t->fixture->tests, t); } -static inline int __bail(int for_realz, bool no_print, __u8 step) +static inline int __bail(int for_realz, struct __test_metadata *t) { + /* if this is ASSERT, return immediately. */ if (for_realz) { - if (no_print) - _exit(step); - abort(); + t->aborted = true; + longjmp(t->env, 1); } + /* otherwise, end the for loop and continue. */ return 0; } +static inline void __test_check_assert(struct __test_metadata *t) +{ + if (t->aborted) { + if (t->no_print) + _exit(t->step); + abort(); + } +} + struct __test_metadata *__active_test; static void __timeout_handler(int sig, siginfo_t *info, void *ucontext) { -- 2.32.0