From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.5 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 11590C433E0 for ; Fri, 12 Jun 2020 22:36:55 +0000 (UTC) Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9766B206DC for ; Fri, 12 Jun 2020 22:36:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="XsmsOLCF" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9766B206DC Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=chromium.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=linux-kernel-mentees-bounces@lists.linuxfoundation.org Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 3DCA62588A; Fri, 12 Jun 2020 22:36:54 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 7iPpu7FLDiFW; Fri, 12 Jun 2020 22:36:50 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id 9100D226D3; Fri, 12 Jun 2020 22:36:50 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 729F9C0881; Fri, 12 Jun 2020 22:36:50 +0000 (UTC) Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 83267C016F for ; Fri, 12 Jun 2020 22:36:48 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 594A3226D3 for ; Fri, 12 Jun 2020 22:36:48 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id zuVPbplKdbEd for ; Fri, 12 Jun 2020 22:36:46 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mail-pj1-f68.google.com (mail-pj1-f68.google.com [209.85.216.68]) by silver.osuosl.org (Postfix) with ESMTPS id EF7EE20392 for ; Fri, 12 Jun 2020 22:36:45 +0000 (UTC) Received: by mail-pj1-f68.google.com with SMTP id u8so4211605pje.4 for ; Fri, 12 Jun 2020 15:36:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=lO8mi2zhhtsGQXztgPFepnvQEc1Z1nZkKCQAprRqTJ4=; b=XsmsOLCFQ93CbLn9XQetz0h9AFJYU3ErW5h+8j+CVclkQsYBeNjGXvwmosvZkRiHCj xycBVj8L/V6qzkc39xxVw3XI6A9itH8pQiXCHcN+kZ/PkXsLDOqTaA8OEHVKdlVmI6D/ VYg1SNz562LcmJvbRlZRyCd5daQtFxeb8sbPI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=lO8mi2zhhtsGQXztgPFepnvQEc1Z1nZkKCQAprRqTJ4=; b=ioNb2+6PpluBkkcAKEfqJY+iKeLoWv+qSa+KbuUvv9PAW7woggVxu/g9t34TI7BNiQ IEDzpWpsmFcUeuN5F3HoD+BO7Blo5DT8MvGKlg7BFF0diT85gQxolxegFSbcZAp2Q2Gr S52/Czt930tN2+i+N+r52tKKNynV6bHL0VNO01ucbHeShGCGI5QgMATcQ69VwMRlDJmW gp0ZE45njgfrPb7W1rlSC9yJfFi1oa6q5GEepXxFnkWkBzNjoUaGGvLThx4ewku6zcMs Z7QRg8u/RcZCBdxsCCvnpcpf0DbNGoamW3LW8lUYb3UP9tXXHXZgCdcJg89CV9D6faPc 9t8g== X-Gm-Message-State: AOAM532kdY537Gevp4lr7NMpW5ErPu8JaySu8Tn2ECCnKVWTNfPa983i X+nvhBwko4yICpW1T725PR1r3rEtNoNkvQ== X-Google-Smtp-Source: ABdhPJyrBo5EKiDLRgRPY9opnNYen61fBUs9EhgZy/OdHh3845pdzrbzn9u/rdo0zXk8zuFL7tbD7A== X-Received: by 2002:a17:90a:aa88:: with SMTP id l8mr1041887pjq.145.1592001405265; Fri, 12 Jun 2020 15:36:45 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id j13sm6481571pje.25.2020.06.12.15.36.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Jun 2020 15:36:44 -0700 (PDT) Date: Fri, 12 Jun 2020 15:36:43 -0700 From: Kees Cook To: Vitor Massaru Iha Message-ID: <202006121403.CF8D57C@keescook> References: <20200611215501.213058-1-vitor@massaru.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20200611215501.213058-1-vitor@massaru.org> Cc: linux@rasmusvillemoes.dk, brendanhiggins@google.com, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel-mentees@lists.linuxfoundation.org, kunit-dev@googlegroups.com Subject: Re: [Linux-kernel-mentees] [PATCH] lib: kunit_test_overflow: add KUnit test of check_*_overflow functions X-BeenThere: linux-kernel-mentees@lists.linuxfoundation.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: linux-kernel-mentees-bounces@lists.linuxfoundation.org Sender: "Linux-kernel-mentees" On Thu, Jun 11, 2020 at 06:55:01PM -0300, Vitor Massaru Iha wrote: > This adds the convertion of the runtime tests of check_*_overflow fuctions, > from `lib/test_overflow.c`to KUnit tests. > > The log similar to the one seen in dmesg running test_overflow can be > seen in `test.log`. > > Signed-off-by: Vitor Massaru Iha > --- > lib/Kconfig.debug | 17 ++ > lib/Makefile | 1 + > lib/kunit_overflow_test.c | 590 ++++++++++++++++++++++++++++++++++++++ > 3 files changed, 608 insertions(+) > create mode 100644 lib/kunit_overflow_test.c What tree is this based on? I can't apply it to v5.7, linux-next, nor Linus's latest. I've fixed it up to apply to linux-next for now. :) Looking at linux-next, though, I am reminded of my agony over naming: obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o obj-$(CONFIG_LINEAR_RANGES_TEST) += test_linear_ranges.o obj-$(CONFIG_OVERFLOW_KUNIT_TEST) += kunit_overflow_test.o *-test test_* *_test This has to get fixed now, and the naming convention needs to be documented. For old tests, the preferred naming was test_*. For kunit, I think it should be kunit_* (and no trailing _test; that's redundant). For for this bikeshed, I think it should be kunit_overflow.c For the CONFIG name, it seems to be suggested in docs to be *_KUNIT_TEST: ... menuconfig). From there, you can enable any KUnit tests you want: they usually have config options ending in ``_KUNIT_TEST``. ... I think much stronger language needs to be added to "Writing your first test" (which actually recommends the wrong thing: "config MISC_EXAMPLE_TEST"). And then doesn't specify a module file name, though it hints at one: ... obj-$(CONFIG_MISC_EXAMPLE_TEST) += example-test.o ... So, please, let's get this documented: we really really need a single naming convention for these. For Kconfig in the tree, I see: drivers/base/Kconfig:config PM_QOS_KUNIT_TEST drivers/base/test/Kconfig:config KUNIT_DRIVER_PE_TEST fs/ext4/Kconfig:config EXT4_KUNIT_TESTS lib/Kconfig.debug:config SYSCTL_KUNIT_TEST lib/Kconfig.debug:config OVERFLOW_KUNIT_TEST lib/Kconfig.debug:config LIST_KUNIT_TEST lib/Kconfig.debug:config LINEAR_RANGES_TEST lib/kunit/Kconfig:menuconfig KUNIT lib/kunit/Kconfig:config KUNIT_DEBUGFS lib/kunit/Kconfig:config KUNIT_TEST lib/kunit/Kconfig:config KUNIT_EXAMPLE_TEST lib/kunit/Kconfig:config KUNIT_ALL_TESTS Which is: *_KUNIT_TEST KUNIT_*_TEST KUNIT_*_TESTS *_TEST Nooooo. ;) If it should all be *_KUNIT_TEST, let's do that. I think just *_KUNIT would be sufficient (again, adding the word "test" to "kunit" is redundant). And it absolutely should not be a prefix, otherwise it'll get sorted away from the thing it's named after. So my preference is here would be CONFIG_OVERFLOW_KUNIT. (Yes the old convention was CONFIG_TEST_*, but those things tended to be regression tests, not unit tests.) Please please, can we fix this before we add anything more? > > diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug > index 1f4ab7a2bdee..72fcfe1f24a4 100644 > --- a/lib/Kconfig.debug > +++ b/lib/Kconfig.debug > @@ -2075,6 +2075,23 @@ config SYSCTL_KUNIT_TEST > > If unsure, say N. > > +config OVERFLOW_KUNIT_TEST > + tristate "KUnit test for overflow" if !KUNIT_ALL_TESTS > + depends on KUNIT > + default KUNIT_ALL_TESTS > + help > + This builds the overflow KUnit tests. > + > + KUnit tests run during boot and output the results to the debug log > + in TAP format (http://testanything.org/). Only useful for kernel devs > + running KUnit test harness and are not for inclusion into a production > + build. > + > + 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 LIST_KUNIT_TEST > tristate "KUnit Test for Kernel Linked-list structures" if !KUNIT_ALL_TESTS > depends on KUNIT Regarding output: [ 36.611358] TAP version 14 [ 36.611953] # Subtest: overflow [ 36.611954] 1..3 ... [ 36.622914] # overflow_calculation_test: s64: 21 arithmetic tests [ 36.624020] ok 1 - overflow_calculation_test ... [ 36.731096] # overflow_shift_test: ok: (s64)(0 << 63) == 0 [ 36.731840] ok 2 - overflow_shift_test ... [ 36.750294] kunit_try_catch: vmalloc: allocation failure: 18446744073709551615 bytes, mode:0xcc0(GFP_KERNEL), nodemask=(null),cpuset=/,mems_allowed=0 ... [ 36.805350] # overflow_allocation_test: devm_kzalloc detected saturation [ 36.807763] ok 3 - overflow_allocation_test [ 36.807765] ok 1 - overflow A few things here.... - On the outer test report, there is no "plan" line (I was expecting "1..1"). Technically it's optional, but it seems like the information is available. :) - The subtest should have its own "TAP version 14" line, and it should be using the diagnostic line prefix for the top-level test (this is what kselftest is doing). - There is no way to distinguish top-level TAP output from kernel log lines. I think we should stick with the existing marker, which is "# ", so that kernel output has no way to be interpreted as TAP details -- unless it intentionally starts adding "#"s. ;) - There is no summary line (to help humans). For example, the kselftest API produces a final pass/fail report. Taken together, I was expecting the output to be: [ 36.611358] # TAP version 14 [ 36.611953] # 1..1 [ 36.611958] # # TAP version 14 [ 36.611954] # # 1..3 ... [ 36.622914] # # # overflow_calculation_test: s64: 21 arithmetic tests [ 36.624020] # # ok 1 - overflow_calculation_test ... [ 36.731096] # # # overflow_shift_test: ok: (s64)(0 << 63) == 0 [ 36.731840] # # ok 2 - overflow_shift_test ... [ 36.750294] kunit_try_catch: vmalloc: allocation failure: 18446744073709551615 bytes, mode:0xcc0(GFP_KERNEL), nodemask=(null),cpuset=/,mems_allowed=0 ... [ 36.805350] # # # overflow_allocation_test: devm_kzalloc detected saturation [ 36.807763] # # ok 3 - overflow_allocation_test [ 36.807763] # # # overflow: PASS [ 36.807765] # ok 1 - overflow [ 36.807767] # # kunit: PASS But I assume there are threads on this that I've not read... :) Now, speaking to actual behavior, I love it. :) All the tests are there (and then some -- noted below). > diff --git a/lib/Makefile b/lib/Makefile > index 685aee60de1d..a3290adc0019 100644 > --- a/lib/Makefile > +++ b/lib/Makefile > @@ -309,3 +309,4 @@ obj-$(CONFIG_OBJAGG) += objagg.o > > # KUnit tests > obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o > +obj-$(CONFIG_OVERFLOW_KUNIT_TEST) += kunit_overflow_test.o > diff --git a/lib/kunit_overflow_test.c b/lib/kunit_overflow_test.c > new file mode 100644 > index 000000000000..c3eb8f0d3d50 > --- /dev/null > +++ b/lib/kunit_overflow_test.c A lot of this file is unchanged, so I would suggest doing this as a "git mv lib/test_overflow.c lib/kunit_overflow.c" and then put the changes into the file. Then it should be easier to track git history, etc. Without this, it's a lot harder to review this patch since I'm just looking at a 590 new lines. ;) Really, it's a diff (which I'll paste here for the code review...) > --- a/lib/test_overflow.c 2020-06-12 14:07:11.161999209 -0700 > +++ b/lib/kunit_overflow_test.c 2020-06-12 14:07:27.950183116 -0700 > @@ -1,17 +1,18 @@ > -// SPDX-License-Identifier: GPL-2.0 OR MIT > +// SPDX-License-Identifier: GPL-2.0 Please don't change the license. > +/* > + * This code is the conversion of the overflow test in runtime to KUnit tests. > + */ > + This can be left off. > /* > * Test cases for arithmetic overflow checks. > */ > #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt > > +#include > #include > #include > -#include > #include > -#include > #include > -#include > -#include > #include > > #define DEFINE_TEST_ARRAY(t) \ > @@ -19,7 +20,7 @@ > t a, b; \ > t sum, diff, prod; \ > bool s_of, d_of, p_of; \ > - } t ## _tests[] __initconst > + } t ## _tests[] Why drop the __initconst? > DEFINE_TEST_ARRAY(u8) = { > {0, 0, 0, 0, 0, false, false, false}, > @@ -44,6 +45,7 @@ > {128, 128, 0, 0, 0, true, false, true}, > {123, 234, 101, 145, 110, true, true, true}, > }; > + Style nit: I'd like to avoid the blank lines here. > DEFINE_TEST_ARRAY(u16) = { > {0, 0, 0, 0, 0, false, false, false}, > {1, 1, 2, 0, 1, false, false, false}, > @@ -66,6 +68,7 @@ > {123, 234, 357, 65425, 28782, false, true, false}, > {1234, 2345, 3579, 64425, 10146, false, true, true}, > }; > + > DEFINE_TEST_ARRAY(u32) = { > {0, 0, 0, 0, 0, false, false, false}, > {1, 1, 2, 0, 1, false, false, false}, > @@ -163,6 +166,7 @@ > {S16_MIN, S16_MIN, 0, 0, 0, true, false, true}, > {S16_MAX, S16_MAX, -2, 0, 1, true, false, true}, > }; > + > DEFINE_TEST_ARRAY(s32) = { > {0, 0, 0, 0, 0, false, false, false}, > > @@ -186,6 +190,7 @@ > {S32_MIN, S32_MIN, 0, 0, 0, true, false, true}, > {S32_MAX, S32_MAX, -2, 0, 1, true, false, true}, > }; > + > DEFINE_TEST_ARRAY(s64) = { > {0, 0, 0, 0, 0, false, false, false}, > > @@ -215,254 +220,243 @@ > {0, -S64_MAX, -S64_MAX, S64_MAX, 0, false, false, false}, > }; > > -#define check_one_op(t, fmt, op, sym, a, b, r, of) do { \ > - t _r; \ > - bool _of; \ > - \ > - _of = check_ ## op ## _overflow(a, b, &_r); \ > - if (_of != of) { \ > - pr_warn("expected "fmt" "sym" "fmt \ > - " to%s overflow (type %s)\n", \ > - a, b, of ? "" : " not", #t); \ > - err = 1; \ > - } \ > - if (_r != r) { \ > - pr_warn("expected "fmt" "sym" "fmt" == " \ > - fmt", got "fmt" (type %s)\n", \ > - a, b, r, _r, #t); \ > - err = 1; \ > - } \ > +#define check_one_op(test, t, fmt, op, sym, a, b, r, of) do { \ > + t _r; \ > + bool _of; \ > + \ > + _of = check_ ## op ## _overflow(a, b, &_r); \ > + if (_of != of) { \ > + KUNIT_FAIL(test, "Expected "fmt" "sym" "fmt \ > + " to%s overflow (type %s)\n", \ > + a, b, of ? "" : " not", #t); \ > + } \ > + if (_r != r) { \ > + KUNIT_FAIL(test, "Expected "fmt" "sym" "fmt" == " \ > + fmt", got "fmt" (type %s)\n", \ > + a, b, r, _r, #t); \ > + } \ > } while (0) The trailing \ makes this more awkward to diff, but one thing I'm not quite seeing is why "test" needs to be added. It's not a variable in these macros. i.e. it is used literally: #define DEFINE_TEST_FUNC(test, t, fmt) \ static void do_test_ ## t(struct kunit *test, const struct test_ ## t *p) \ { \ check_one_op(test, t, fmt, add, "+", p->a, p->b, p->sum, p->s_of); \ ... Only callers of the do_test_*() would need to be changed. I think all of these macros just need the pr_warn/KUNIT_FAIL changes, and the function prototypes updated to include struct kunit *test. > > -#define DEFINE_TEST_FUNC(t, fmt) \ > -static int __init do_test_ ## t(const struct test_ ## t *p) \ > -{ \ > - int err = 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 = 0; \ > - unsigned i; \ > - \ > - pr_info("%-3s: %zu arithmetic tests\n", #t, \ > - ARRAY_SIZE(t ## _tests)); \ > - for (i = 0; i < ARRAY_SIZE(t ## _tests); ++i) \ > - err |= do_test_ ## t(&t ## _tests[i]); \ > - return err; \ > +#define DEFINE_TEST_FUNC(test, t, fmt) \ > +static void do_test_ ## t(struct kunit *test, const struct test_ ## t *p) \ > +{ \ > + check_one_op(test, t, fmt, add, "+", p->a, p->b, p->sum, p->s_of); \ > + check_one_op(test, t, fmt, add, "+", p->b, p->a, p->sum, p->s_of); \ > + check_one_op(test, t, fmt, sub, "-", p->a, p->b, p->diff, p->d_of); \ > + check_one_op(test, t, fmt, mul, "*", p->a, p->b, p->prod, p->p_of); \ > + check_one_op(test, t, fmt, mul, "*", p->b, p->a, p->prod, p->p_of); \ > +} \ Then these all only need the prototype on the actual function changed. > + \ > +static void test_ ## t ## _overflow(struct kunit *test) \ > +{ \ > + unsigned i; \ > + \ > + kunit_warn(test, "%-3s: %zu arithmetic tests\n", #t, \ > + ARRAY_SIZE(t ## _tests)); \ > + for (i = 0; i < ARRAY_SIZE(t ## _tests); ++i) \ > + do_test_ ## t(test, &t ## _tests[i]); \ > } > > -DEFINE_TEST_FUNC(u8, "%d"); > -DEFINE_TEST_FUNC(s8, "%d"); > -DEFINE_TEST_FUNC(u16, "%d"); > -DEFINE_TEST_FUNC(s16, "%d"); > -DEFINE_TEST_FUNC(u32, "%u"); > -DEFINE_TEST_FUNC(s32, "%d"); > +DEFINE_TEST_FUNC(test, u8, "%d"); > +DEFINE_TEST_FUNC(test, s8, "%d"); > +DEFINE_TEST_FUNC(test, u16, "%d"); > +DEFINE_TEST_FUNC(test, s16, "%d"); > +DEFINE_TEST_FUNC(test, u32, "%u"); > +DEFINE_TEST_FUNC(test, s32, "%d"); > #if BITS_PER_LONG == 64 > -DEFINE_TEST_FUNC(u64, "%llu"); > -DEFINE_TEST_FUNC(s64, "%lld"); > +DEFINE_TEST_FUNC(test, u64, "%llu"); > +DEFINE_TEST_FUNC(test, s64, "%lld"); > #endif And all the actual uses of the macros can be left unchanged. > > -static int __init test_overflow_calculation(void) > +static void overflow_calculation_test(struct kunit *test) > { > - int err = 0; > > - err |= test_u8_overflow(); > - err |= test_s8_overflow(); > - err |= test_u16_overflow(); > - err |= test_s16_overflow(); > - err |= test_u32_overflow(); > - err |= test_s32_overflow(); > + test_u8_overflow(test); > + test_s8_overflow(test); > + test_s8_overflow(test); The s8 test got added twice here accidentally. > + test_u16_overflow(test); > + test_s16_overflow(test); > + test_u32_overflow(test); > + test_s32_overflow(test); > #if BITS_PER_LONG == 64 > - err |= test_u64_overflow(); > - err |= test_s64_overflow(); > + test_u64_overflow(test); > + test_s64_overflow(test); > #endif > - > - return err; > } I think it might be nice to keep the "err" vars around for a final report line (maybe per test)? (It would keep the diff churn way lower, too...) So, yes! I like it. :) Most of my comments here have nothing to do with specifically this patch (sorry)! But I'd love to see a v2. Thanks for doing this! I'm glad to see more TAP output. :) -- Kees Cook _______________________________________________ Linux-kernel-mentees mailing list Linux-kernel-mentees@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees