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=-14.4 required=3.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=ham 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 C6FDFC54FCB for ; Thu, 23 Apr 2020 19:02:34 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 6C14920728 for ; Thu, 23 Apr 2020 19:02:34 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Mfa8Czv2" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6C14920728 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id ECE4C8E0005; Thu, 23 Apr 2020 15:02:33 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id EA5E58E0003; Thu, 23 Apr 2020 15:02:33 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id DBBBF8E0005; Thu, 23 Apr 2020 15:02:33 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0172.hostedemail.com [216.40.44.172]) by kanga.kvack.org (Postfix) with ESMTP id C3BF78E0003 for ; Thu, 23 Apr 2020 15:02:33 -0400 (EDT) Received: from smtpin13.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with ESMTP id 7E869181AC9BF for ; Thu, 23 Apr 2020 19:02:33 +0000 (UTC) X-FDA: 76740040986.13.quill24_5079040922b5b X-HE-Tag: quill24_5079040922b5b X-Filterd-Recvd-Size: 13230 Received: from mail-pg1-f194.google.com (mail-pg1-f194.google.com [209.85.215.194]) by imf21.hostedemail.com (Postfix) with ESMTP for ; Thu, 23 Apr 2020 19:02:32 +0000 (UTC) Received: by mail-pg1-f194.google.com with SMTP id j7so3328833pgj.13 for ; Thu, 23 Apr 2020 12:02:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=n7JAMDSmKb0zPqj3/9pUxsTwik3iVjNoQO25C5iF3fs=; b=Mfa8Czv2cFQTW3z0CJj7OFYOoFYxGIRTICGzn7BlFUX7G49qH9QPpp5Kq6doveV56a e/0/v3rW5sJaatt/CIfSL54YjqsFbmL3pVq7sIGmSVTCP3LzAFjndBC9qNAzrLLySpxe 7J3/7x5ZEnnN+HwPznSJoGxU2/L9JAeNB3/Ec63nh3O5QLIsmwXp0iAPPSBrisBuUco3 9nIZXQkKq8IKQ1pFSt/IDFeKuIulNswrHonwNqdVy4cMguig1Yos/ouuiIDl3b2nrShe QfpUNkSR4dKi3qfGGfYw6Qn22G2Sf08iL3o5bs/XBV2liv9UQXPfUzU8vNvbXpzsnJTt /nSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=n7JAMDSmKb0zPqj3/9pUxsTwik3iVjNoQO25C5iF3fs=; b=Y/87pCykCP/KvFXI7lN6IBKJQ4HAOiETzpjegT55b7G0F39i/q9Dav8nM1ONCf3ENV DiUtF6v5WfztlV+oQy7Q9q4vcotDVOrQlqSyS5wmVT/0dn9A17hVc3esbETPUAl81kRR kBM+8F8obLdIGG+4C2rgN5ddyVd/nmoRIxeUw6bfWhf5gbmQ3SDaS0AEukHa36bKYw14 fumlpi7HYMV0zc7HPjjX+Ue0IZrCC8PcX08YAAnneMQ1W3SMFUCKMh9KoQObWyzULUyf MfZJVcCfl1Jxakrqh2gY3Dr83rI/kUuiS6ji8GIuS5goPD6+1Vvg4+dpTjN6C+IkOw7q sqyA== X-Gm-Message-State: AGi0PubdeETB2Gmgjg9S/fG/e7QilQWNJUOrwXK2b89M0pIcFyxYnyI/ 6y09/jF/cJ3YMulCqkPSPIhrJfdCpzdhlgWUtF9Mjg== X-Google-Smtp-Source: APiQypIhJlO1zl0qcqEKhhbnrKL2ybaeplZ+sZ/m1WmAXBXu74IX24WtOwhp8rDzq6iTQ4wZ3vBdxsh3EAsxdHDNOxU= X-Received: by 2002:a63:cf02:: with SMTP id j2mr5408734pgg.130.1587668551632; Thu, 23 Apr 2020 12:02:31 -0700 (PDT) MIME-Version: 1.0 References: <20200325161249.55095-1-glider@google.com> <20200325161249.55095-14-glider@google.com> In-Reply-To: <20200325161249.55095-14-glider@google.com> From: Andrey Konovalov Date: Thu, 23 Apr 2020 21:02:20 +0200 Message-ID: Subject: Re: [PATCH v5 13/38] kmsan: add tests for KMSAN To: Alexander Potapenko Cc: Vegard Nossum , Dmitry Vyukov , Marco Elver , Linux Memory Management List , Alexander Viro , Andreas Dilger , Andrew Morton , Andrey Ryabinin , Andy Lutomirski , Ard Biesheuvel , Arnd Bergmann , Christoph Hellwig , Christoph Hellwig , "Darrick J. Wong" , "David S. Miller" , Dmitry Torokhov , Eric Biggers , Eric Dumazet , Eric Van Hensbergen , Greg Kroah-Hartman , Harry Wentland , Herbert Xu , Ilya Leoshkevich , Ingo Molnar , Jason Wang , Jens Axboe , Marek Szyprowski , Mark Rutland , "Martin K. Petersen" , Martin Schwidefsky , Matthew Wilcox , "Michael S . Tsirkin" , Michal Hocko , Michal Simek , Petr Mladek , Qian Cai , Randy Dunlap , Robin Murphy , Sergey Senozhatsky , Steven Rostedt , Takashi Iwai , "Theodore Ts'o" , Thomas Gleixner , Vasily Gorbik , Wolfram Sang Content-Type: text/plain; charset="UTF-8" X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: On Wed, Mar 25, 2020 at 5:13 PM wrote: > > The initial commit adds several tests that trigger KMSAN warnings in > simple cases. > To use, build the kernel with CONFIG_TEST_KMSAN and do > `insmod test_kmsan.ko` > > Signed-off-by: Alexander Potapenko > To: Alexander Potapenko > Cc: Vegard Nossum > Cc: Dmitry Vyukov > Cc: Marco Elver > Cc: Andrey Konovalov > Cc: linux-mm@kvack.org > --- > v2: > - added printk_test() > v4: > - test_kmsan: don't report -Wuninitialized warnings in the test > - test_kmsan.c: addressed comments by Andrey Konovalov > > Change-Id: I287e86ae83a82b770f2baa46e5bbdce1dfa65195 > --- > lib/Makefile | 2 + > lib/test_kmsan.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 231 insertions(+) > create mode 100644 lib/test_kmsan.c > > diff --git a/lib/Makefile b/lib/Makefile > index ab68a86743607..d8058c5c05826 100644 > --- a/lib/Makefile > +++ b/lib/Makefile > @@ -68,6 +68,8 @@ CFLAGS_test_kasan.o += $(call cc-disable-warning, vla) > obj-$(CONFIG_TEST_UBSAN) += test_ubsan.o > CFLAGS_test_ubsan.o += $(call cc-disable-warning, vla) > UBSAN_SANITIZE_test_ubsan.o := y > +obj-$(CONFIG_TEST_KMSAN) += test_kmsan.o > +CFLAGS_test_kmsan.o += $(call cc-disable-warning, uninitialized) > obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o > obj-$(CONFIG_TEST_LIST_SORT) += test_list_sort.o > obj-$(CONFIG_TEST_MIN_HEAP) += test_min_heap.o > diff --git a/lib/test_kmsan.c b/lib/test_kmsan.c > new file mode 100644 > index 0000000000000..f1780ed0cd315 > --- /dev/null > +++ b/lib/test_kmsan.c > @@ -0,0 +1,229 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Module for testing KMSAN. > + * > + * Copyright (C) 2017-2019 Google LLC > + * Author: Alexander Potapenko > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + * > + */ > + > +/* > + * Tests below use noinline and volatile to work around compiler optimizations > + * that may mask KMSAN bugs. > + */ > +#define pr_fmt(fmt) "kmsan test: %s : " fmt, __func__ > + > +#include > +#include > +#include > +#include > +#include > + > +#define CHECK(x) \ > + do { \ > + if (x) \ > + pr_info(#x " is true\n"); \ > + else \ > + pr_info(#x " is false\n"); \ > + } while (0) > + > +int signed_sum3(int a, int b, int c) static here and below. Also makes sense to move this function closer to uninit_multiple_args_test(). > +{ > + return a + b + c; > +} > + > +noinline void uninit_kmalloc_test(void) > +{ > + int *ptr; > + > + pr_info("-----------------------------\n"); > + pr_info("uninitialized kmalloc test (UMR report)\n"); > + ptr = kmalloc(sizeof(int), GFP_KERNEL); > + pr_info("kmalloc returned %p\n", ptr); > + CHECK(*ptr); kfree(ptr) here and below. In KASAN tests we also check that kmalloc() succeeds, but I don't have a strong opinion on whether we should do that. > +} > +noinline void init_kmalloc_test(void) > +{ > + int *ptr; > + > + pr_info("-----------------------------\n"); > + pr_info("initialized kmalloc test (no reports)\n"); > + ptr = kmalloc(sizeof(int), GFP_KERNEL); > + memset(ptr, 0, sizeof(int)); > + pr_info("kmalloc returned %p\n", ptr); > + CHECK(*ptr); > +} > + > +noinline void init_kzalloc_test(void) > +{ > + int *ptr; > + > + pr_info("-----------------------------\n"); > + pr_info("initialized kzalloc test (no reports)\n"); > + ptr = kzalloc(sizeof(int), GFP_KERNEL); > + pr_info("kzalloc returned %p\n", ptr); > + CHECK(*ptr); > +} > + > +noinline void uninit_multiple_args_test(void) > +{ > + volatile int a; > + volatile char b = 3, c; > + > + pr_info("-----------------------------\n"); > + pr_info("uninitialized local passed to fn (UMR report)\n"); > + CHECK(signed_sum3(a, b, c)); > +} > + > +noinline void uninit_stack_var_test(void) > +{ > + int cond; > + > + pr_info("-----------------------------\n"); > + pr_info("uninitialized stack variable (UMR report)\n"); > + CHECK(cond); > +} > + > +noinline void init_stack_var_test(void) > +{ > + volatile int cond = 1; > + > + pr_info("-----------------------------\n"); > + pr_info("initialized stack variable (no reports)\n"); > + CHECK(cond); > +} > + > +noinline void two_param_fn_2(int arg1, int arg2) > +{ > + CHECK(arg1); > + CHECK(arg2); > +} > + > +noinline void one_param_fn(int arg) > +{ > + two_param_fn_2(arg, arg); > + CHECK(arg); > +} > + > +noinline void two_param_fn(int arg1, int arg2) > +{ > + int init = 0; > + > + one_param_fn(init); > + CHECK(arg1); > + CHECK(arg2); > +} > + > +noinline void params_test(void) > +{ > + volatile int uninit, init = 1; > + > + pr_info("-----------------------------\n"); > + pr_info("uninit passed through a function parameter (UMR report)\n"); > + two_param_fn(uninit, init); > +} > + > +noinline void do_uninit_local_array(char *array, int start, int stop) > +{ > + int i; > + volatile char uninit; > + > + for (i = start; i < stop; i++) > + array[i] = uninit; > +} > + > +noinline void uninit_kmsan_check_memory_test(void) > +{ > + volatile char local_array[8]; > + > + pr_info("-----------------------------\n"); > + pr_info("kmsan_check_memory() called on uninit local (UMR report)\n"); > + do_uninit_local_array((char *)local_array, 5, 7); > + > + kmsan_check_memory((char *)local_array, 8); > +} > + > +noinline void init_kmsan_vmap_vunmap_test(void) > +{ > + const int npages = 2; > + struct page *pages[npages]; > + void *vbuf; > + int i; > + > + pr_info("-----------------------------\n"); > + pr_info("pages initialized via vmap (no reports)\n"); > + > + for (i = 0; i < npages; i++) > + pages[i] = alloc_page(GFP_KERNEL); > + vbuf = vmap(pages, npages, VM_MAP, PAGE_KERNEL); > + memset(vbuf, 0xfe, npages * PAGE_SIZE); > + for (i = 0; i < npages; i++) > + kmsan_check_memory(page_address(pages[i]), PAGE_SIZE); > + > + if (vbuf) > + vunmap(vbuf); > + for (i = 0; i < npages; i++) > + if (pages[i]) > + __free_page(pages[i]); > +} > + > +noinline void init_vmalloc_test(void) > +{ > + char *buf; > + int npages = 8, i; > + > + pr_info("-----------------------------\n"); > + pr_info("pages initialized via vmap (no reports)\n"); > + buf = vmalloc(PAGE_SIZE * npages); > + buf[0] = 1; > + memset(buf, 0xfe, PAGE_SIZE * npages); > + CHECK(buf[0]); > + for (i = 0; i < npages; i++) > + kmsan_check_memory(&buf[PAGE_SIZE * i], PAGE_SIZE); > + vfree(buf); > +} > + > +noinline void uaf_test(void) > +{ > + volatile int *var; > + > + pr_info("-----------------------------\n"); > + pr_info("use-after-free in kmalloc-ed buffer (UMR report)\n"); > + var = kmalloc(80, GFP_KERNEL); > + var[3] = 0xfeedface; > + kfree((int *)var); > + CHECK(var[3]); > +} > + > +noinline void printk_test(void) > +{ > + volatile int uninit; > + > + pr_info("-----------------------------\n"); > + pr_info("uninit local passed to pr_info() (UMR report)\n"); > + pr_info("%px contains %d\n", &uninit, uninit); > +} > + > +static noinline int __init kmsan_tests_init(void) > +{ > + uninit_kmalloc_test(); > + init_kmalloc_test(); > + init_kzalloc_test(); > + uninit_multiple_args_test(); > + uninit_stack_var_test(); > + init_stack_var_test(); > + params_test(); > + uninit_kmsan_check_memory_test(); > + init_kmsan_vmap_vunmap_test(); > + init_vmalloc_test(); > + uaf_test(); > + printk_test(); > + return -EAGAIN; > +} > + > +module_init(kmsan_tests_init); > +MODULE_LICENSE("GPL"); > -- > 2.25.1.696.g5e7596f4ac-goog >