From nobody Tue Jun 23 20:24:03 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1A8FEC433F5 for ; Sun, 27 Feb 2022 18:45:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231192AbiB0SqD (ORCPT ); Sun, 27 Feb 2022 13:46:03 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52764 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229644AbiB0SqA (ORCPT ); Sun, 27 Feb 2022 13:46:00 -0500 Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A024728E27 for ; Sun, 27 Feb 2022 10:45:22 -0800 (PST) Received: by mail-pj1-x1034.google.com with SMTP id j10-20020a17090a94ca00b001bc2a9596f6so9403695pjw.5 for ; Sun, 27 Feb 2022 10:45:22 -0800 (PST) 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=rtQJ6+HWuDHNtXviDEv3CrUYrjsryDE8pWmriGiESg0=; b=m2E7Mkc5+O/hSN+7zDdRObC+NbGDn8KfETTWlSmuj/vdJqDtWt/86czuCbSuNxGYsA 1Y8x9mmgL+ELb5DPf58L2FnoGs1NDCSPpYG1XAYvTOFZMvu4Tjtd1dL3M+2Uzub2AVmJ mxFjyzhIpbnoLtl+uqKjMt1eDPuGbpgQO/92Y= 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=rtQJ6+HWuDHNtXviDEv3CrUYrjsryDE8pWmriGiESg0=; b=1FIgmjJy9K/52VeVWzPI2cJ6HoL982qFNu3SnwLNQAyXK/Bvi38svMV3mONR78deom 1CqMkUqpPpBvqjCIl2ymzCGsL9XAbC8kTzj1Ee25dO7Cm3Gc0aM88oFqFfVlpFZ2oZI0 BQl8DQ3cmjDu4YE5brPg6BDNVfNAKxqrXVDOBBOFlbe7eUjphqvPg7vUUhRN9/Toh2JS qXFsQaKwK/a9qkqHuvPV5RgMS6/czyMYQ8nxxN+yRvhje5ZQDy1bRWKLr+mY6+9p54Sr t/o1RXwTfJ5ndcZGfiPDxb46y3r0obDijf4GjLE7MrH3mCOOspJ79xKP6yzYhHeLp+y/ P3FA== X-Gm-Message-State: AOAM533XRWSIV4IZ5tro6WHgwaqmQTQAiD7aucCWMfXdL48d6kC+aqLC GEYfRp3ZrM/VR6HmNjwOlZyEfg== X-Google-Smtp-Source: ABdhPJzVRRQGxF6e1NTngPEsB3I/EvTNRmSUfuQ6v7xj8PQt1X32lE1LoqLXaWLdGVbZluSQR3Vj5w== X-Received: by 2002:a17:90b:250f:b0:1bc:e520:91e6 with SMTP id ns15-20020a17090b250f00b001bce52091e6mr13355572pjb.43.1645987521825; Sun, 27 Feb 2022 10:45:21 -0800 (PST) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id q10-20020a056a00084a00b004f26d3f5d8fsm10450378pfk.25.2022.02.27.10.45.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 27 Feb 2022 10:45:21 -0800 (PST) From: Kees Cook To: Kees Cook Cc: "Gustavo A . R . Silva" , Nathan Chancellor , Nick Desaulniers , Rasmus Villemoes , Vitor Massaru Iha , Daniel Latypov , David Gow , Anton Ivanov , Jeff Dike , Richard Weinberger , Masahiro Yamada , Arnd Bergmann , linux-kernel@vger.kernel.org, linux-um@lists.infradead.org, linux-kbuild@vger.kernel.org, kunit-dev@googlegroups.com, llvm@lists.linux.dev, x86@kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH v3 1/7] overflow: Provide constant expression struct_size Date: Sun, 27 Feb 2022 10:45:11 -0800 Message-Id: <20220227184517.504931-2-keescook@chromium.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220227184517.504931-1-keescook@chromium.org> References: <20220227184517.504931-1-keescook@chromium.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=5098; h=from:subject; bh=2kZK8Pa8mdtDR/Nqo/3Vk6gXcxnyZeRVGJOFKK5/Dm4=; b=owEBbQKS/ZANAwAKAYly9N/cbcAmAcsmYgBiG8a7FSbvVC74wmbAmC12ksTVuBzN9xRSIPC+WKU3 EO0+lGSJAjMEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCYhvGuwAKCRCJcvTf3G3AJksnD/ 9jFKmi/Ux9BHhxzZ2RpxelaewUNUU1aSHv57YDOG4L43fmRoLxzBROLz9OcWcP5/ejuFFtwfP5323z DZFpA+Ts0sy9zDjBAcP06aCVrZ0D5y/C1HsAUvPpk+yS2jUe50vXwu7X4wwMS//COr8VCW+aGk4dvG B9loTCNsEklQK46RkPdt0d/WAGj0xMnzHWyztM050GcaJUl4TSBtIeN+5BKRWOt045Npdnf3eCWXq5 24GX5UE5ts6sZKHIk4ywytyDoK+uftNnd8Ufbn8iG34ZO8/fbkf7WAilUNTQH/y1cfyx8qYSIDJ7eL ZqDZejMvx4eMGypzGXA4J2L+Isq+cRIXrbnFLxtUgJt9YvTRrfQdunOtMOTC2WmHAnEKzOs9jlymHB T+Vc4UxaWsdNIBMnhRu+nSHuG/JJK2iYBNxjlNh3xcFWcODPFhCJG4S93ANnr+fKRDE8kq9rAkOYna KxjcdpjVWN/jDTmLHOI3cXBRLG3AxPuwSNAvFKvnck0F8hRGoQDfqTXM10M3TLrNXL9tKJrEJ/eIuQ TT36kiajoi0oH2nbWk9ne714xn1lJ4NoqeFFDO05bz78F70Sb5SOe7nU5RN75Gdbpw18YhvTG6ojX6 cuKk1/+pWSBz29y7CCOHSd+MakbP+FqPYa4n7OorO435P4PZiQdZPAhov3Xw== X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" There have been cases where struct_size() (or flex_array_size()) needs to be calculated for an initializer, which requires it be a constant expression. This is possible when the "count" argument is a constant expression, so provide this ability for the helpers. Cc: Gustavo A. R. Silva Cc: Nathan Chancellor Cc: Nick Desaulniers Cc: Rasmus Villemoes Signed-off-by: Kees Cook Reviewed-by: Gustavo A. R. Silva Tested-by: Gustavo A. R. Silva Link: https://lore.kernel.org/lkml/20220210010407.GA701603@embeddedor Tested-by: David Gow --- v1: https://lore.kernel.org/linux-hardening/20220210004326.776574-1-keescoo= k@chromium.org v2: - fix broken self-test due to CE optimization --- include/linux/overflow.h | 10 +++++++--- lib/test_overflow.c | 26 +++++++++++++++++--------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/include/linux/overflow.h b/include/linux/overflow.h index 59d7228104d0..f1221d11f8e5 100644 --- a/include/linux/overflow.h +++ b/include/linux/overflow.h @@ -4,6 +4,7 @@ =20 #include #include +#include =20 /* * We need to compute the minimum and maximum values representable in a gi= ven @@ -221,8 +222,9 @@ static inline size_t __must_check size_sub(size_t minue= nd, size_t subtrahend) * Return: number of bytes needed or SIZE_MAX on overflow. */ #define flex_array_size(p, member, count) \ - size_mul(count, \ - sizeof(*(p)->member) + __must_be_array((p)->member)) + __builtin_choose_expr(__is_constexpr(count), \ + (count) * sizeof(*(p)->member) + __must_be_array((p)->member), \ + size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member))) =20 /** * struct_size() - Calculate size of structure with trailing flexible arra= y. @@ -237,6 +239,8 @@ static inline size_t __must_check size_sub(size_t minue= nd, size_t subtrahend) * Return: number of bytes needed or SIZE_MAX on overflow. */ #define struct_size(p, member, count) \ - size_add(sizeof(*(p)), flex_array_size(p, member, count)) + __builtin_choose_expr(__is_constexpr(count), \ + sizeof(*(p)) + flex_array_size(p, member, count), \ + size_add(sizeof(*(p)), flex_array_size(p, member, count))) =20 #endif /* __LINUX_OVERFLOW_H */ diff --git a/lib/test_overflow.c b/lib/test_overflow.c index 712fb2351c27..f6530fce799d 100644 --- a/lib/test_overflow.c +++ b/lib/test_overflow.c @@ -602,10 +602,18 @@ struct __test_flex_array { =20 static int __init test_overflow_size_helpers(void) { + /* Make sure struct_size() can be used in a constant expression. */ + u8 ce_array[struct_size((struct __test_flex_array *)0, data, 55)]; struct __test_flex_array *obj; int count =3D 0; int err =3D 0; int var; + volatile int unconst =3D 0; + + /* Verify constant expression against runtime version. */ + var =3D 55; + OPTIMIZER_HIDE_VAR(var); + err |=3D sizeof(ce_array) !=3D struct_size(obj, data, var); =20 #define check_one_size_helper(expected, func, args...) ({ \ bool __failure =3D false; \ @@ -663,28 +671,28 @@ static int __init test_overflow_size_helpers(void) flex_array_size, obj, data, var++); err |=3D check_one_size_helper(5 * sizeof(*obj->data), flex_array_size, obj, data, var++); - err |=3D check_one_size_helper(0, flex_array_size, obj, data, 0); + err |=3D check_one_size_helper(0, flex_array_size, obj, data, 0 + unconst= ); err |=3D check_one_size_helper(sizeof(*obj->data), - flex_array_size, obj, data, 1); + flex_array_size, obj, data, 1 + unconst); err |=3D check_one_size_helper(7 * sizeof(*obj->data), - flex_array_size, obj, data, 7); + flex_array_size, obj, data, 7 + unconst); err |=3D check_one_size_helper(SIZE_MAX, - flex_array_size, obj, data, -1); + flex_array_size, obj, data, -1 + unconst); err |=3D check_one_size_helper(SIZE_MAX, - flex_array_size, obj, data, SIZE_MAX - 4); + flex_array_size, obj, data, SIZE_MAX - 4 + unconst); =20 var =3D 4; err |=3D check_one_size_helper(sizeof(*obj) + (4 * sizeof(*obj->data)), struct_size, obj, data, var++); err |=3D check_one_size_helper(sizeof(*obj) + (5 * sizeof(*obj->data)), struct_size, obj, data, var++); - err |=3D check_one_size_helper(sizeof(*obj), struct_size, obj, data, 0); + err |=3D check_one_size_helper(sizeof(*obj), struct_size, obj, data, 0 + = unconst); err |=3D check_one_size_helper(sizeof(*obj) + sizeof(*obj->data), - struct_size, obj, data, 1); + struct_size, obj, data, 1 + unconst); err |=3D check_one_size_helper(SIZE_MAX, - struct_size, obj, data, -3); + struct_size, obj, data, -3 + unconst); err |=3D check_one_size_helper(SIZE_MAX, - struct_size, obj, data, SIZE_MAX - 3); + struct_size, obj, data, SIZE_MAX - 3 + unconst); =20 pr_info("%d overflow size helper tests finished\n", count); =20 --=20 2.32.0 From nobody Tue Jun 23 20:24:03 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 507E4C433F5 for ; Sun, 27 Feb 2022 18:45:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231445AbiB0SqV (ORCPT ); Sun, 27 Feb 2022 13:46:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53392 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231229AbiB0SqJ (ORCPT ); Sun, 27 Feb 2022 13:46:09 -0500 Received: from mail-pg1-x535.google.com (mail-pg1-x535.google.com [IPv6:2607:f8b0:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CB6234ECE5 for ; Sun, 27 Feb 2022 10:45:23 -0800 (PST) Received: by mail-pg1-x535.google.com with SMTP id z4so9556515pgh.12 for ; Sun, 27 Feb 2022 10:45:23 -0800 (PST) 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=CORTFBC46eh2Ga2s+fFB0KGQ4LMJ6ZxXrGNYQWksMqg=; b=jytEN8QTp7WhnOe0gT5W/OXrVbY0DUQY952kCReWpRh9pDUaVhNG1K0ws9pIOqfHmK adIxfisDqTjVHsRnx+V9+Hiuw3IYOO2Yrcf2t+Z7nuXFudBfIPQoYAj4V9ZZ2qZUFlGP I/PjfCexi3vGX3x11G8SN7l0KCs7oVLuCbH6I= 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=CORTFBC46eh2Ga2s+fFB0KGQ4LMJ6ZxXrGNYQWksMqg=; b=yrtGKxlc3jOjetNY4xcUdDMArshYfw7S45fOT1Xx5DVu29jVfRI309VyMdN+crADWA TzC50J1s5snx293ntM9OgpvfXX42dipZmYxTNMmbFkIUHsWVR99MFDH11ZypjIYUCtiD pWHE8ALdqc7N+Kv/IY3qByvGAJ7oRW+yuIB2Ji/LOS6srON9tzSIi3XG/YeRb/cs4I7d NxaZ5iw6geXUmr8m7KIaeHBt0AD4UZZ8Nf7FsLjLI009cYUOQx/toYG0cVJNLKAbzPKe IduTAR6jvaNbe615JCpZSG/yGkwhgpNqJ4mhkO36dUvXgzbv23VfAR22zwxsX0vGbkOs Du4A== X-Gm-Message-State: AOAM532Sk81+PXrKh20w9mu9t9UAan8EA5AblJ9pQxxD+01vLPnnwOh8 j01rWPTxIFzXy/iIELplDQdPZg== X-Google-Smtp-Source: ABdhPJxomb26Bwz9HcGd5TkaawG3h2BNGxZVW5HWB81Zwt50QQjqO2wMQalut84jO4vI56mEbrWb8A== X-Received: by 2002:aa7:8882:0:b0:4df:7b9e:1ccb with SMTP id z2-20020aa78882000000b004df7b9e1ccbmr17848161pfe.41.1645987523005; Sun, 27 Feb 2022 10:45:23 -0800 (PST) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id n34-20020a056a000d6200b004e1ba1016absm10661559pfv.31.2022.02.27.10.45.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 27 Feb 2022 10:45:21 -0800 (PST) From: Kees Cook To: Kees Cook Cc: Rasmus Villemoes , Nick Desaulniers , Vitor Massaru Iha , Daniel Latypov , David Gow , "Gustavo A. R. Silva" , Nathan Chancellor , Anton Ivanov , Jeff Dike , Richard Weinberger , Masahiro Yamada , Arnd Bergmann , linux-kernel@vger.kernel.org, linux-um@lists.infradead.org, linux-kbuild@vger.kernel.org, kunit-dev@googlegroups.com, llvm@lists.linux.dev, x86@kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH v3 2/7] lib: overflow: Convert to Kunit Date: Sun, 27 Feb 2022 10:45:12 -0800 Message-Id: <20220227184517.504931-3-keescook@chromium.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220227184517.504931-1-keescook@chromium.org> References: <20220227184517.504931-1-keescook@chromium.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=34366; h=from:subject; bh=dzw9SDJzAKsm5GcR68EenTegMSttn9bi588mTjw/bnc=; b=owEBbQKS/ZANAwAKAYly9N/cbcAmAcsmYgBiG8a7t8JK9SalujIWrFt5o3iTGFXwFh4Drbrgk5FY iGnGW3+JAjMEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCYhvGuwAKCRCJcvTf3G3AJgoFD/ 9D+GRjQWP3rUKgJzs9GPpa9OhEnWomxof+Oim9tM5eNiNIQ9kvU6GK50UwU5lQ+lOlH4XiH7iztUbT qZKWivb/l6dfOmhCbP6glggmU9AXEUmZZsl6Y2ceKQi4XbBkVbqreWixI6HxEGx9SofyEN9M/GgVJ5 /kdcSkF05xIirv9M4TYn+v/geFlU/0R4T1Xbpqtp4SxN4p2xMtD9PCiYkVi3HVMtf9wRdUfiVBScvJ 4B6KclzV8X8O5f3VIl0vnAPx8MMRH0ScvR0JRvyum6FJPO0WYbVQR7gngPXkxElXm58TEx+7iC/Ysm +SgXNPgPhR5XqesfyyHMdsudhteSo6ezh+dTtOJoJs1kD1gdpIim/BpPaMoBhtDsfjVMGy+AYv0mPB GhTyZGGdieNnE3PbDV7XLyt3p8oRKLJDbI0bJa9BMlV3qBa/lLVWWFzJTZEe5lXDcmQUX7IyREHMNa 6UJgcct8Aj6tsOMrKHgGeosRWKZCvZREAkmGBBj9wSonwxywMlOX9+VbThO+pj4rxzRrT5pNKk+wTz di+QIdGbgbXvNXmIZLCPSv1hOqdagRRzcctlUSHtmm60Kbn5kBwfr4oFyNcl7lfWwP70ErwU+dnVTX Qc+V5XTcQLuTXjCvVOvLOwVc9f5aTYpFcZI7FOt8gm2AXQJBH53yRSeGM6Iw== X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Convert overflow unit tests to KUnit, for better integration into the kernel self test framework. Includes a rename of test_overflow.c to overflow_kunit.c, and CONFIG_TEST_OVERFLOW to CONFIG_OVERFLOW_KUNIT_TEST. $ ./tools/testing/kunit/kunit.py run overflow ... [14:33:51] Starting KUnit Kernel (1/1)... [14:33:51] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [14:33:51] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D overflow = (11 subtests) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [14:33:51] [PASSED] u8_overflow_test [14:33:51] [PASSED] s8_overflow_test [14:33:51] [PASSED] u16_overflow_test [14:33:51] [PASSED] s16_overflow_test [14:33:51] [PASSED] u32_overflow_test [14:33:51] [PASSED] s32_overflow_test [14:33:51] [PASSED] u64_overflow_test [14:33:51] [PASSED] s64_overflow_test [14:33:51] [PASSED] overflow_shift_test [14:33:51] [PASSED] overflow_allocation_test [14:33:51] [PASSED] overflow_size_helpers_test [14:33:51] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [PA= SSED] overflow =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D [14:33:51] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [14:33:51] Testing complete. Passed: 11, Failed: 0, Crashed: 0, Skipped: 0,= Errors: 0 [14:33:51] Elapsed time: 12.525s total, 0.001s configuring, 12.402s buildin= g, 0.101s running Cc: Rasmus Villemoes Cc: Nick Desaulniers Co-developed-by: Vitor Massaru Iha Signed-off-by: Vitor Massaru Iha Link: https://lore.kernel.org/lkml/20200720224418.200495-1-vitor@massaru.or= g/ Co-developed-by: Daniel Latypov Signed-off-by: Daniel Latypov Link: https://lore.kernel.org/linux-kselftest/20210503211536.1384578-1-dlat= ypov@google.com/ Acked-by: Nick Desaulniers Link: https://lore.kernel.org/lkml/CAKwvOdm62iA1dNiC6Q11UJ-MnTqtc4kXkm-ubPa= FMK824_k0nw@mail.gmail.com Signed-off-by: Kees Cook Reviewed-by: David Gow Link: https://lore.kernel.org/lkml/CABVgOS=3DTWVh649_Vjo3wnMu9gZnq66gkV-LtG= gsksAWMqc+MSA@mail.gmail.com Tested-by: David Gow --- v1: https://lore.kernel.org/lkml/20220216224153.2242451-1-keescook@chromium= .org v2: https://lore.kernel.org/lkml/20220224054825.1853314-1-keescook@chromium= .org v3: - tweak commit log (David) --- lib/Kconfig.debug | 16 +- lib/Makefile | 2 +- lib/{test_overflow.c =3D> overflow_kunit.c} | 554 ++++++++++------------ 3 files changed, 263 insertions(+), 309 deletions(-) rename lib/{test_overflow.c =3D> overflow_kunit.c} (54%) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 14b89aa37c5c..14d90d03bc8d 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -2214,9 +2214,6 @@ config TEST_UUID config TEST_XARRAY tristate "Test the XArray code at runtime" =20 -config TEST_OVERFLOW - tristate "Test check_*_overflow() functions at runtime" - config TEST_RHASHTABLE tristate "Perform selftest on resizable hash table" help @@ -2501,6 +2498,19 @@ config MEMCPY_KUNIT_TEST =20 If unsure, say N. =20 +config OVERFLOW_KUNIT_TEST + tristate "Test check_*_overflow() functions at runtime" if !KUNIT_ALL_TES= TS + depends on KUNIT + default KUNIT_ALL_TESTS + help + Builds unit tests for the check_*_overflow(), size_*(), allocation, and + related functions. + + For more information on KUnit and unit tests in general please refer + to the KUnit documentation in Documentation/dev-tools/kunit/. + + If unsure, say N. + config TEST_UDELAY tristate "udelay test driver" help diff --git a/lib/Makefile b/lib/Makefile index 300f569c626b..fdfcbfaff32f 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -77,7 +77,6 @@ obj-$(CONFIG_TEST_LIST_SORT) +=3D test_list_sort.o obj-$(CONFIG_TEST_MIN_HEAP) +=3D test_min_heap.o obj-$(CONFIG_TEST_LKM) +=3D test_module.o obj-$(CONFIG_TEST_VMALLOC) +=3D test_vmalloc.o -obj-$(CONFIG_TEST_OVERFLOW) +=3D test_overflow.o obj-$(CONFIG_TEST_RHASHTABLE) +=3D test_rhashtable.o obj-$(CONFIG_TEST_SORT) +=3D test_sort.o obj-$(CONFIG_TEST_USER_COPY) +=3D test_user_copy.o @@ -363,6 +362,7 @@ obj-$(CONFIG_BITS_TEST) +=3D test_bits.o obj-$(CONFIG_CMDLINE_KUNIT_TEST) +=3D cmdline_kunit.o obj-$(CONFIG_SLUB_KUNIT_TEST) +=3D slub_kunit.o obj-$(CONFIG_MEMCPY_KUNIT_TEST) +=3D memcpy_kunit.o +obj-$(CONFIG_OVERFLOW_KUNIT_TEST) +=3D overflow_kunit.o =20 obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) +=3D devmem_is_allowed.o =20 diff --git a/lib/test_overflow.c b/lib/overflow_kunit.c similarity index 54% rename from lib/test_overflow.c rename to lib/overflow_kunit.c index f6530fce799d..475f0c064bf6 100644 --- a/lib/test_overflow.c +++ b/lib/overflow_kunit.c @@ -1,11 +1,13 @@ // SPDX-License-Identifier: GPL-2.0 OR MIT /* - * Test cases for arithmetic overflow checks. + * Test cases for arithmetic overflow checks. See: + * https://www.kernel.org/doc/html/latest/dev-tools/kunit/kunit-tool.html#= configuring-building-and-running-tests + * ./tools/testing/kunit/kunit.py run overflow [--raw_output] */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt =20 +#include #include -#include #include #include #include @@ -19,7 +21,7 @@ t a, b; \ t sum, diff, prod; \ bool s_of, d_of, p_of; \ - } t ## _tests[] __initconst + } t ## _tests[] =20 DEFINE_TEST_ARRAY(u8) =3D { {0, 0, 0, 0, 0, false, false, false}, @@ -220,43 +222,31 @@ DEFINE_TEST_ARRAY(s64) =3D { bool _of; \ \ _of =3D check_ ## op ## _overflow(a, b, &_r); \ - if (_of !=3D of) { \ - pr_warn("expected "fmt" "sym" "fmt \ - " to%s overflow (type %s)\n", \ - a, b, of ? "" : " not", #t); \ - err =3D 1; \ - } \ - if (_r !=3D r) { \ - pr_warn("expected "fmt" "sym" "fmt" =3D=3D " \ - fmt", got "fmt" (type %s)\n", \ - a, b, r, _r, #t); \ - err =3D 1; \ - } \ + KUNIT_EXPECT_EQ_MSG(test, _of, of, \ + "expected "fmt" "sym" "fmt" to%s overflow (type %s)\n", \ + a, b, of ? "" : " not", #t); \ + KUNIT_EXPECT_EQ_MSG(test, _r, r, \ + "expected "fmt" "sym" "fmt" =3D=3D "fmt", got "fmt" (type %s)\n", \ + a, b, r, _r, #t); \ } while (0) =20 #define DEFINE_TEST_FUNC(t, fmt) \ -static int __init do_test_ ## t(const struct test_ ## t *p) \ +static void do_test_ ## t(struct kunit *test, const struct test_ ## t *p) \ { \ - int err =3D 0; \ - \ check_one_op(t, fmt, add, "+", p->a, p->b, p->sum, p->s_of); \ check_one_op(t, fmt, add, "+", p->b, p->a, p->sum, p->s_of); \ check_one_op(t, fmt, sub, "-", p->a, p->b, p->diff, p->d_of); \ check_one_op(t, fmt, mul, "*", p->a, p->b, p->prod, p->p_of); \ check_one_op(t, fmt, mul, "*", p->b, p->a, p->prod, p->p_of); \ - \ - return err; \ } \ \ -static int __init test_ ## t ## _overflow(void) { \ - int err =3D 0; \ +static void t ## _overflow_test(struct kunit *test) { \ unsigned i; \ \ for (i =3D 0; i < ARRAY_SIZE(t ## _tests); ++i) \ - err |=3D do_test_ ## t(&t ## _tests[i]); \ - pr_info("%zu %s arithmetic tests finished\n", \ + do_test_ ## t(test, &t ## _tests[i]); \ + kunit_info(test, "%zu %s arithmetic tests finished\n", \ ARRAY_SIZE(t ## _tests), #t); \ - return err; \ } =20 DEFINE_TEST_FUNC(u8, "%d"); @@ -270,198 +260,176 @@ DEFINE_TEST_FUNC(u64, "%llu"); DEFINE_TEST_FUNC(s64, "%lld"); #endif =20 -static int __init test_overflow_calculation(void) +static void overflow_shift_test(struct kunit *test) { - int err =3D 0; - - err |=3D test_u8_overflow(); - err |=3D test_s8_overflow(); - err |=3D test_u16_overflow(); - err |=3D test_s16_overflow(); - err |=3D test_u32_overflow(); - err |=3D test_s32_overflow(); -#if BITS_PER_LONG =3D=3D 64 - err |=3D test_u64_overflow(); - err |=3D test_s64_overflow(); -#endif - - return err; -} - -static int __init test_overflow_shift(void) -{ - int err =3D 0; int count =3D 0; =20 /* Args are: value, shift, type, expected result, overflow expected */ -#define TEST_ONE_SHIFT(a, s, t, expect, of) ({ \ - int __failed =3D 0; \ +#define TEST_ONE_SHIFT(a, s, t, expect, of) do { \ typeof(a) __a =3D (a); \ typeof(s) __s =3D (s); \ t __e =3D (expect); \ t __d; \ bool __of =3D check_shl_overflow(__a, __s, &__d); \ if (__of !=3D of) { \ - pr_warn("expected (%s)(%s << %s) to%s overflow\n", \ + KUNIT_EXPECT_EQ_MSG(test, __of, of, \ + "expected (%s)(%s << %s) to%s overflow\n", \ #t, #a, #s, of ? "" : " not"); \ - __failed =3D 1; \ } else if (!__of && __d !=3D __e) { \ - pr_warn("expected (%s)(%s << %s) =3D=3D %s\n", \ + KUNIT_EXPECT_EQ_MSG(test, __d, __e, \ + "expected (%s)(%s << %s) =3D=3D %s\n", \ #t, #a, #s, #expect); \ if ((t)-1 < 0) \ - pr_warn("got %lld\n", (s64)__d); \ + kunit_info(test, "got %lld\n", (s64)__d); \ else \ - pr_warn("got %llu\n", (u64)__d); \ - __failed =3D 1; \ + kunit_info(test, "got %llu\n", (u64)__d); \ } \ count++; \ - __failed; \ -}) +} while (0) =20 /* Sane shifts. */ - err |=3D TEST_ONE_SHIFT(1, 0, u8, 1 << 0, false); - err |=3D TEST_ONE_SHIFT(1, 4, u8, 1 << 4, false); - err |=3D TEST_ONE_SHIFT(1, 7, u8, 1 << 7, false); - err |=3D TEST_ONE_SHIFT(0xF, 4, u8, 0xF << 4, false); - err |=3D TEST_ONE_SHIFT(1, 0, u16, 1 << 0, false); - err |=3D TEST_ONE_SHIFT(1, 10, u16, 1 << 10, false); - err |=3D TEST_ONE_SHIFT(1, 15, u16, 1 << 15, false); - err |=3D TEST_ONE_SHIFT(0xFF, 8, u16, 0xFF << 8, false); - err |=3D TEST_ONE_SHIFT(1, 0, int, 1 << 0, false); - err |=3D TEST_ONE_SHIFT(1, 16, int, 1 << 16, false); - err |=3D TEST_ONE_SHIFT(1, 30, int, 1 << 30, false); - err |=3D TEST_ONE_SHIFT(1, 0, s32, 1 << 0, false); - err |=3D TEST_ONE_SHIFT(1, 16, s32, 1 << 16, false); - err |=3D TEST_ONE_SHIFT(1, 30, s32, 1 << 30, false); - err |=3D TEST_ONE_SHIFT(1, 0, unsigned int, 1U << 0, false); - err |=3D TEST_ONE_SHIFT(1, 20, unsigned int, 1U << 20, false); - err |=3D TEST_ONE_SHIFT(1, 31, unsigned int, 1U << 31, false); - err |=3D TEST_ONE_SHIFT(0xFFFFU, 16, unsigned int, 0xFFFFU << 16, false); - err |=3D TEST_ONE_SHIFT(1, 0, u32, 1U << 0, false); - err |=3D TEST_ONE_SHIFT(1, 20, u32, 1U << 20, false); - err |=3D TEST_ONE_SHIFT(1, 31, u32, 1U << 31, false); - err |=3D TEST_ONE_SHIFT(0xFFFFU, 16, u32, 0xFFFFU << 16, false); - err |=3D TEST_ONE_SHIFT(1, 0, u64, 1ULL << 0, false); - err |=3D TEST_ONE_SHIFT(1, 40, u64, 1ULL << 40, false); - err |=3D TEST_ONE_SHIFT(1, 63, u64, 1ULL << 63, false); - err |=3D TEST_ONE_SHIFT(0xFFFFFFFFULL, 32, u64, - 0xFFFFFFFFULL << 32, false); + TEST_ONE_SHIFT(1, 0, u8, 1 << 0, false); + TEST_ONE_SHIFT(1, 4, u8, 1 << 4, false); + TEST_ONE_SHIFT(1, 7, u8, 1 << 7, false); + TEST_ONE_SHIFT(0xF, 4, u8, 0xF << 4, false); + TEST_ONE_SHIFT(1, 0, u16, 1 << 0, false); + TEST_ONE_SHIFT(1, 10, u16, 1 << 10, false); + TEST_ONE_SHIFT(1, 15, u16, 1 << 15, false); + TEST_ONE_SHIFT(0xFF, 8, u16, 0xFF << 8, false); + TEST_ONE_SHIFT(1, 0, int, 1 << 0, false); + TEST_ONE_SHIFT(1, 16, int, 1 << 16, false); + TEST_ONE_SHIFT(1, 30, int, 1 << 30, false); + TEST_ONE_SHIFT(1, 0, s32, 1 << 0, false); + TEST_ONE_SHIFT(1, 16, s32, 1 << 16, false); + TEST_ONE_SHIFT(1, 30, s32, 1 << 30, false); + TEST_ONE_SHIFT(1, 0, unsigned int, 1U << 0, false); + TEST_ONE_SHIFT(1, 20, unsigned int, 1U << 20, false); + TEST_ONE_SHIFT(1, 31, unsigned int, 1U << 31, false); + TEST_ONE_SHIFT(0xFFFFU, 16, unsigned int, 0xFFFFU << 16, false); + TEST_ONE_SHIFT(1, 0, u32, 1U << 0, false); + TEST_ONE_SHIFT(1, 20, u32, 1U << 20, false); + TEST_ONE_SHIFT(1, 31, u32, 1U << 31, false); + TEST_ONE_SHIFT(0xFFFFU, 16, u32, 0xFFFFU << 16, false); + TEST_ONE_SHIFT(1, 0, u64, 1ULL << 0, false); + TEST_ONE_SHIFT(1, 40, u64, 1ULL << 40, false); + TEST_ONE_SHIFT(1, 63, u64, 1ULL << 63, false); + TEST_ONE_SHIFT(0xFFFFFFFFULL, 32, u64, 0xFFFFFFFFULL << 32, false); =20 /* Sane shift: start and end with 0, without a too-wide shift. */ - err |=3D TEST_ONE_SHIFT(0, 7, u8, 0, false); - err |=3D TEST_ONE_SHIFT(0, 15, u16, 0, false); - err |=3D TEST_ONE_SHIFT(0, 31, unsigned int, 0, false); - err |=3D TEST_ONE_SHIFT(0, 31, u32, 0, false); - err |=3D TEST_ONE_SHIFT(0, 63, u64, 0, false); + TEST_ONE_SHIFT(0, 7, u8, 0, false); + TEST_ONE_SHIFT(0, 15, u16, 0, false); + TEST_ONE_SHIFT(0, 31, unsigned int, 0, false); + TEST_ONE_SHIFT(0, 31, u32, 0, false); + TEST_ONE_SHIFT(0, 63, u64, 0, false); =20 /* Sane shift: start and end with 0, without reaching signed bit. */ - err |=3D TEST_ONE_SHIFT(0, 6, s8, 0, false); - err |=3D TEST_ONE_SHIFT(0, 14, s16, 0, false); - err |=3D TEST_ONE_SHIFT(0, 30, int, 0, false); - err |=3D TEST_ONE_SHIFT(0, 30, s32, 0, false); - err |=3D TEST_ONE_SHIFT(0, 62, s64, 0, false); + TEST_ONE_SHIFT(0, 6, s8, 0, false); + TEST_ONE_SHIFT(0, 14, s16, 0, false); + TEST_ONE_SHIFT(0, 30, int, 0, false); + TEST_ONE_SHIFT(0, 30, s32, 0, false); + TEST_ONE_SHIFT(0, 62, s64, 0, false); =20 /* Overflow: shifted the bit off the end. */ - err |=3D TEST_ONE_SHIFT(1, 8, u8, 0, true); - err |=3D TEST_ONE_SHIFT(1, 16, u16, 0, true); - err |=3D TEST_ONE_SHIFT(1, 32, unsigned int, 0, true); - err |=3D TEST_ONE_SHIFT(1, 32, u32, 0, true); - err |=3D TEST_ONE_SHIFT(1, 64, u64, 0, true); + TEST_ONE_SHIFT(1, 8, u8, 0, true); + TEST_ONE_SHIFT(1, 16, u16, 0, true); + TEST_ONE_SHIFT(1, 32, unsigned int, 0, true); + TEST_ONE_SHIFT(1, 32, u32, 0, true); + TEST_ONE_SHIFT(1, 64, u64, 0, true); =20 /* Overflow: shifted into the signed bit. */ - err |=3D TEST_ONE_SHIFT(1, 7, s8, 0, true); - err |=3D TEST_ONE_SHIFT(1, 15, s16, 0, true); - err |=3D TEST_ONE_SHIFT(1, 31, int, 0, true); - err |=3D TEST_ONE_SHIFT(1, 31, s32, 0, true); - err |=3D TEST_ONE_SHIFT(1, 63, s64, 0, true); + TEST_ONE_SHIFT(1, 7, s8, 0, true); + TEST_ONE_SHIFT(1, 15, s16, 0, true); + TEST_ONE_SHIFT(1, 31, int, 0, true); + TEST_ONE_SHIFT(1, 31, s32, 0, true); + TEST_ONE_SHIFT(1, 63, s64, 0, true); =20 /* Overflow: high bit falls off unsigned types. */ /* 10010110 */ - err |=3D TEST_ONE_SHIFT(150, 1, u8, 0, true); + TEST_ONE_SHIFT(150, 1, u8, 0, true); /* 1000100010010110 */ - err |=3D TEST_ONE_SHIFT(34966, 1, u16, 0, true); + TEST_ONE_SHIFT(34966, 1, u16, 0, true); /* 10000100000010001000100010010110 */ - err |=3D TEST_ONE_SHIFT(2215151766U, 1, u32, 0, true); - err |=3D TEST_ONE_SHIFT(2215151766U, 1, unsigned int, 0, true); + TEST_ONE_SHIFT(2215151766U, 1, u32, 0, true); + TEST_ONE_SHIFT(2215151766U, 1, unsigned int, 0, true); /* 1000001000010000010000000100000010000100000010001000100010010110 */ - err |=3D TEST_ONE_SHIFT(9372061470395238550ULL, 1, u64, 0, true); + TEST_ONE_SHIFT(9372061470395238550ULL, 1, u64, 0, true); =20 /* Overflow: bit shifted into signed bit on signed types. */ /* 01001011 */ - err |=3D TEST_ONE_SHIFT(75, 1, s8, 0, true); + TEST_ONE_SHIFT(75, 1, s8, 0, true); /* 0100010001001011 */ - err |=3D TEST_ONE_SHIFT(17483, 1, s16, 0, true); + TEST_ONE_SHIFT(17483, 1, s16, 0, true); /* 01000010000001000100010001001011 */ - err |=3D TEST_ONE_SHIFT(1107575883, 1, s32, 0, true); - err |=3D TEST_ONE_SHIFT(1107575883, 1, int, 0, true); + TEST_ONE_SHIFT(1107575883, 1, s32, 0, true); + TEST_ONE_SHIFT(1107575883, 1, int, 0, true); /* 0100000100001000001000000010000001000010000001000100010001001011 */ - err |=3D TEST_ONE_SHIFT(4686030735197619275LL, 1, s64, 0, true); + TEST_ONE_SHIFT(4686030735197619275LL, 1, s64, 0, true); =20 /* Overflow: bit shifted past signed bit on signed types. */ /* 01001011 */ - err |=3D TEST_ONE_SHIFT(75, 2, s8, 0, true); + TEST_ONE_SHIFT(75, 2, s8, 0, true); /* 0100010001001011 */ - err |=3D TEST_ONE_SHIFT(17483, 2, s16, 0, true); + TEST_ONE_SHIFT(17483, 2, s16, 0, true); /* 01000010000001000100010001001011 */ - err |=3D TEST_ONE_SHIFT(1107575883, 2, s32, 0, true); - err |=3D TEST_ONE_SHIFT(1107575883, 2, int, 0, true); + TEST_ONE_SHIFT(1107575883, 2, s32, 0, true); + TEST_ONE_SHIFT(1107575883, 2, int, 0, true); /* 0100000100001000001000000010000001000010000001000100010001001011 */ - err |=3D TEST_ONE_SHIFT(4686030735197619275LL, 2, s64, 0, true); + TEST_ONE_SHIFT(4686030735197619275LL, 2, s64, 0, true); =20 /* Overflow: values larger than destination type. */ - err |=3D TEST_ONE_SHIFT(0x100, 0, u8, 0, true); - err |=3D TEST_ONE_SHIFT(0xFF, 0, s8, 0, true); - err |=3D TEST_ONE_SHIFT(0x10000U, 0, u16, 0, true); - err |=3D TEST_ONE_SHIFT(0xFFFFU, 0, s16, 0, true); - err |=3D TEST_ONE_SHIFT(0x100000000ULL, 0, u32, 0, true); - err |=3D TEST_ONE_SHIFT(0x100000000ULL, 0, unsigned int, 0, true); - err |=3D TEST_ONE_SHIFT(0xFFFFFFFFUL, 0, s32, 0, true); - err |=3D TEST_ONE_SHIFT(0xFFFFFFFFUL, 0, int, 0, true); - err |=3D TEST_ONE_SHIFT(0xFFFFFFFFFFFFFFFFULL, 0, s64, 0, true); + TEST_ONE_SHIFT(0x100, 0, u8, 0, true); + TEST_ONE_SHIFT(0xFF, 0, s8, 0, true); + TEST_ONE_SHIFT(0x10000U, 0, u16, 0, true); + TEST_ONE_SHIFT(0xFFFFU, 0, s16, 0, true); + TEST_ONE_SHIFT(0x100000000ULL, 0, u32, 0, true); + TEST_ONE_SHIFT(0x100000000ULL, 0, unsigned int, 0, true); + TEST_ONE_SHIFT(0xFFFFFFFFUL, 0, s32, 0, true); + TEST_ONE_SHIFT(0xFFFFFFFFUL, 0, int, 0, true); + TEST_ONE_SHIFT(0xFFFFFFFFFFFFFFFFULL, 0, s64, 0, true); =20 /* Nonsense: negative initial value. */ - err |=3D TEST_ONE_SHIFT(-1, 0, s8, 0, true); - err |=3D TEST_ONE_SHIFT(-1, 0, u8, 0, true); - err |=3D TEST_ONE_SHIFT(-5, 0, s16, 0, true); - err |=3D TEST_ONE_SHIFT(-5, 0, u16, 0, true); - err |=3D TEST_ONE_SHIFT(-10, 0, int, 0, true); - err |=3D TEST_ONE_SHIFT(-10, 0, unsigned int, 0, true); - err |=3D TEST_ONE_SHIFT(-100, 0, s32, 0, true); - err |=3D TEST_ONE_SHIFT(-100, 0, u32, 0, true); - err |=3D TEST_ONE_SHIFT(-10000, 0, s64, 0, true); - err |=3D TEST_ONE_SHIFT(-10000, 0, u64, 0, true); + TEST_ONE_SHIFT(-1, 0, s8, 0, true); + TEST_ONE_SHIFT(-1, 0, u8, 0, true); + TEST_ONE_SHIFT(-5, 0, s16, 0, true); + TEST_ONE_SHIFT(-5, 0, u16, 0, true); + TEST_ONE_SHIFT(-10, 0, int, 0, true); + TEST_ONE_SHIFT(-10, 0, unsigned int, 0, true); + TEST_ONE_SHIFT(-100, 0, s32, 0, true); + TEST_ONE_SHIFT(-100, 0, u32, 0, true); + TEST_ONE_SHIFT(-10000, 0, s64, 0, true); + TEST_ONE_SHIFT(-10000, 0, u64, 0, true); =20 /* Nonsense: negative shift values. */ - err |=3D TEST_ONE_SHIFT(0, -5, s8, 0, true); - err |=3D TEST_ONE_SHIFT(0, -5, u8, 0, true); - err |=3D TEST_ONE_SHIFT(0, -10, s16, 0, true); - err |=3D TEST_ONE_SHIFT(0, -10, u16, 0, true); - err |=3D TEST_ONE_SHIFT(0, -15, int, 0, true); - err |=3D TEST_ONE_SHIFT(0, -15, unsigned int, 0, true); - err |=3D TEST_ONE_SHIFT(0, -20, s32, 0, true); - err |=3D TEST_ONE_SHIFT(0, -20, u32, 0, true); - err |=3D TEST_ONE_SHIFT(0, -30, s64, 0, true); - err |=3D TEST_ONE_SHIFT(0, -30, u64, 0, true); + TEST_ONE_SHIFT(0, -5, s8, 0, true); + TEST_ONE_SHIFT(0, -5, u8, 0, true); + TEST_ONE_SHIFT(0, -10, s16, 0, true); + TEST_ONE_SHIFT(0, -10, u16, 0, true); + TEST_ONE_SHIFT(0, -15, int, 0, true); + TEST_ONE_SHIFT(0, -15, unsigned int, 0, true); + TEST_ONE_SHIFT(0, -20, s32, 0, true); + TEST_ONE_SHIFT(0, -20, u32, 0, true); + TEST_ONE_SHIFT(0, -30, s64, 0, true); + TEST_ONE_SHIFT(0, -30, u64, 0, true); =20 /* Overflow: shifted at or beyond entire type's bit width. */ - err |=3D TEST_ONE_SHIFT(0, 8, u8, 0, true); - err |=3D TEST_ONE_SHIFT(0, 9, u8, 0, true); - err |=3D TEST_ONE_SHIFT(0, 8, s8, 0, true); - err |=3D TEST_ONE_SHIFT(0, 9, s8, 0, true); - err |=3D TEST_ONE_SHIFT(0, 16, u16, 0, true); - err |=3D TEST_ONE_SHIFT(0, 17, u16, 0, true); - err |=3D TEST_ONE_SHIFT(0, 16, s16, 0, true); - err |=3D TEST_ONE_SHIFT(0, 17, s16, 0, true); - err |=3D TEST_ONE_SHIFT(0, 32, u32, 0, true); - err |=3D TEST_ONE_SHIFT(0, 33, u32, 0, true); - err |=3D TEST_ONE_SHIFT(0, 32, int, 0, true); - err |=3D TEST_ONE_SHIFT(0, 33, int, 0, true); - err |=3D TEST_ONE_SHIFT(0, 32, s32, 0, true); - err |=3D TEST_ONE_SHIFT(0, 33, s32, 0, true); - err |=3D TEST_ONE_SHIFT(0, 64, u64, 0, true); - err |=3D TEST_ONE_SHIFT(0, 65, u64, 0, true); - err |=3D TEST_ONE_SHIFT(0, 64, s64, 0, true); - err |=3D TEST_ONE_SHIFT(0, 65, s64, 0, true); + TEST_ONE_SHIFT(0, 8, u8, 0, true); + TEST_ONE_SHIFT(0, 9, u8, 0, true); + TEST_ONE_SHIFT(0, 8, s8, 0, true); + TEST_ONE_SHIFT(0, 9, s8, 0, true); + TEST_ONE_SHIFT(0, 16, u16, 0, true); + TEST_ONE_SHIFT(0, 17, u16, 0, true); + TEST_ONE_SHIFT(0, 16, s16, 0, true); + TEST_ONE_SHIFT(0, 17, s16, 0, true); + TEST_ONE_SHIFT(0, 32, u32, 0, true); + TEST_ONE_SHIFT(0, 33, u32, 0, true); + TEST_ONE_SHIFT(0, 32, int, 0, true); + TEST_ONE_SHIFT(0, 33, int, 0, true); + TEST_ONE_SHIFT(0, 32, s32, 0, true); + TEST_ONE_SHIFT(0, 33, s32, 0, true); + TEST_ONE_SHIFT(0, 64, u64, 0, true); + TEST_ONE_SHIFT(0, 65, u64, 0, true); + TEST_ONE_SHIFT(0, 64, s64, 0, true); + TEST_ONE_SHIFT(0, 65, s64, 0, true); =20 /* * Corner case: for unsigned types, we fail when we've shifted @@ -472,17 +440,14 @@ static int __init test_overflow_shift(void) * signed bit). So, for now, we will test this condition but * mark it as not expected to overflow. */ - err |=3D TEST_ONE_SHIFT(0, 7, s8, 0, false); - err |=3D TEST_ONE_SHIFT(0, 15, s16, 0, false); - err |=3D TEST_ONE_SHIFT(0, 31, int, 0, false); - err |=3D TEST_ONE_SHIFT(0, 31, s32, 0, false); - err |=3D TEST_ONE_SHIFT(0, 63, s64, 0, false); - - pr_info("%d shift tests finished\n", count); + TEST_ONE_SHIFT(0, 7, s8, 0, false); + TEST_ONE_SHIFT(0, 15, s16, 0, false); + TEST_ONE_SHIFT(0, 31, int, 0, false); + TEST_ONE_SHIFT(0, 31, s32, 0, false); + TEST_ONE_SHIFT(0, 63, s64, 0, false); =20 + kunit_info(test, "%d shift tests finished\n", count); #undef TEST_ONE_SHIFT - - return err; } =20 /* @@ -502,7 +467,7 @@ static int __init test_overflow_shift(void) #define TEST_SIZE (5 * 4096) =20 #define DEFINE_TEST_ALLOC(func, free_func, want_arg, want_gfp, want_node)\ -static int __init test_ ## func (void *arg) \ +static void test_ ## func (struct kunit *test, void *arg) \ { \ volatile size_t a =3D TEST_SIZE; \ volatile size_t b =3D (SIZE_MAX / TEST_SIZE) + 1; \ @@ -510,30 +475,24 @@ static int __init test_ ## func (void *arg) \ \ /* Tiny allocation test. */ \ ptr =3D alloc ## want_arg ## want_gfp ## want_node (func, arg, 1);\ - if (!ptr) { \ - pr_warn(#func " failed regular allocation?!\n"); \ - return 1; \ - } \ + KUNIT_ASSERT_NOT_ERR_OR_NULL_MSG(test, ptr, \ + #func " failed regular allocation?!\n"); \ free ## want_arg (free_func, arg, ptr); \ \ /* Wrapped allocation test. */ \ ptr =3D alloc ## want_arg ## want_gfp ## want_node (func, arg, \ a * b); \ - if (!ptr) { \ - pr_warn(#func " unexpectedly failed bad wrapping?!\n"); \ - return 1; \ - } \ + KUNIT_ASSERT_NOT_ERR_OR_NULL_MSG(test, ptr, \ + #func " unexpectedly failed bad wrapping?!\n"); \ free ## want_arg (free_func, arg, ptr); \ \ /* Saturated allocation test. */ \ ptr =3D alloc ## want_arg ## want_gfp ## want_node (func, arg, \ array_size(a, b)); \ if (ptr) { \ - pr_warn(#func " missed saturation!\n"); \ + KUNIT_FAIL(test, #func " missed saturation!\n"); \ free ## want_arg (free_func, arg, ptr); \ - return 1; \ } \ - return 0; \ } =20 /* @@ -554,44 +513,38 @@ DEFINE_TEST_ALLOC(kvzalloc_node, kvfree, 0, 1, 1); DEFINE_TEST_ALLOC(devm_kmalloc, devm_kfree, 1, 1, 0); DEFINE_TEST_ALLOC(devm_kzalloc, devm_kfree, 1, 1, 0); =20 -static int __init test_overflow_allocation(void) +static void overflow_allocation_test(struct kunit *test) { const char device_name[] =3D "overflow-test"; struct device *dev; int count =3D 0; - int err =3D 0; =20 -#define check_allocation_overflow(alloc) ({ \ +#define check_allocation_overflow(alloc) do { \ count++; \ - test_ ## alloc(dev); \ -}) + test_ ## alloc(test, dev); \ +} while (0) =20 /* Create dummy device for devm_kmalloc()-family tests. */ dev =3D root_device_register(device_name); - if (IS_ERR(dev)) { - pr_warn("Cannot register test device\n"); - return 1; - } - - err |=3D check_allocation_overflow(kmalloc); - err |=3D check_allocation_overflow(kmalloc_node); - err |=3D check_allocation_overflow(kzalloc); - err |=3D check_allocation_overflow(kzalloc_node); - err |=3D check_allocation_overflow(__vmalloc); - err |=3D check_allocation_overflow(kvmalloc); - err |=3D check_allocation_overflow(kvmalloc_node); - err |=3D check_allocation_overflow(kvzalloc); - err |=3D check_allocation_overflow(kvzalloc_node); - err |=3D check_allocation_overflow(devm_kmalloc); - err |=3D check_allocation_overflow(devm_kzalloc); + KUNIT_ASSERT_FALSE_MSG(test, IS_ERR(dev), + "Cannot register test device\n"); + + check_allocation_overflow(kmalloc); + check_allocation_overflow(kmalloc_node); + check_allocation_overflow(kzalloc); + check_allocation_overflow(kzalloc_node); + check_allocation_overflow(__vmalloc); + check_allocation_overflow(kvmalloc); + check_allocation_overflow(kvmalloc_node); + check_allocation_overflow(kvzalloc); + check_allocation_overflow(kvzalloc_node); + check_allocation_overflow(devm_kmalloc); + check_allocation_overflow(devm_kzalloc); =20 device_unregister(dev); =20 - pr_info("%d allocation overflow tests finished\n", count); - + kunit_info(test, "%d allocation overflow tests finished\n", count); #undef check_allocation_overflow - - return err; } =20 struct __test_flex_array { @@ -600,127 +553,118 @@ struct __test_flex_array { unsigned long data[]; }; =20 -static int __init test_overflow_size_helpers(void) +static void overflow_size_helpers_test(struct kunit *test) { /* Make sure struct_size() can be used in a constant expression. */ u8 ce_array[struct_size((struct __test_flex_array *)0, data, 55)]; struct __test_flex_array *obj; int count =3D 0; - int err =3D 0; int var; volatile int unconst =3D 0; =20 /* Verify constant expression against runtime version. */ var =3D 55; OPTIMIZER_HIDE_VAR(var); - err |=3D sizeof(ce_array) !=3D struct_size(obj, data, var); + KUNIT_EXPECT_EQ(test, sizeof(ce_array), struct_size(obj, data, var)); =20 -#define check_one_size_helper(expected, func, args...) ({ \ - bool __failure =3D false; \ - size_t _r; \ - \ - _r =3D func(args); \ - if (_r !=3D (expected)) { \ - pr_warn("expected " #func "(" #args ") " \ - "to return %zu but got %zu instead\n", \ - (size_t)(expected), _r); \ - __failure =3D true; \ - } \ +#define check_one_size_helper(expected, func, args...) do { \ + size_t _r =3D func(args); \ + KUNIT_EXPECT_EQ_MSG(test, _r, expected, \ + "expected " #func "(" #args ") to return %zu but got %zu instead\n", \ + (size_t)(expected), _r); \ count++; \ - __failure; \ -}) +} while (0) =20 var =3D 4; - err |=3D check_one_size_helper(20, size_mul, var++, 5); - err |=3D check_one_size_helper(20, size_mul, 4, var++); - err |=3D check_one_size_helper(0, size_mul, 0, 3); - err |=3D check_one_size_helper(0, size_mul, 3, 0); - err |=3D check_one_size_helper(6, size_mul, 2, 3); - err |=3D check_one_size_helper(SIZE_MAX, size_mul, SIZE_MAX, 1); - err |=3D check_one_size_helper(SIZE_MAX, size_mul, SIZE_MAX, 3); - err |=3D check_one_size_helper(SIZE_MAX, size_mul, SIZE_MAX, -3); + check_one_size_helper(20, size_mul, var++, 5); + check_one_size_helper(20, size_mul, 4, var++); + check_one_size_helper(0, size_mul, 0, 3); + check_one_size_helper(0, size_mul, 3, 0); + check_one_size_helper(6, size_mul, 2, 3); + check_one_size_helper(SIZE_MAX, size_mul, SIZE_MAX, 1); + check_one_size_helper(SIZE_MAX, size_mul, SIZE_MAX, 3); + check_one_size_helper(SIZE_MAX, size_mul, SIZE_MAX, -3); =20 var =3D 4; - err |=3D check_one_size_helper(9, size_add, var++, 5); - err |=3D check_one_size_helper(9, size_add, 4, var++); - err |=3D check_one_size_helper(9, size_add, 9, 0); - err |=3D check_one_size_helper(9, size_add, 0, 9); - err |=3D check_one_size_helper(5, size_add, 2, 3); - err |=3D check_one_size_helper(SIZE_MAX, size_add, SIZE_MAX, 1); - err |=3D check_one_size_helper(SIZE_MAX, size_add, SIZE_MAX, 3); - err |=3D check_one_size_helper(SIZE_MAX, size_add, SIZE_MAX, -3); + check_one_size_helper(9, size_add, var++, 5); + check_one_size_helper(9, size_add, 4, var++); + check_one_size_helper(9, size_add, 9, 0); + check_one_size_helper(9, size_add, 0, 9); + check_one_size_helper(5, size_add, 2, 3); + check_one_size_helper(SIZE_MAX, size_add, SIZE_MAX, 1); + check_one_size_helper(SIZE_MAX, size_add, SIZE_MAX, 3); + check_one_size_helper(SIZE_MAX, size_add, SIZE_MAX, -3); =20 var =3D 4; - err |=3D check_one_size_helper(1, size_sub, var--, 3); - err |=3D check_one_size_helper(1, size_sub, 4, var--); - err |=3D check_one_size_helper(1, size_sub, 3, 2); - err |=3D check_one_size_helper(9, size_sub, 9, 0); - err |=3D check_one_size_helper(SIZE_MAX, size_sub, 9, -3); - err |=3D check_one_size_helper(SIZE_MAX, size_sub, 0, 9); - err |=3D check_one_size_helper(SIZE_MAX, size_sub, 2, 3); - err |=3D check_one_size_helper(SIZE_MAX, size_sub, SIZE_MAX, 0); - err |=3D check_one_size_helper(SIZE_MAX, size_sub, SIZE_MAX, 10); - err |=3D check_one_size_helper(SIZE_MAX, size_sub, 0, SIZE_MAX); - err |=3D check_one_size_helper(SIZE_MAX, size_sub, 14, SIZE_MAX); - err |=3D check_one_size_helper(SIZE_MAX - 2, size_sub, SIZE_MAX - 1, 1); - err |=3D check_one_size_helper(SIZE_MAX - 4, size_sub, SIZE_MAX - 1, 3); - err |=3D check_one_size_helper(1, size_sub, SIZE_MAX - 1, -3); + check_one_size_helper(1, size_sub, var--, 3); + check_one_size_helper(1, size_sub, 4, var--); + check_one_size_helper(1, size_sub, 3, 2); + check_one_size_helper(9, size_sub, 9, 0); + check_one_size_helper(SIZE_MAX, size_sub, 9, -3); + check_one_size_helper(SIZE_MAX, size_sub, 0, 9); + check_one_size_helper(SIZE_MAX, size_sub, 2, 3); + check_one_size_helper(SIZE_MAX, size_sub, SIZE_MAX, 0); + check_one_size_helper(SIZE_MAX, size_sub, SIZE_MAX, 10); + check_one_size_helper(SIZE_MAX, size_sub, 0, SIZE_MAX); + check_one_size_helper(SIZE_MAX, size_sub, 14, SIZE_MAX); + check_one_size_helper(SIZE_MAX - 2, size_sub, SIZE_MAX - 1, 1); + check_one_size_helper(SIZE_MAX - 4, size_sub, SIZE_MAX - 1, 3); + check_one_size_helper(1, size_sub, SIZE_MAX - 1, -3); =20 var =3D 4; - err |=3D check_one_size_helper(4 * sizeof(*obj->data), - flex_array_size, obj, data, var++); - err |=3D check_one_size_helper(5 * sizeof(*obj->data), - flex_array_size, obj, data, var++); - err |=3D check_one_size_helper(0, flex_array_size, obj, data, 0 + unconst= ); - err |=3D check_one_size_helper(sizeof(*obj->data), - flex_array_size, obj, data, 1 + unconst); - err |=3D check_one_size_helper(7 * sizeof(*obj->data), - flex_array_size, obj, data, 7 + unconst); - err |=3D check_one_size_helper(SIZE_MAX, - flex_array_size, obj, data, -1 + unconst); - err |=3D check_one_size_helper(SIZE_MAX, - flex_array_size, obj, data, SIZE_MAX - 4 + unconst); + check_one_size_helper(4 * sizeof(*obj->data), + flex_array_size, obj, data, var++); + check_one_size_helper(5 * sizeof(*obj->data), + flex_array_size, obj, data, var++); + check_one_size_helper(0, flex_array_size, obj, data, 0 + unconst); + check_one_size_helper(sizeof(*obj->data), + flex_array_size, obj, data, 1 + unconst); + check_one_size_helper(7 * sizeof(*obj->data), + flex_array_size, obj, data, 7 + unconst); + check_one_size_helper(SIZE_MAX, + flex_array_size, obj, data, -1 + unconst); + check_one_size_helper(SIZE_MAX, + flex_array_size, obj, data, SIZE_MAX - 4 + unconst); =20 var =3D 4; - err |=3D check_one_size_helper(sizeof(*obj) + (4 * sizeof(*obj->data)), - struct_size, obj, data, var++); - err |=3D check_one_size_helper(sizeof(*obj) + (5 * sizeof(*obj->data)), - struct_size, obj, data, var++); - err |=3D check_one_size_helper(sizeof(*obj), struct_size, obj, data, 0 + = unconst); - err |=3D check_one_size_helper(sizeof(*obj) + sizeof(*obj->data), - struct_size, obj, data, 1 + unconst); - err |=3D check_one_size_helper(SIZE_MAX, - struct_size, obj, data, -3 + unconst); - err |=3D check_one_size_helper(SIZE_MAX, - struct_size, obj, data, SIZE_MAX - 3 + unconst); - - pr_info("%d overflow size helper tests finished\n", count); - - return err; + check_one_size_helper(sizeof(*obj) + (4 * sizeof(*obj->data)), + struct_size, obj, data, var++); + check_one_size_helper(sizeof(*obj) + (5 * sizeof(*obj->data)), + struct_size, obj, data, var++); + check_one_size_helper(sizeof(*obj), struct_size, obj, data, 0 + unconst); + check_one_size_helper(sizeof(*obj) + sizeof(*obj->data), + struct_size, obj, data, 1 + unconst); + check_one_size_helper(SIZE_MAX, + struct_size, obj, data, -3 + unconst); + check_one_size_helper(SIZE_MAX, + struct_size, obj, data, SIZE_MAX - 3 + unconst); + + kunit_info(test, "%d overflow size helper tests finished\n", count); +#undef check_one_size_helper } =20 -static int __init test_module_init(void) -{ - int err =3D 0; - - err |=3D test_overflow_calculation(); - err |=3D test_overflow_shift(); - err |=3D test_overflow_size_helpers(); - err |=3D test_overflow_allocation(); - - if (err) { - pr_warn("FAIL!\n"); - err =3D -EINVAL; - } else { - pr_info("all tests passed\n"); - } +static struct kunit_case overflow_test_cases[] =3D { + KUNIT_CASE(u8_overflow_test), + KUNIT_CASE(s8_overflow_test), + KUNIT_CASE(u16_overflow_test), + KUNIT_CASE(s16_overflow_test), + KUNIT_CASE(u32_overflow_test), + KUNIT_CASE(s32_overflow_test), +#if BITS_PER_LONG =3D=3D 64 + KUNIT_CASE(u64_overflow_test), + KUNIT_CASE(s64_overflow_test), +#endif + KUNIT_CASE(overflow_shift_test), + KUNIT_CASE(overflow_allocation_test), + KUNIT_CASE(overflow_size_helpers_test), + {} +}; =20 - return err; -} +static struct kunit_suite overflow_test_suite =3D { + .name =3D "overflow", + .test_cases =3D overflow_test_cases, +}; =20 -static void __exit test_module_exit(void) -{ } +kunit_test_suite(overflow_test_suite); =20 -module_init(test_module_init); -module_exit(test_module_exit); MODULE_LICENSE("Dual MIT/GPL"); --=20 2.32.0 From nobody Tue Jun 23 20:24:03 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6B58EC433FE for ; Sun, 27 Feb 2022 18:45:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231250AbiB0SqM (ORCPT ); Sun, 27 Feb 2022 13:46:12 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53340 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231210AbiB0SqI (ORCPT ); Sun, 27 Feb 2022 13:46:08 -0500 Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C9AAF28E36 for ; Sun, 27 Feb 2022 10:45:22 -0800 (PST) Received: by mail-pl1-x629.google.com with SMTP id l9so8467661pls.6 for ; Sun, 27 Feb 2022 10:45:22 -0800 (PST) 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=lNerjKnrLq1mzg7meHtI9HSpdFqh8op60Xx8N1ZiLfw=; b=Jr0yJeEZIKJLj1DUJnFBO3uvzL0weaiXKeajxm9pM8JoQNy2uegYOMvaJRLuJ8Uib7 Pv0U4bOC0mzJS889tXajsXuZEDCxHLF6/3dzjCPuLL7LYMNCxjD0nF6GdeWIPWR8H9Fm clw/KWTuD8soQR8FJZpgXCYEHze59giMoUZ+Y= 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=lNerjKnrLq1mzg7meHtI9HSpdFqh8op60Xx8N1ZiLfw=; b=VJenAY/QUvk+ntsLT3Wgn/v7lODEKSZf2ODgT1NhnoOFCWe0GHpxgLxTE67/GrsMH0 nWTZrXmWdyf9ORhgmilqXwZESluxIpzF9uIljrxMprs9JXbH4wYY42i40/C0eux27E5R lrTHof0DFrLTXpKDtGbzewSpW315Byn2VPCgvit7o2+OuZwJGUj+vHiwbgwLuYK6plUl /b2qb1Z7OP4TCXsIvdYsePAI5bJYXSoNu/GaDIp7hK69szoGqoMeDVr3+zkxis9KDOqL Wdtn/8I9W5QOucr/a+/h0263qQqzvnMCqfbr+QQ9Vg0ufQth1UxpHPI4yzrbXFpupMYk Kqhg== X-Gm-Message-State: AOAM531sl12/k3P9Rm7qeoYw9sfDwN5wUGr38uumiCYssiQ+MwCgthwZ uPvxMjMEIX+/XNQhbH+k+t4UuA8YeF4nnw== X-Google-Smtp-Source: ABdhPJwr3yU+S9CYU72TPvCVp/pkqfJFhYcfUElEnSnBBrukweZBCVubPSK86r4KINp53JP/mq3zxw== X-Received: by 2002:a17:90a:a78c:b0:1b8:b769:62d0 with SMTP id f12-20020a17090aa78c00b001b8b76962d0mr13075887pjq.227.1645987522189; Sun, 27 Feb 2022 10:45:22 -0800 (PST) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id f6-20020a056a00238600b004e1906b3bb2sm10683826pfc.12.2022.02.27.10.45.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 27 Feb 2022 10:45:21 -0800 (PST) From: Kees Cook To: Kees Cook Cc: David Gow , "Gustavo A. R. Silva" , Nathan Chancellor , Nick Desaulniers , Rasmus Villemoes , Vitor Massaru Iha , Daniel Latypov , Anton Ivanov , Jeff Dike , Richard Weinberger , Masahiro Yamada , Arnd Bergmann , linux-kernel@vger.kernel.org, linux-um@lists.infradead.org, linux-kbuild@vger.kernel.org, kunit-dev@googlegroups.com, llvm@lists.linux.dev, x86@kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH v3 3/7] um: Cleanup syscall_handler_t definition/cast, fix warning Date: Sun, 27 Feb 2022 10:45:13 -0800 Message-Id: <20220227184517.504931-4-keescook@chromium.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220227184517.504931-1-keescook@chromium.org> References: <20220227184517.504931-1-keescook@chromium.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" X-Developer-Signature: v=1; a=openpgp-sha256; l=2860; i=keescook@chromium.org; h=from:subject; bh=x+dnSolAXYFL3BT0a5kvXMCMP6a5EsT3sg6+p2gJHGU=; b=owEBbQKS/ZANAwAKAYly9N/cbcAmAcsmYgBiG8a7yUYgXa1FT6iIYRcyFYXJrB5R00YlXTwQ84Dl ly57u+qJAjMEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCYhvGuwAKCRCJcvTf3G3AJizYEA CNb2bXcut1vDNHAoju2GPOc3OFs0G8V2WKCzzUKRK1IzqIDaSsvmZft2Zh01er3fyOo/fCw+N561JI dQ5RSNtSjGVoEb02yuUbZJRtB96/H1ByjVXwEzt3GmUh+YDqRCQh0516dzh2HKYejN2BpTZOdlSnoi HNT5GnI7w0PJW1CoarvIjIHPg8kQeXRS4LQIb0/xlPQRhr4wqrbQnmumuPRIhcdgCOeqYJYEmGJTWa XDrdOKdghbjEjNJQuwPrXMgxA0nbT5QV9kNPGe5ovoiT/MUw8jAyhmbAGfEffwgMCogtTMNQ31seeB VDr9NFJDVw/R/iIKpSmijT5XKvHnrbmYVscXr4YwhogN11OtdUBcWVcZ1oSkHmT8fnHVwHThhtlXQh r59GYhqhaWouBSz1pb/g/dcpu0530mr96aeOBz0o/ZADYRAPk59CVog0QBSVlILeLJuc2w63STCWPU HhGzGEYn9aWm+kE0jLdCpPi9VmLXZ6hRCtFkxhoujHW9W9YAAcdltYUcy1W1Hf5nSM6AdAvwsIM2cJ XiAk6mLRQydd2hnuKYvux1kouR/u+aqTKC6e384tsqmzrEh1eSZhFjgt3xgqkbOAu0j3EcRxMd6KWP p/0O+lB7e9hnEMcMyLksL0BlODvLslyBwJHpobDwFRAQPTrUdUvNGzIYIsjA== X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: David Gow The syscall_handler_t type for x86_64 was defined as 'long (*)(void)', but always cast to 'long (*)(long, long, long, long, long, long)' before use. This now triggers a warning (see below). Define syscall_handler_t as the latter instead, and remove the cast. This simplifies the code, and fixes the warning. Warning: In file included from ../arch/um/include/asm/processor-generic.h:13 from ../arch/x86/um/asm/processor.h:41 from ../include/linux/rcupdate.h:30 from ../include/linux/rculist.h:11 from ../include/linux/pid.h:5 from ../include/linux/sched.h:14 from ../include/linux/ptrace.h:6 from ../arch/um/kernel/skas/syscall.c:7: ../arch/um/kernel/skas/syscall.c: In function =E2=80=98handle_syscall=E2=80= =99: ../arch/x86/um/shared/sysdep/syscalls_64.h:18:11: warning: cast between inc= ompatible function types from =E2=80=98long int (*)(void)=E2=80=99 to =E2= =80=98long int (*)(long int, long int, long int, long int, long int, l= ong int)=E2=80=99 [ -Wcast-function-type] 18 | (((long (*)(long, long, long, long, long, long)) \ | ^ ../arch/x86/um/asm/ptrace.h:36:62: note: in definition of macro =E2=80=98PT= _REGS_SET_SYSCALL_RETURN=E2=80=99 36 | #define PT_REGS_SET_SYSCALL_RETURN(r, res) (PT_REGS_AX(r) =3D (res)) | ^~~ ../arch/um/kernel/skas/syscall.c:46:33: note: in expansion of macro =E2=80= =98EXECUTE_SYSCALL=E2=80=99 46 | EXECUTE_SYSCALL(syscall, regs)); | ^~~~~~~~~~~~~~~ Signed-off-by: David Gow Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20220210034353.1065703-1-davidgow@google.com Tested-by: David Gow --- This is just a re-send of the above linked patch, collecting it into this s= eries. --- arch/x86/um/shared/sysdep/syscalls_64.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/x86/um/shared/sysdep/syscalls_64.h b/arch/x86/um/shared/s= ysdep/syscalls_64.h index 48d6cd12f8a5..b6b997225841 100644 --- a/arch/x86/um/shared/sysdep/syscalls_64.h +++ b/arch/x86/um/shared/sysdep/syscalls_64.h @@ -10,13 +10,12 @@ #include #include =20 -typedef long syscall_handler_t(void); +typedef long syscall_handler_t(long, long, long, long, long, long); =20 extern syscall_handler_t *sys_call_table[]; =20 #define EXECUTE_SYSCALL(syscall, regs) \ - (((long (*)(long, long, long, long, long, long)) \ - (*sys_call_table[syscall]))(UPT_SYSCALL_ARG1(®s->regs), \ + (((*sys_call_table[syscall]))(UPT_SYSCALL_ARG1(®s->regs), \ UPT_SYSCALL_ARG2(®s->regs), \ UPT_SYSCALL_ARG3(®s->regs), \ UPT_SYSCALL_ARG4(®s->regs), \ --=20 2.32.0 From nobody Tue Jun 23 20:24:03 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 02058C433EF for ; Sun, 27 Feb 2022 18:45:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231370AbiB0SqP (ORCPT ); Sun, 27 Feb 2022 13:46:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53370 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231219AbiB0SqI (ORCPT ); Sun, 27 Feb 2022 13:46:08 -0500 Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2ABDB4ECD6 for ; Sun, 27 Feb 2022 10:45:23 -0800 (PST) Received: by mail-pl1-x636.google.com with SMTP id q11so8895302pln.11 for ; Sun, 27 Feb 2022 10:45:23 -0800 (PST) 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=hguOC+xPYO0eaAtZXq+RAjwSHPM/20IFHUGj359jpG8=; b=Vt+FMmf2Lvacdy2VablByMnnRD1mjjC9+gDyfFfDq1B8f1Y4ajQPMV0pNVAwM0HZ9+ ta7G8l5pJ+K0fPQjp9rdTxZyZvDIpiK8a22ZNIYRBfHI4U0rZifX7Zi4ZWRI4jtYa0tl LPTe8NuUbL6oMV+pLKAfdbADATj8s48JOZxcE= 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=hguOC+xPYO0eaAtZXq+RAjwSHPM/20IFHUGj359jpG8=; b=CkoNrafSFpoREu5Q3edRzdWpBYFY2MA02qtjPGVMObCXGzf83FpJ11biLy2dDuE2BZ ySvvOvtqsHcoNEVhYLYFF+LNg3t+NdJXyRLpRPe8jMb6LYdHQ73vfZlqebG4iTuOSg/b L8JmTjXkBBXsbVzdl6+YpTs7VeMOj1hDiNZak9JmFiYd4cnz5DwAp+MDqVosgNnIqJHg u8rggE24P+bKUqgRXQ8phxRKWfsfnqmV0tOA53EtmLbA1tBeIncbxDCvzQaLnZK8/AYw EoBA6RFObfvHey9xltveSmIGupkubnWAdGfFlWVne7PKcROHkxeGlWvbTSFouRJ4FWGP gQkw== X-Gm-Message-State: AOAM5313iGehVkIX4IyyaPGaw7vF70ah54bCmIX9wR5+Wn16gV/Mu302 6bXdpKYyHsmKars5hAUtKPv3+A== X-Google-Smtp-Source: ABdhPJwyo1rMccr+9zW0ZyrPf84LJWZt8qC3wyk+XmwEvTaVBmNHap92GcCcUQYiiBcW9n/4wUYQ/g== X-Received: by 2002:a17:902:8203:b0:14f:c36f:70c with SMTP id x3-20020a170902820300b0014fc36f070cmr17209832pln.95.1645987522375; Sun, 27 Feb 2022 10:45:22 -0800 (PST) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id bg3-20020a056a001f8300b004f40e8b3133sm694802pfb.188.2022.02.27.10.45.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 27 Feb 2022 10:45:21 -0800 (PST) From: Kees Cook To: Kees Cook Cc: David Gow , Anton Ivanov , "Gustavo A. R. Silva" , Nathan Chancellor , Nick Desaulniers , Rasmus Villemoes , Vitor Massaru Iha , Daniel Latypov , Jeff Dike , Richard Weinberger , Masahiro Yamada , Arnd Bergmann , linux-kernel@vger.kernel.org, linux-um@lists.infradead.org, linux-kbuild@vger.kernel.org, kunit-dev@googlegroups.com, llvm@lists.linux.dev, x86@kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH v3 4/7] um: Remove unused timeval_to_ns() function Date: Sun, 27 Feb 2022 10:45:14 -0800 Message-Id: <20220227184517.504931-5-keescook@chromium.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220227184517.504931-1-keescook@chromium.org> References: <20220227184517.504931-1-keescook@chromium.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1397; i=keescook@chromium.org; h=from:subject; bh=BBY0jyLtd6SE6A0Q+0QxoOVDMufJjpQntzXWcTVbBzQ=; b=owEBbQKS/ZANAwAKAYly9N/cbcAmAcsmYgBiG8a7pgTujxq03iEogLI3HZhrantD7izHXSbMposM 3ezh8hWJAjMEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCYhvGuwAKCRCJcvTf3G3AJvdxD/ oCEV1wTwasGpPxS1HOVrQMyGEgZMjg1DXdqdV6HOBfnHhLIsIzbWuxSG7ROL9d+etvNu4CZ+boboMy F7ft4nDST1eKRd78RKyyQPuhjph5qsS/hk7PIadhAeAy+zBCdKfXIPzdA+NlthXEVCBTJU7MfuhaS8 WnW0AsKPv7iPGwFgFd3xCJ9Bl4aLW8KtaOhcKju3e1VCGJ/s4Yzf+P9PKpsgoHBBjRJWAxHvpISG9J yuRL+4TvhGpwioQUFq1FxLJy3blx9iD3vtnGBT+uaTxYXgjQZ8DF6m/lUsVwR43OdedREO3Gle3h2O ArZdZq0I1UZ7NysvfZOXcGFyrF1+OrxIIee/APsPXfOUeFkk12RJNnNCBBXcFdv/AtnX69OORj4hLW 4VBpLH01GaHhh9bO+Nzgzoiygx0ZURY6DOIbGd85lHROMECQedbCVjnSZWrDz9aA0L2IaOw0Neipba vifUqc5dwEZaZaQ/qpTOeLvmmTlgrFN7xOfi4oLNykNb65NlKZm9AOveVJrTprb2lcc4Q+ssTRhJ79 66chg4/PouI37iL0kA7CQLexQvpIc9aUVlvvZ5E4N7heEOMbxZ85wYGG5KSjWp5dGCbDQ6UDSbqyQD PtbBq8sZX7srMnaXmhH0C7ni5QOuy5hpeXo9lOudn2EfJOcEdpCfihoVDUtg== X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: David Gow The timeval_to_ns() function doesn't appear to be used anywhere, as far as I (or git grep) can tell, and clang throws up a warning about it: ../arch/um/os-Linux/time.c:21:25: warning: unused function 'timeval_to_ns' = [-Wunused-function] static inline long long timeval_to_ns(const struct timeval *tv) ^ 1 warning generated. Signed-off-by: David Gow Acked-By: Anton Ivanov Link: https://lore.kernel.org/lkml/78d6ac17-9492-7c41-d6dd-4c92dce8ce62@cam= bridgegreys.com Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20220224081233.1765788-1-davidgow@google.com Tested-by: David Gow --- This is a resend of the above linked patch, just included in this series. --- arch/um/os-Linux/time.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 6c5041c5560b..4d5591d96d8c 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -18,12 +18,6 @@ =20 static timer_t event_high_res_timer =3D 0; =20 -static inline long long timeval_to_ns(const struct timeval *tv) -{ - return ((long long) tv->tv_sec * UM_NSEC_PER_SEC) + - tv->tv_usec * UM_NSEC_PER_USEC; -} - static inline long long timespec_to_ns(const struct timespec *ts) { return ((long long) ts->tv_sec * UM_NSEC_PER_SEC) + ts->tv_nsec; --=20 2.32.0 From nobody Tue Jun 23 20:24:03 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 571B1C43217 for ; Sun, 27 Feb 2022 18:45:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229601AbiB0SqS (ORCPT ); Sun, 27 Feb 2022 13:46:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53372 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231221AbiB0SqI (ORCPT ); Sun, 27 Feb 2022 13:46:08 -0500 Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F01E050453 for ; Sun, 27 Feb 2022 10:45:23 -0800 (PST) Received: by mail-pj1-x1031.google.com with SMTP id bx5so9229424pjb.3 for ; Sun, 27 Feb 2022 10:45:23 -0800 (PST) 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=BMkktAsNfHIhPa1AJtPClUlYlr4FtiZE1a3GDbCXgk4=; b=eH6EZmnqMckOS9O4oCCAOQ97Gk7PWZAVrFVwAHWRPKjSCasHblw8J3H51Cto/L4Oq/ 7zqDwL6uGdZO25v6bmjZhS2MBNmqdSItLdQ8tnbuPyKYCvQsgJaqVAw1FtxJcVe83/LS Zy2H2PJDdnwp3/ziVO/JJXQqpsFMARfT5Ychk= 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=BMkktAsNfHIhPa1AJtPClUlYlr4FtiZE1a3GDbCXgk4=; b=WrwG8tbDNTS6iNIxYhG1GAcUIFURRjTQ3BznLmXyETWbor0YMIx9yRteoxFAj3eq1W IK44yslvnh9V434myUsX4S3JQg81VS8Jumy+Fe9GP3wbqDrJFZjhSN+eQhSQlsFD/uNe ku/oTNEan9V5CckTvTLdYp1KGEGd7SG8PPc+3CyAzMSlCQ4+4GUfEir2DqjEaGPE/9CL FxK0F7mgFZTY8qvrcK6FRsWzkUK8SmsZD7IovAtlqTqALCfifHGbm6ffGgf/4esW40hm Ak2v5Kx9utln/Eqn3I9xrOXhy5nTk85csG7TXb/KlIpR5VMz8sdGn9uq3gn62++IiwNv DfrQ== X-Gm-Message-State: AOAM5327k9mVQmI1Hg4KBSBYBLa6XQu7PtNzOC56tz/FJuMqatnJT7uk FUl6ZiGr8DAxuW+Hsi9z98PmqA== X-Google-Smtp-Source: ABdhPJw84+Su+R84+skE0k1lOhQUbnaFmq9xBqLDdfjXiaJKJ64Oxb/qHpmbmqqlBln5RT3beTcbVA== X-Received: by 2002:a17:902:d705:b0:14e:e5a2:1b34 with SMTP id w5-20020a170902d70500b0014ee5a21b34mr16650742ply.88.1645987523283; Sun, 27 Feb 2022 10:45:23 -0800 (PST) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id y12-20020a62ce0c000000b004ec4d8900d5sm10038318pfg.163.2022.02.27.10.45.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 27 Feb 2022 10:45:23 -0800 (PST) From: Kees Cook To: Kees Cook Cc: Jeff Dike , Richard Weinberger , Anton Ivanov , Masahiro Yamada , Nick Desaulniers , Nathan Chancellor , David Gow , linux-um@lists.infradead.org, linux-kbuild@vger.kernel.org, linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com, llvm@lists.linux.dev, "Gustavo A. R. Silva" , Rasmus Villemoes , Vitor Massaru Iha , Daniel Latypov , Arnd Bergmann , linux-kernel@vger.kernel.org, x86@kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH v3 5/7] um: Allow builds with Clang Date: Sun, 27 Feb 2022 10:45:15 -0800 Message-Id: <20220227184517.504931-6-keescook@chromium.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220227184517.504931-1-keescook@chromium.org> References: <20220227184517.504931-1-keescook@chromium.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3536; h=from:subject; bh=9QnH+z+rCwCFrRsn/51gPTE+pPH8ccRFsd0v6DZGBGk=; b=owEBbQKS/ZANAwAKAYly9N/cbcAmAcsmYgBiG8a8dEBk1HwrxEO2kL1Oda4tIa5yb6JeGO7Q8F+W TXMu3eKJAjMEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCYhvGvAAKCRCJcvTf3G3AJh5fD/ 9KuzRhMOYg8agcaXgdhk9bHElsujSJHIv4H/iYy4vhIm5y+K4au1niInCr8gbRxN8h9SSpzFeHVeOV A+xuZDPDYD0/lGfOoYtZpV2f9uQZVbCu2O4DEne9NwKDTvoIRjBem9qfJmbhHpG6gcFnEYy8IA3/oe YoJUrjDoIKakakFQ0EWS7Y3OF6mZutVETPOUUBQJJ6FTmaXehOi2JRWbE5M0Y6f1utAKkHM7GQObJl gp4Y6NzKu3MsgDQC/PitvlV7wxex2381qQKHfMjaBXLtUKLizYHyvbjWStV9XM2J6VbCt0BU/LV+yJ qDs59Ih223zt/j7TbKxTAjrwLIX+byh70A+0o9K4CJvWbyAJ9X5CnAccGvf1HCW28QwuyLrpTwSAy8 YiSKxd9UxcYUI4/CDSV+8r72iiUkt7nWG1Ygv1E416BjhxHrDuk2k7nFssdZEYfIlDIqQA8ey/QpWf d48v7LOCx1Cui2GUH/XGI/QqDM7TOISr58NfvoT02QrJ398Hk/EovB9Y1CzFA+hlUrdcmRLnfw+THt WQvvUo7T7/w80plD1UFpTjsxcPq6znVhO0NCDULvpyGKXfCqzxri43YBojcrgwA4vXNVIrRUeaC5RW nBl0txZW59SpCiVLjlI9W0bmg+VGOmyOQGYcXCJo4mdIvb2DjeBGm21cJnyA== X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add SUBARCH target for Clang+um (which must go last, not alphabetically, so the other SUBARCHes are assigned). Remove open-coded "DEFINE" macro, instead using linux/kbuild.h's version which was updated to use Clang-friendly assembly in commit cf0c3e68aa81 ("kbuild: fix asm-offset generation to work with clang"). Redefine "DEFINE_LONGS" in terms of "COMMENT" and "DEFINE" so that the intended coment actually has useful content. Add a missed "break" to avoid implicit fall-through warnings. This lets me run KUnit tests with Clang: $ ./tools/testing/kunit/kunit.py run --make_options LLVM=3D1 ... Cc: Jeff Dike Cc: Richard Weinberger Cc: Anton Ivanov Cc: Masahiro Yamada Cc: Nick Desaulniers Cc: Nathan Chancellor Cc: David Gow Cc: linux-um@lists.infradead.org Cc: linux-kbuild@vger.kernel.org Cc: linux-kselftest@vger.kernel.org Cc: kunit-dev@googlegroups.com Cc: llvm@lists.linux.dev Reviewed-by: Nathan Chancellor Link: https://lore.kernel.org/lkml/Yg2YubZxvYvx7%2Fnm@dev-arch.archlinux-ax= 161/ Tested-by: David Gow Link: https://lore.kernel.org/lkml/CABVgOSk=3DoFxsbSbQE-v65VwR2+mXeGXDDjzq8= t7FShwjJ3+kUg@mail.gmail.com/ Signed-off-by: Kees Cook --- v1: https://lore.kernel.org/lkml/20220217002843.2312603-1-keescook@chromium= .org v2: https://lore.kernel.org/lkml/20220224055831.1854786-1-keescook@chromium= .org v3: - use kbuild.h to avoid duplication (Masahiro) - fix intended comments (Masahiro) - use SUBARCH (Nathan) --- arch/um/os-Linux/execvp.c | 1 + arch/x86/um/user-offsets.c | 9 ++++----- scripts/Makefile.clang | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/um/os-Linux/execvp.c b/arch/um/os-Linux/execvp.c index 84a0777c2a45..c09a5fd5e225 100644 --- a/arch/um/os-Linux/execvp.c +++ b/arch/um/os-Linux/execvp.c @@ -93,6 +93,7 @@ int execvp_noalloc(char *buf, const char *file, char *con= st argv[]) up finding no executable we can use, we want to diagnose that we did find one but were denied access. */ got_eacces =3D 1; + break; case ENOENT: case ESTALE: case ENOTDIR: diff --git a/arch/x86/um/user-offsets.c b/arch/x86/um/user-offsets.c index bae61554abcc..e54a9814ccf1 100644 --- a/arch/x86/um/user-offsets.c +++ b/arch/x86/um/user-offsets.c @@ -8,12 +8,11 @@ #define __FRAME_OFFSETS #include #include +#include =20 -#define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) - -#define DEFINE_LONGS(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long))) +#define DEFINE_LONGS(sym, val) \ + COMMENT(#val " / sizeof(unsigned long)"); \ + DEFINE(sym, val / sizeof(unsigned long)) =20 void foo(void) { diff --git a/scripts/Makefile.clang b/scripts/Makefile.clang index 51fc23e2e9e5..87285b76adb2 100644 --- a/scripts/Makefile.clang +++ b/scripts/Makefile.clang @@ -10,6 +10,7 @@ CLANG_TARGET_FLAGS_powerpc :=3D powerpc64le-linux-gnu CLANG_TARGET_FLAGS_riscv :=3D riscv64-linux-gnu CLANG_TARGET_FLAGS_s390 :=3D s390x-linux-gnu CLANG_TARGET_FLAGS_x86 :=3D x86_64-linux-gnu +CLANG_TARGET_FLAGS_um :=3D $(CLANG_TARGET_FLAGS_$(SUBARCH)) CLANG_TARGET_FLAGS :=3D $(CLANG_TARGET_FLAGS_$(SRCARCH)) =20 ifeq ($(CROSS_COMPILE),) --=20 2.32.0 From nobody Tue Jun 23 20:24:03 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1A4B9C433EF for ; Sun, 27 Feb 2022 18:45:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231452AbiB0SqY (ORCPT ); Sun, 27 Feb 2022 13:46:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53442 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231265AbiB0SqJ (ORCPT ); Sun, 27 Feb 2022 13:46:09 -0500 Received: from mail-pj1-x1032.google.com (mail-pj1-x1032.google.com [IPv6:2607:f8b0:4864:20::1032]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 599D259A4F for ; Sun, 27 Feb 2022 10:45:24 -0800 (PST) Received: by mail-pj1-x1032.google.com with SMTP id bx5so9229431pjb.3 for ; Sun, 27 Feb 2022 10:45:24 -0800 (PST) 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=q6m+DhiSNpp0WEg7Y2GFtce2qoilswFv9XNCymBz300=; b=adurY7lnz6k4Lj7dGkSWg3wTjUo42w1bdJZXLgnRdjA8hkoEPM7J4cvLrp/CrDlLZl Kp5lTQEv4oXe/qyvj2H1tsFXgV69fEpPRjxajXYVyMOv4OHWkZ3G6MpUWIT0wSgreplv PXCW9ylgqLq1EAmFd14NpGlzCdpa8Ed3aenmM= 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=q6m+DhiSNpp0WEg7Y2GFtce2qoilswFv9XNCymBz300=; b=WAVholQWEbgXEoPwo7feDrGFcl47G8KQnPupjSiTvxI1zbzd8RVKNxpgWirUmC2wAa sd/iuUiHVrqXy3d7ptlpYHuSEY0x412/+hEvKdUGRah+gUx/iIV4nYMhVqqFNmEURPNO AaP4p0DQt/KAZBT9lHfFE5WXg5mhMlmxtzI8YocEKjNI2GnjJwpA1QVGfWEZss0cAM0B UzxmGt13dOCbA0+enpjygH1y1LM+SmC4tdr3Pt3K7yg0edrJiUz242Vv1b85+gLk0xwu 2wMzeIgcUEXYP17Zx4Tun8l7cSnrKKW3TdgxykLM52sZZ5zvB4kdTIR3Kf+smZgrjNMN 9ZYg== X-Gm-Message-State: AOAM531mNOBPp3LvxIxApwVZ3uWsFHvb8EI3a/cVZjBDRfGchax+4bDg 5V1lPUCknQ2gL4kV7rkikjMOCA== X-Google-Smtp-Source: ABdhPJwSlhs6c8I9Lo6GGuabSIXJWoTu3k7tDJKSwX1nd4WRcf7i7kGNzdvNDJBsvRw8NeGFJP+y+Q== X-Received: by 2002:a17:902:d4d1:b0:150:1d1c:30bd with SMTP id o17-20020a170902d4d100b001501d1c30bdmr15303539plg.1.1645987523611; Sun, 27 Feb 2022 10:45:23 -0800 (PST) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id o10-20020a056a0015ca00b004e0ff94313esm11270971pfu.91.2022.02.27.10.45.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 27 Feb 2022 10:45:23 -0800 (PST) From: Kees Cook To: Kees Cook Cc: David Gow , Daniel Latypov , Arnd Bergmann , "Gustavo A. R. Silva" , Nathan Chancellor , Nick Desaulniers , Rasmus Villemoes , Vitor Massaru Iha , Anton Ivanov , Jeff Dike , Richard Weinberger , Masahiro Yamada , linux-kernel@vger.kernel.org, linux-um@lists.infradead.org, linux-kbuild@vger.kernel.org, kunit-dev@googlegroups.com, llvm@lists.linux.dev, x86@kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH v3 6/7] lib: stackinit: Convert to KUnit Date: Sun, 27 Feb 2022 10:45:16 -0800 Message-Id: <20220227184517.504931-7-keescook@chromium.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220227184517.504931-1-keescook@chromium.org> References: <20220227184517.504931-1-keescook@chromium.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=18150; h=from:subject; bh=UP9YVxfMlY8O0+NQMLGofpK4VLIvcpYgNEp/ewL3Cy0=; b=owEBbQKS/ZANAwAKAYly9N/cbcAmAcsmYgBiG8a8zSAsXG7oEnfr4TxZoZxcd4Pag+vI1Jn94X84 /Vw1XsGJAjMEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCYhvGvAAKCRCJcvTf3G3AJjCiD/ 0aDe79UaDsyIhrBubBQeRFGV5QTV312hqgfejYoVW3REqLHpl78/fSarG3KikpGeFhv1YY0RcRM+LB cK57iEymCQLba9GlFso5OpTJToY/PjfR7MdxaKgNDVPwQi2NMFIA7gyqoiKZsOBXxJ5x4jYCH1Eiim /B2r2PzGMQC1gXPAlZUi9SrWk7VG9xVFtI2d35Ki7YXslzg7B5/2lwufNFNBaLpoAszcwuKKGZ0xbE njN41caNWtAz1mNT6PlY2vpI/yLkQU38Zq4CdOmmTl8FVL1N+/fpBsc9dnhQcgbuxf2Tr+56NriT1/ y39P7GrZ/F6upX1PxoAMj2Q1FMFERWjLra2zRy8a9m8cxyGcrrkDP3CuqeyusBU0pfLYyQstsNFzhr D+NTQrT2sA8Owp5qm5oHhVqLK5ffOr8T23fQlfdaXqOlzQ0OLngadBP8F1MoMsIvaOM5M1c0W30RYl AK6fvvMbQVMzXs1KYhWTIYIy7saF7GE5bkGm8ILXL/bl9DSo1qKyCk1RakqLj+Uae9gEKF2R1DWBmZ u3kSM4yxBfl3kbobot0gBrqat9yf9vdWWka4EsDWulrAykZB5rGiUXgx4Cf2S62VwtKeVy9hj++1Rp zYZWWyU1BqVm+FQrm3AitOiotMe+NuQz/twVybOPywFHWrllAtWKN6S5obvQ== X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Convert stackinit unit tests to KUnit, for better integration into the kernel self test framework. Includes a rename of test_stackinit.c to stackinit_kunit.c, and CONFIG_TEST_STACKINIT to CONFIG_STACKINIT_KUNIT_TEST. Adjust expected test results based on which stack initialization method was chosen: $ CMD=3D"./tools/testing/kunit/kunit.py run stackinit --raw_output \ --arch=3Dx86_64 --kconfig_add" $ $CMD | grep stackinit: # stackinit: pass:36 fail:0 skip:29 total:65 $ $CMD CONFIG_GCC_PLUGIN_STRUCTLEAK_USER=3Dy | grep stackinit: # stackinit: pass:37 fail:0 skip:28 total:65 $ $CMD CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF=3Dy | grep stackinit: # stackinit: pass:55 fail:0 skip:10 total:65 $ $CMD CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL=3Dy | grep stackinit: # stackinit: pass:62 fail:0 skip:3 total:65 $ $CMD CONFIG_INIT_STACK_ALL_PATTERN=3Dy --make_option LLVM=3D1 | grep sta= ckinit: # stackinit: pass:60 fail:0 skip:5 total:65 $ $CMD CONFIG_INIT_STACK_ALL_ZERO=3Dy --make_option LLVM=3D1 | grep stacki= nit: # stackinit: pass:60 fail:0 skip:5 total:65 Temporarily remove the userspace-build mode, which will be restored in a later patch. Expand the size of the pre-case switch variable so it doesn't get accidentally cleared. Cc: David Gow Cc: Daniel Latypov Cc: Arnd Bergmann Signed-off-by: Kees Cook Tested-by: David Gow --- v1: https://lore.kernel.org/lkml/20220224055145.1853657-1-keescook@chromium= .org v2: - split "userspace KUnit stub" into separate header and patch (Daniel) - Improve commit log and comments (David) - Provide mapping of expected XFAIL tests to CONFIGs (David) --- lib/Kconfig.debug | 22 +- lib/Makefile | 4 +- lib/{test_stackinit.c =3D> stackinit_kunit.c} | 269 ++++++++------------ 3 files changed, 121 insertions(+), 174 deletions(-) rename lib/{test_stackinit.c =3D> stackinit_kunit.c} (66%) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 14d90d03bc8d..a5556ab05240 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -2511,6 +2511,17 @@ config OVERFLOW_KUNIT_TEST =20 If unsure, say N. =20 +config STACKINIT_KUNIT_TEST + tristate "Test level of stack variable initialization" if !KUNIT_ALL_TESTS + depends on KUNIT + default KUNIT_ALL_TESTS + help + Test if the kernel is zero-initializing stack variables and + padding. Coverage is controlled by compiler flags, + CONFIG_INIT_STACK_ALL_PATTERN, CONFIG_INIT_STACK_ALL_ZERO, + CONFIG_GCC_PLUGIN_STRUCTLEAK, CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF, + or CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL. + config TEST_UDELAY tristate "udelay test driver" help @@ -2602,17 +2613,6 @@ config TEST_OBJAGG Enable this option to test object aggregation manager on boot (or module load). =20 - -config TEST_STACKINIT - tristate "Test level of stack variable initialization" - help - Test if the kernel is zero-initializing stack variables and - padding. Coverage is controlled by compiler flags, - CONFIG_GCC_PLUGIN_STRUCTLEAK, CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF, - or CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL. - - If unsure, say N. - config TEST_MEMINIT tristate "Test heap/page initialization" help diff --git a/lib/Makefile b/lib/Makefile index fdfcbfaff32f..353bc09ce38d 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -93,8 +93,6 @@ obj-$(CONFIG_TEST_KMOD) +=3D test_kmod.o obj-$(CONFIG_TEST_DEBUG_VIRTUAL) +=3D test_debug_virtual.o obj-$(CONFIG_TEST_MEMCAT_P) +=3D test_memcat_p.o obj-$(CONFIG_TEST_OBJAGG) +=3D test_objagg.o -CFLAGS_test_stackinit.o +=3D $(call cc-disable-warning, switch-unreachable) -obj-$(CONFIG_TEST_STACKINIT) +=3D test_stackinit.o obj-$(CONFIG_TEST_BLACKHOLE_DEV) +=3D test_blackhole_dev.o obj-$(CONFIG_TEST_MEMINIT) +=3D test_meminit.o obj-$(CONFIG_TEST_LOCKUP) +=3D test_lockup.o @@ -363,6 +361,8 @@ obj-$(CONFIG_CMDLINE_KUNIT_TEST) +=3D cmdline_kunit.o obj-$(CONFIG_SLUB_KUNIT_TEST) +=3D slub_kunit.o obj-$(CONFIG_MEMCPY_KUNIT_TEST) +=3D memcpy_kunit.o obj-$(CONFIG_OVERFLOW_KUNIT_TEST) +=3D overflow_kunit.o +CFLAGS_stackinit_kunit.o +=3D $(call cc-disable-warning, switch-unreachabl= e) +obj-$(CONFIG_STACKINIT_KUNIT_TEST) +=3D stackinit_kunit.o =20 obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) +=3D devmem_is_allowed.o =20 diff --git a/lib/test_stackinit.c b/lib/stackinit_kunit.c similarity index 66% rename from lib/test_stackinit.c rename to lib/stackinit_kunit.c index a3c74e6a21ff..35c69aa425b2 100644 --- a/lib/test_stackinit.c +++ b/lib/stackinit_kunit.c @@ -2,76 +2,21 @@ /* * Test cases for compiler-based stack variable zeroing via * -ftrivial-auto-var-init=3D{zero,pattern} or CONFIG_GCC_PLUGIN_STRUCTLEA= K*. + * For example, see: + * https://www.kernel.org/doc/html/latest/dev-tools/kunit/kunit-tool.html#= configuring-building-and-running-tests + * ./tools/testing/kunit/kunit.py run stackinit [--raw_output] \ + * --make_option LLVM=3D1 \ + * --kconfig_add CONFIG_INIT_STACK_ALL_ZERO=3Dy * - * External build example: - * clang -O2 -Wall -ftrivial-auto-var-init=3Dpattern \ - * -o test_stackinit test_stackinit.c */ -#ifdef __KERNEL__ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt =20 +#include #include #include #include #include =20 -#else - -/* Userspace headers. */ -#include -#include -#include -#include -#include -#include - -/* Linux kernel-ism stubs for stand-alone userspace build. */ -#define KBUILD_MODNAME "stackinit" -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#define pr_err(fmt, ...) fprintf(stderr, pr_fmt(fmt), ##__VA_ARGS__) -#define pr_warn(fmt, ...) fprintf(stderr, pr_fmt(fmt), ##__VA_ARGS__) -#define pr_info(fmt, ...) fprintf(stdout, pr_fmt(fmt), ##__VA_ARGS__) -#define __init /**/ -#define __exit /**/ -#define __user /**/ -#define noinline __attribute__((__noinline__)) -#define __aligned(x) __attribute__((__aligned__(x))) -#ifdef __clang__ -# define __compiletime_error(message) /**/ -#else -# define __compiletime_error(message) __attribute__((__error__(message))) -#endif -#define __compiletime_assert(condition, msg, prefix, suffix) \ - do { \ - extern void prefix ## suffix(void) __compiletime_error(msg); \ - if (!(condition)) \ - prefix ## suffix(); \ - } while (0) -#define _compiletime_assert(condition, msg, prefix, suffix) \ - __compiletime_assert(condition, msg, prefix, suffix) -#define compiletime_assert(condition, msg) \ - _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) -#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg) -#define BUILD_BUG_ON(condition) \ - BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition) -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; - -#define module_init(func) static int (*do_init)(void) =3D func -#define module_exit(func) static void (*do_exit)(void) =3D func -#define MODULE_LICENSE(str) int main(void) { \ - int rc; \ - /* License: str */ \ - rc =3D do_init(); \ - if (rc =3D=3D 0) \ - do_exit(); \ - return rc; \ - } - -#endif /* __KERNEL__ */ - /* Exfiltration buffer. */ #define MAX_VAR_SIZE 128 static u8 check_buf[MAX_VAR_SIZE]; @@ -201,7 +146,7 @@ static bool range_contains(char *haystack_start, size_t= haystack_size, */ #define DEFINE_TEST_DRIVER(name, var_type, which, xfail) \ /* Returns 0 on success, 1 on failure. */ \ -static noinline __init int test_ ## name (void) \ +static noinline void test_ ## name (struct kunit *test) \ { \ var_type zero INIT_CLONE_ ## which; \ int ignored; \ @@ -220,10 +165,8 @@ static noinline __init int test_ ## name (void) \ /* Verify all bytes overwritten with 0xFF. */ \ for (sum =3D 0, i =3D 0; i < target_size; i++) \ sum +=3D (check_buf[i] !=3D 0xFF); \ - if (sum) { \ - pr_err(#name ": leaf fill was not 0xFF!?\n"); \ - return 1; \ - } \ + KUNIT_ASSERT_EQ_MSG(test, sum, 0, \ + "leaf fill was not 0xFF!?\n"); \ /* Clear entire check buffer for later bit tests. */ \ memset(check_buf, 0x00, sizeof(check_buf)); \ /* Extract stack-defined variable contents. */ \ @@ -231,32 +174,29 @@ static noinline __init int test_ ## name (void) \ FETCH_ARG_ ## which(zero)); \ \ /* Validate that compiler lined up fill and target. */ \ - if (!range_contains(fill_start, fill_size, \ - target_start, target_size)) { \ - pr_err(#name ": stack fill missed target!?\n"); \ - pr_err(#name ": fill %zu wide\n", fill_size); \ - pr_err(#name ": target offset by %d\n", \ - (int)((ssize_t)(uintptr_t)fill_start - \ - (ssize_t)(uintptr_t)target_start)); \ - return 1; \ - } \ + KUNIT_ASSERT_TRUE_MSG(test, \ + range_contains(fill_start, fill_size, \ + target_start, target_size), \ + "stack fill missed target!? " \ + "(fill %zu wide, target offset by %d)\n", \ + fill_size, \ + (int)((ssize_t)(uintptr_t)fill_start - \ + (ssize_t)(uintptr_t)target_start)); \ \ /* Look for any bytes still 0xFF in check region. */ \ for (sum =3D 0, i =3D 0; i < target_size; i++) \ sum +=3D (check_buf[i] =3D=3D 0xFF); \ \ - if (sum =3D=3D 0) { \ - pr_info(#name " ok\n"); \ - return 0; \ - } else { \ - pr_warn(#name " %sFAIL (uninit bytes: %d)\n", \ - (xfail) ? "X" : "", sum); \ - return (xfail) ? 0 : 1; \ - } \ + if (sum !=3D 0 && xfail) \ + kunit_skip(test, \ + "XFAIL uninit bytes: %d\n", \ + sum); \ + KUNIT_ASSERT_EQ_MSG(test, sum, 0, \ + "uninit bytes: %d\n", sum); \ } #define DEFINE_TEST(name, var_type, which, init_level, xfail) \ /* no-op to force compiler into ignoring "uninitialized" vars */\ -static noinline __init DO_NOTHING_TYPE_ ## which(var_type) \ +static noinline DO_NOTHING_TYPE_ ## which(var_type) \ do_nothing_ ## name(var_type *ptr) \ { \ /* Will always be true, but compiler doesn't know. */ \ @@ -265,9 +205,8 @@ do_nothing_ ## name(var_type *ptr) \ else \ return DO_NOTHING_RETURN_ ## which(ptr + 1); \ } \ -static noinline __init int leaf_ ## name(unsigned long sp, \ - bool fill, \ - var_type *arg) \ +static noinline int leaf_ ## name(unsigned long sp, bool fill, \ + var_type *arg) \ { \ char buf[VAR_BUFFER]; \ var_type var \ @@ -341,6 +280,27 @@ struct test_user { unsigned long four; }; =20 +#define ALWAYS_PASS WANT_SUCCESS +#define ALWAYS_FAIL XFAIL + +#ifdef CONFIG_INIT_STACK_NONE +# define USER_PASS XFAIL +# define BYREF_PASS XFAIL +# define STRONG_PASS XFAIL +#elif defined(CONFIG_GCC_PLUGIN_STRUCTLEAK_USER) +# define USER_PASS WANT_SUCCESS +# define BYREF_PASS XFAIL +# define STRONG_PASS XFAIL +#elif defined(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF) +# define USER_PASS WANT_SUCCESS +# define BYREF_PASS WANT_SUCCESS +# define STRONG_PASS XFAIL +#else +# define USER_PASS WANT_SUCCESS +# define BYREF_PASS WANT_SUCCESS +# define STRONG_PASS WANT_SUCCESS +#endif + #define DEFINE_SCALAR_TEST(name, init, xfail) \ DEFINE_TEST(name ## _ ## init, name, SCALAR, \ init, xfail) @@ -364,27 +324,26 @@ struct test_user { DEFINE_STRUCT_TEST(trailing_hole, init, xfail); \ DEFINE_STRUCT_TEST(packed, init, xfail) =20 -#define DEFINE_STRUCT_INITIALIZER_TESTS(base) \ +#define DEFINE_STRUCT_INITIALIZER_TESTS(base, xfail) \ DEFINE_STRUCT_TESTS(base ## _ ## partial, \ - WANT_SUCCESS); \ - DEFINE_STRUCT_TESTS(base ## _ ## all, \ - WANT_SUCCESS) + xfail); \ + DEFINE_STRUCT_TESTS(base ## _ ## all, xfail) =20 /* These should be fully initialized all the time! */ -DEFINE_SCALAR_TESTS(zero, WANT_SUCCESS); -DEFINE_STRUCT_TESTS(zero, WANT_SUCCESS); +DEFINE_SCALAR_TESTS(zero, ALWAYS_PASS); +DEFINE_STRUCT_TESTS(zero, ALWAYS_PASS); /* Struct initializers: padding may be left uninitialized. */ -DEFINE_STRUCT_INITIALIZER_TESTS(static); -DEFINE_STRUCT_INITIALIZER_TESTS(dynamic); -DEFINE_STRUCT_INITIALIZER_TESTS(runtime); -DEFINE_STRUCT_INITIALIZER_TESTS(assigned_static); -DEFINE_STRUCT_INITIALIZER_TESTS(assigned_dynamic); -DEFINE_STRUCT_TESTS(assigned_copy, XFAIL); +DEFINE_STRUCT_INITIALIZER_TESTS(static, STRONG_PASS); +DEFINE_STRUCT_INITIALIZER_TESTS(dynamic, STRONG_PASS); +DEFINE_STRUCT_INITIALIZER_TESTS(runtime, STRONG_PASS); +DEFINE_STRUCT_INITIALIZER_TESTS(assigned_static, STRONG_PASS); +DEFINE_STRUCT_INITIALIZER_TESTS(assigned_dynamic, STRONG_PASS); +DEFINE_STRUCT_TESTS(assigned_copy, ALWAYS_FAIL); /* No initialization without compiler instrumentation. */ -DEFINE_SCALAR_TESTS(none, WANT_SUCCESS); -DEFINE_STRUCT_TESTS(none, WANT_SUCCESS); +DEFINE_SCALAR_TESTS(none, STRONG_PASS); +DEFINE_STRUCT_TESTS(none, BYREF_PASS); /* Initialization of members with __user attribute. */ -DEFINE_TEST(user, struct test_user, STRUCT, none, WANT_SUCCESS); +DEFINE_TEST(user, struct test_user, STRUCT, none, USER_PASS); =20 /* * Check two uses through a variable declaration outside either path, @@ -398,7 +357,7 @@ static int noinline __leaf_switch_none(int path, bool f= ill) * This is intentionally unreachable. To silence the * warning, build with -Wno-switch-unreachable */ - uint64_t var; + uint64_t var[10]; =20 case 1: target_start =3D &var; @@ -423,19 +382,19 @@ static int noinline __leaf_switch_none(int path, bool= fill) memcpy(check_buf, target_start, target_size); break; default: - var =3D 5; - return var & forced_mask; + var[1] =3D 5; + return var[1] & forced_mask; } return 0; } =20 -static noinline __init int leaf_switch_1_none(unsigned long sp, bool fill, +static noinline int leaf_switch_1_none(unsigned long sp, bool fill, uint64_t *arg) { return __leaf_switch_none(1, fill); } =20 -static noinline __init int leaf_switch_2_none(unsigned long sp, bool fill, +static noinline int leaf_switch_2_none(unsigned long sp, bool fill, uint64_t *arg) { return __leaf_switch_none(2, fill); @@ -447,68 +406,56 @@ static noinline __init int leaf_switch_2_none(unsigne= d long sp, bool fill, * non-code areas (i.e. in a switch statement before the first "case"). * https://bugs.llvm.org/show_bug.cgi?id=3D44916 */ -DEFINE_TEST_DRIVER(switch_1_none, uint64_t, SCALAR, XFAIL); -DEFINE_TEST_DRIVER(switch_2_none, uint64_t, SCALAR, XFAIL); - -static int __init test_stackinit_init(void) -{ - unsigned int failures =3D 0; - -#define test_scalars(init) do { \ - failures +=3D test_u8_ ## init (); \ - failures +=3D test_u16_ ## init (); \ - failures +=3D test_u32_ ## init (); \ - failures +=3D test_u64_ ## init (); \ - failures +=3D test_char_array_ ## init (); \ - } while (0) - -#define test_structs(init) do { \ - failures +=3D test_small_hole_ ## init (); \ - failures +=3D test_big_hole_ ## init (); \ - failures +=3D test_trailing_hole_ ## init (); \ - failures +=3D test_packed_ ## init (); \ - } while (0) - +DEFINE_TEST_DRIVER(switch_1_none, uint64_t, SCALAR, ALWAYS_FAIL); +DEFINE_TEST_DRIVER(switch_2_none, uint64_t, SCALAR, ALWAYS_FAIL); + +#define KUNIT_test_scalars(init) \ + KUNIT_CASE(test_u8_ ## init), \ + KUNIT_CASE(test_u16_ ## init), \ + KUNIT_CASE(test_u32_ ## init), \ + KUNIT_CASE(test_u64_ ## init), \ + KUNIT_CASE(test_char_array_ ## init) + +#define KUNIT_test_structs(init) \ + KUNIT_CASE(test_small_hole_ ## init), \ + KUNIT_CASE(test_big_hole_ ## init), \ + KUNIT_CASE(test_trailing_hole_ ## init),\ + KUNIT_CASE(test_packed_ ## init) \ + +static struct kunit_case stackinit_test_cases[] =3D { /* These are explicitly initialized and should always pass. */ - test_scalars(zero); - test_structs(zero); + KUNIT_test_scalars(zero), + KUNIT_test_structs(zero), /* Padding here appears to be accidentally always initialized? */ - test_structs(dynamic_partial); - test_structs(assigned_dynamic_partial); + KUNIT_test_structs(dynamic_partial), + KUNIT_test_structs(assigned_dynamic_partial), /* Padding initialization depends on compiler behaviors. */ - test_structs(static_partial); - test_structs(static_all); - test_structs(dynamic_all); - test_structs(runtime_partial); - test_structs(runtime_all); - test_structs(assigned_static_partial); - test_structs(assigned_static_all); - test_structs(assigned_dynamic_all); + KUNIT_test_structs(static_partial), + KUNIT_test_structs(static_all), + KUNIT_test_structs(dynamic_all), + KUNIT_test_structs(runtime_partial), + KUNIT_test_structs(runtime_all), + KUNIT_test_structs(assigned_static_partial), + KUNIT_test_structs(assigned_static_all), + KUNIT_test_structs(assigned_dynamic_all), /* Everything fails this since it effectively performs a memcpy(). */ - test_structs(assigned_copy); - + KUNIT_test_structs(assigned_copy), /* STRUCTLEAK_BYREF_ALL should cover everything from here down. */ - test_scalars(none); - failures +=3D test_switch_1_none(); - failures +=3D test_switch_2_none(); - + KUNIT_test_scalars(none), + KUNIT_CASE(test_switch_1_none), + KUNIT_CASE(test_switch_2_none), /* STRUCTLEAK_BYREF should cover from here down. */ - test_structs(none); - + KUNIT_test_structs(none), /* STRUCTLEAK will only cover this. */ - failures +=3D test_user(); - - if (failures =3D=3D 0) - pr_info("all tests passed!\n"); - else - pr_err("failures: %u\n", failures); + KUNIT_CASE(test_user), + {} +}; =20 - return failures ? -EINVAL : 0; -} -module_init(test_stackinit_init); +static struct kunit_suite stackinit_test_suite =3D { + .name =3D "stackinit", + .test_cases =3D stackinit_test_cases, +}; =20 -static void __exit test_stackinit_exit(void) -{ } -module_exit(test_stackinit_exit); +kunit_test_suites(&stackinit_test_suite); =20 MODULE_LICENSE("GPL"); --=20 2.32.0 From nobody Tue Jun 23 20:24:03 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5A517C433EF for ; Sun, 27 Feb 2022 18:45:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231534AbiB0Sqa (ORCPT ); Sun, 27 Feb 2022 13:46:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53358 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231243AbiB0SqJ (ORCPT ); Sun, 27 Feb 2022 13:46:09 -0500 Received: from mail-pg1-x52d.google.com (mail-pg1-x52d.google.com [IPv6:2607:f8b0:4864:20::52d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3723128E1E for ; Sun, 27 Feb 2022 10:45:24 -0800 (PST) Received: by mail-pg1-x52d.google.com with SMTP id bc27so686092pgb.4 for ; Sun, 27 Feb 2022 10:45:24 -0800 (PST) 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=EWQuW1pZiUPIz4vJWrH7gUOgoQp6sbO55rWZ8FArGBo=; b=HLkqZFFlTh5+wey7xEt6qvB2xnXL8ejZbXQpwYg5M1Hu1M39jy+KYOCy7/GkcvyadB BI27ZEoyAs5JPMjoehKWQKvoBalf8/7INAiq3V+ogadzoquBwdpxG2sGl1D3AwUozWZe 1cb8DNTjkn+F/UQfsvc/MiKw8lt/uudrXvxGY= 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=EWQuW1pZiUPIz4vJWrH7gUOgoQp6sbO55rWZ8FArGBo=; b=SxZkuDMnTqF+cHCtG5lL5d/57iZks54MUgDcOsZ9OhTJxj2plOsbLbUu2V8EeD/gfZ 2qJ+tywQk4IZIOi046+mHINDq2gLaY6kAMlIY0wKG3b3RWRIxaDKyCBIaGpbPGClAXuC E4alpl2BYhrBve25UR+cpCJfzePCqD9JtFSF9dsPZZ38lBWjEm1P07DBVa6PQRThIFjM rmgCnDc2T//qiMQqPFLohUuOQJqTZDD1wEhIdvLVzaOAa4qj52bwNlUW0GS/ifhZ1MSh qFSVzxS+0Y34S+Tt+ptlAFZouPh80N1MVE3DtWRmDzRNVpS5dRmDPK1QGHkoqHRpWIi5 E7+A== X-Gm-Message-State: AOAM531Ms5ye98L5+0b4gf1FbyeyFopNTFW2+hRkMrtTg8FpGyly/5ib wncWjnQUBwLjnM0PZxbxrJEPDQ== X-Google-Smtp-Source: ABdhPJzYJK2sbqKeWGcVXkV09fnJetSZa1jM/ltSYX5lABvFLKwJcjqTK4mm3tuldsTqkNji510KUQ== X-Received: by 2002:a05:6a00:140b:b0:4e1:2cbd:30ba with SMTP id l11-20020a056a00140b00b004e12cbd30bamr17894766pfu.46.1645987523441; Sun, 27 Feb 2022 10:45:23 -0800 (PST) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id 17-20020a056a00071100b004f0f941d1e8sm9954418pfl.24.2022.02.27.10.45.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 27 Feb 2022 10:45:23 -0800 (PST) From: Kees Cook To: Kees Cook Cc: "Gustavo A. R. Silva" , Nathan Chancellor , Nick Desaulniers , Rasmus Villemoes , Vitor Massaru Iha , Daniel Latypov , David Gow , Anton Ivanov , Jeff Dike , Richard Weinberger , Masahiro Yamada , Arnd Bergmann , linux-kernel@vger.kernel.org, linux-um@lists.infradead.org, linux-kbuild@vger.kernel.org, kunit-dev@googlegroups.com, llvm@lists.linux.dev, x86@kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH v3 7/7] UAPI: Introduce KUnit userspace compatibility Date: Sun, 27 Feb 2022 10:45:17 -0800 Message-Id: <20220227184517.504931-8-keescook@chromium.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220227184517.504931-1-keescook@chromium.org> References: <20220227184517.504931-1-keescook@chromium.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=7184; h=from:subject; bh=mgoDk12UNa5uSTGjFwO4+2nZAO80+cbZdVwcvxPnBXo=; b=owEBbQKS/ZANAwAKAYly9N/cbcAmAcsmYgBiG8a8w5LxxpsIKgH44u9caHGgDW3ETo0Dp34N8ul1 zx4hrReJAjMEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCYhvGvAAKCRCJcvTf3G3AJpx8D/ 9NJbctB6I8TH57q8ZxlKFajHl++CZpRi+uCUD2clP0VMybkc6osP/9W8EKbq2NJ+lV4SD9NYZv+zg0 Gu8kfYQHAup5DPbbwwCgFA2mcjbsC9xEbShZNo0GNrioT7sceP4nUx9LmROGT8zIt5HVFl82xIZbJd bLWUxVm2pZzU+QO7kggwCOusM1upIZsy29LkhkIEyK863FjG/jQOTLGRm6sMdRa3VDGmoCrWryhVw2 XvqCvf2/wSERJSTzW3cCgmR9D2wkBWqYZiGOnuRFxJDDt3Z8Ci306XKDiBtG2RscJn982Wp0xJe928 l3nLadXMQ6czcDCUA1ebs4nr/p7CT1AZYNtQjquACs1zZkKKi7Heb8j6U3Kqnor8hobwxWFYf4MuUA iXCx3eM0g9SLpuMRiLfxyyUQM8RyAuhT/yV9HxQ8cNnK5UUaD0wZvSRu/RMC4lCYamCKA9+pD9fdNT zZrD3fgqGQR8qS5RotWk9Y7ZwXNtFTRgqoaNF+wVrgOo58Mk0xPPBRvuBIb1/HkD5rQOZKH4Q1b1uP KDf/c6lWLVbwMOoI31RoLBUwyNNrD2C0BABp4P+yclmNSYUdoebFUSbE6PHPKbBv11vlH2Y1NlCUq5 TWoMW97b0vqrT+Fg4vuna7z0fpv2BIqzYiQRHmVHlMdVvvR1eobpjMGw78bg== X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The original lib/test_stackinit.c, which exclusively tests toolchain features, was designed to also be built without the full Linux kernel sources so that compiler developers and distro maintainers had an easy way to check for toolchain behaviors. When it was ported to KUnit, this mode was removed to simplify the code. Add a small header that provides a minimally operational KUnit API that can allow unit tests that don't depend on kernel-specific behaviors to build and run strictly from userspace without kernel sources. Add userspace-build support back to the renamed lib/stackinit_kunit.c test. Signed-off-by: Kees Cook Reviewed-by: Brendan Higgins Tested-by: David Gow --- v1: https://lore.kernel.org/lkml/20220224055145.1853657-1-keescook@chromium= .org v2: - split from stackinit_kunit.c refactoring patch - add missing returns (Daniel) - report expression mismatch in assert msg (Daniel) - emulate kunit_test_suites() (Daniel) - emit valid KTAP (David) --- include/uapi/misc/kunit.h | 181 ++++++++++++++++++++++++++++++++++++++ lib/stackinit_kunit.c | 11 +++ 2 files changed, 192 insertions(+) create mode 100644 include/uapi/misc/kunit.h diff --git a/include/uapi/misc/kunit.h b/include/uapi/misc/kunit.h new file mode 100644 index 000000000000..afdffda583ae --- /dev/null +++ b/include/uapi/misc/kunit.h @@ -0,0 +1,181 @@ +#ifndef __UAPI_MISC_KUNIT_H__ +#define __UAPI_MISC_KUNIT_H__ +/* + * This is a light-weight userspace drop-in replacement for the in-kernel + * KUnit API. It seeks to implement a minimal subset of features so that + * a concisely written KUnit test can be made to run entirely in userspace + * when it doesn't actually depend on any real kernel internals. + * + * Additionally contains many refactored kernel-isms to support building + * and running in userspace without full kernel source. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +#define __user /**/ +#define noinline __attribute__((__noinline__)) +#define __aligned(x) __attribute__((__aligned__(x))) +#ifdef __clang__ +# define __compiletime_error(message) /**/ +#else +# define __compiletime_error(message) __attribute__((__error__(message))) +#endif +#define __compiletime_assert(condition, msg, prefix, suffix) \ + do { \ + extern void prefix ## suffix(void) __compiletime_error(msg); \ + if (!(condition)) \ + prefix ## suffix(); \ + } while (0) +#define _compiletime_assert(condition, msg, prefix, suffix) \ + __compiletime_assert(condition, msg, prefix, suffix) +#define compiletime_assert(condition, msg) \ + _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) +#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg) +#define BUILD_BUG_ON(condition) \ + BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition) + +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) + +#define MODULE_LICENSE(str) /* str */ + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +#define TEST_PASS 0 +#define TEST_SKIP 1 +#define TEST_FAIL 2 +struct kunit { + int status; + char *msg; +}; +struct kunit_case { + void (*run_case)(struct kunit *test); + const char *name; +}; +struct kunit_suite { + const char *name; + const struct kunit_case *test_cases; +}; +#define KUNIT_CASE(test_name) { .run_case =3D test_name, .name =3D #test_n= ame } + +#define KUNIT_ASSERT_TRUE_MSG(test, expr, fmt, ...) \ +do { \ + if (!(expr)) { \ + if (test->status !=3D TEST_SKIP) \ + test->status =3D TEST_FAIL; \ + if (test->msg) \ + free(test->msg); \ + asprintf(&test->msg, fmt, ##__VA_ARGS__); \ + return; \ + } \ +} while (0) + +#define KUNIT_ASSERT_EQ_MSG(test, left, right, fmt, ...) \ + KUNIT_ASSERT_TRUE_MSG(test, (left) =3D=3D (right), \ + #left " !=3D " #right ": " fmt, \ + ##__VA_ARGS__) + +#define kunit_skip(test, fmt, ...) \ +do { \ + test->status =3D TEST_SKIP; \ + if (test->msg) \ + free(test->msg); \ + asprintf(&test->msg, fmt, ##__VA_ARGS__); \ + return; \ +} while (0) + +static int do_kunit_test_suite(struct kunit_suite *suite) +{ + const struct kunit_case *test_case; + int pass =3D 0, fail =3D 0, skip =3D 0; + int rc =3D 0; + size_t i =3D 0; + + printf(" TAP version 14\n"); + for (test_case =3D suite->test_cases; test_case->run_case; test_case++) + i++; + printf(" 1..%zu\n", i); + i =3D 0; + for (test_case =3D suite->test_cases; test_case->run_case; test_case++) { + struct kunit test =3D { }; + + i++; + test_case->run_case(&test); + switch (test.status) { + default: + case TEST_FAIL: + fprintf(stderr, " not ok %zu - %s%s%s", + i, test_case->name, + test.msg ? " # ERROR " : "", + test.msg ?: "\n"); + rc =3D 1; + fail++; + break; + case TEST_SKIP: + fprintf(stdout, " ok %zu - %s # SKIP%s%s", + i, test_case->name, + test.msg ? " " : "", + test.msg ?: "\n"); + skip++; + break; + case TEST_PASS: + fprintf(stdout, " ok %zu - %s\n", + i, test_case->name); + pass++; + break; + } + if (test.msg) + free(test.msg); + } + printf("# %s: pass:%d fail:%d skip:%d total:%zu\n", + suite->name, pass, fail, skip, i); + return rc; +} + +static int run_suites(char *name, struct kunit_suite *suites[], size_t cou= nt) +{ + int pass =3D 0, fail =3D 0, skip =3D 0; + int one, ret =3D 0; + size_t i; + + printf("TAP version 14\n"); + printf("1..%zu\n", count); + for (i =3D 0; i < count; ++i) { + one =3D do_kunit_test_suite(suites[i]); + switch (one) { + case TEST_SKIP: + skip++; + break; + case TEST_PASS: + pass++; + break; + default: + fail++; + break; + } + printf("%sok %zu - %s\n", + one =3D=3D TEST_FAIL ? "not " : "", + i + 1, suites[i]->name); + ret |=3D one; + } + printf("# %s: pass:%d fail:%d skip:%d total:%zu\n", + name, pass, fail, skip, count); + return ret; +} + +#define kunit_test_suites(suite...) \ +int main(int argc, char *argv[]) { \ + static struct kunit_suite *suites[] =3D { suite }; \ + return run_suites(argv[0], suites, ARRAY_SIZE(suites)); \ +} + +#endif /* __UAPI_MISC_KUNIT_H__ */ diff --git a/lib/stackinit_kunit.c b/lib/stackinit_kunit.c index 35c69aa425b2..6d468630c90a 100644 --- a/lib/stackinit_kunit.c +++ b/lib/stackinit_kunit.c @@ -8,7 +8,13 @@ * --make_option LLVM=3D1 \ * --kconfig_add CONFIG_INIT_STACK_ALL_ZERO=3Dy * + * External build example: + * clang -O2 -Wall -ftrivial-auto-var-init=3Dpattern \ + * -o stackinit_kunit stackinit_kunit.c + * ./stackinit_kunit + * */ +#ifdef __KERNEL__ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt =20 #include @@ -17,6 +23,11 @@ #include #include =20 +#else +/* Userspace KUnit stub header. */ +#include +#endif + /* Exfiltration buffer. */ #define MAX_VAR_SIZE 128 static u8 check_buf[MAX_VAR_SIZE]; --=20 2.32.0