Received: by 10.192.165.148 with SMTP id m20csp3394110imm; Mon, 23 Apr 2018 05:58:48 -0700 (PDT) X-Google-Smtp-Source: AIpwx49Fy5RxhIvNb5MbjRhLFxbCgBzpqIJbALV4BityNY45dDDKWXBi8J7a4UngpFejLZr9ac+a X-Received: by 10.99.115.4 with SMTP id o4mr16723083pgc.404.1524488328203; Mon, 23 Apr 2018 05:58:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524488328; cv=none; d=google.com; s=arc-20160816; b=OBbd5+uU6rfZDLNHlsCt0WifHCafFzcHQI2CgliG6LXZlTlcDWR9DJMrQ7wW52SHdp md4ti8Tlvt/xGpM9ihg0+cd9tI7NOR0+4K7YlpuPylxE/yzoCX7uHy8ByHpCehVyhgw1 ktcaCrya55GunGXM8PgK+0dhIKpUxbGz1RvmCLh0cfg845F2EZPVEPKVyJQSrMU9iWmT nAEzD2GbC7GgVP/KJOMqIqdLr32P9LZp1hgldlPY6hw5kvwSZlSmEzYm1mSG6AS0dgIB dGgDejnKokS9LztLGs9rFCvSqbvJb7sBm7JmvTucw16qDE59sY65Sxhvep05hV+aXOJv FfXg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=kkq4S5sRXaA1eYcvYNv5kYCthxlN3nK5h1Yl4Y0OMYU=; b=tnOCuXuSakx4uE/yxBj7DEHMBwKrZrwiNYJYXg4qgf1DbWbU16SAfO4MCVhgKaJmdT pI7EmcFCA7F7xTLBCn8jyQ3aPVZBPlENkAyy2p3WhZ7E1uGBb8RMWAFnygULYEkluLnq WZ/dr/D4tMuxLgfaYuLcVOIrV8c5xQWDwG2YMJX11uVwr1vGkzRLA3aYhV8hJreBlfX4 BhaGOCCP16WzPZUdRrYypw6vsa6cOlMUYBt8SShji8HAlZYbG60ou1hmaBdFTqWl2GB2 VQstqq/obRNQ7oqMk/gvAPwFgx6TrDjFj18YSp1VUQxXQJKHcxGYSUTsrPKW4/Ia9oMw lsnA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=vgp+ZxMe; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d87si11519912pfj.348.2018.04.23.05.58.34; Mon, 23 Apr 2018 05:58:48 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=vgp+ZxMe; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755332AbeDWM4y (ORCPT + 99 others); Mon, 23 Apr 2018 08:56:54 -0400 Received: from mail-it0-f66.google.com ([209.85.214.66]:40079 "EHLO mail-it0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754946AbeDWMzp (ORCPT ); Mon, 23 Apr 2018 08:55:45 -0400 Received: by mail-it0-f66.google.com with SMTP id u62-v6so10497349ita.5; Mon, 23 Apr 2018 05:55:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=kkq4S5sRXaA1eYcvYNv5kYCthxlN3nK5h1Yl4Y0OMYU=; b=vgp+ZxMeQjY09EfTTOugcdlPHMVGv+Q7xuEK3TLFN8efNjL7A8B4QxWZANuNfQzZSZ Pc1NeNGD/cykuChn4R1z6YShy4049GOG0+SX277lA5rayp0uF7RSH9yXM+k4G5GG8U+0 /DjBms7d1AuGIAadPbCHYQkobTZqCfPzigs5ucK0yfhJEgfl1oDaG8k55TXbMjcJ1PDb lMuvG16LSYUzxooNtSBBtQbQhIW4+ZEWT1Vc9T1E16c/4Hriw8H+bXk1gk3zWvq1OCVD PIJn6k4PhKa5Se9HDGxljUBEWL3nKtFN7jAyG16hkTn/FL4M25mNaAib1I3j45P8EhyD KesQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=kkq4S5sRXaA1eYcvYNv5kYCthxlN3nK5h1Yl4Y0OMYU=; b=Tv9n/ivk3QOxpsvX2UrW3/LIDhNpEUUJJDGcRWiiGLZ/dX1vZJM6UUDdYq3mt1sQcd RSfHZrEqzz+oauHylzSoCqHspF8iG6N5Ee7sU8fprLXZemZGdEaji88G/l7PgpCcAyXF u0X16f6uxiUp3MrJW8MU8VcU4hI6PMdiKpihUnsvNP1kFe+sX8qf/Fh90mrljNwlwDg3 X3eD2KPDsfEbN8Jkinqb9T9a4VrQFKnHzyyGzZpHi6LY//Ht9+xfzW2Jl7Uu0EybnYDA 6wC5fdFfTevuED8QcA/pvIUGGWSpckfJ6IK7KktUjI2ubTL/jkAG67Mj1ABB6jVQ0ZTH FTcg== X-Gm-Message-State: ALQs6tBVRQn5nXoLxxjN3XqnU59NWy/H7dLWOeN7J+d3f5XGAkBaz4oP MNh4pxd/dZy30v6hE5pxFUM= X-Received: by 2002:a24:30c4:: with SMTP id q187-v6mr1123812itq.19.1524488144486; Mon, 23 Apr 2018 05:55:44 -0700 (PDT) Received: from Mort.huawei.com (174-23-152-165.slkc.qwest.net. [174.23.152.165]) by smtp.gmail.com with ESMTPSA id n67-v6sm5934417ioe.20.2018.04.23.05.55.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 23 Apr 2018 05:55:43 -0700 (PDT) From: Igor Stoppa X-Google-Original-From: Igor Stoppa To: willy@infradead.org, keescook@chromium.org, paul@paul-moore.com, sds@tycho.nsa.gov, mhocko@kernel.org, corbet@lwn.net Cc: labbott@redhat.com, linux-cc=david@fromorbit.com, --cc=rppt@linux.vnet.ibm.com, --security-module@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, kernel-hardening@lists.openwall.com, igor.stoppa@gmail.com, Igor Stoppa Subject: [PATCH 5/9] Pmalloc selftest Date: Mon, 23 Apr 2018 16:54:54 +0400 Message-Id: <20180423125458.5338-6-igor.stoppa@huawei.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180423125458.5338-1-igor.stoppa@huawei.com> References: <20180423125458.5338-1-igor.stoppa@huawei.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add basic self-test functionality for pmalloc. The testing is introduced as early as possible, right after the main dependency, genalloc, has passed successfully, so that it can help diagnosing failures in pmalloc users. Signed-off-by: Igor Stoppa --- include/linux/test_pmalloc.h | 24 ++++++++ init/main.c | 2 + mm/Kconfig | 10 ++++ mm/Makefile | 1 + mm/test_pmalloc.c | 138 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 175 insertions(+) create mode 100644 include/linux/test_pmalloc.h create mode 100644 mm/test_pmalloc.c diff --git a/include/linux/test_pmalloc.h b/include/linux/test_pmalloc.h new file mode 100644 index 000000000000..c7e2e451c17c --- /dev/null +++ b/include/linux/test_pmalloc.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * test_pmalloc.h + * + * (C) Copyright 2018 Huawei Technologies Co. Ltd. + * Author: Igor Stoppa + */ + + +#ifndef __LINUX_TEST_PMALLOC_H +#define __LINUX_TEST_PMALLOC_H + + +#ifdef CONFIG_TEST_PROTECTABLE_MEMORY + +void test_pmalloc(void); + +#else + +static inline void test_pmalloc(void){}; + +#endif + +#endif diff --git a/init/main.c b/init/main.c index b795aa341a3a..27f8479c4578 100644 --- a/init/main.c +++ b/init/main.c @@ -91,6 +91,7 @@ #include #include #include +#include #include #include @@ -679,6 +680,7 @@ asmlinkage __visible void __init start_kernel(void) */ mem_encrypt_init(); + test_pmalloc(); #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start && !initrd_below_start_ok && page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) { diff --git a/mm/Kconfig b/mm/Kconfig index d7ef40eaa4e8..f98b4c0aebce 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -758,3 +758,13 @@ config PROTECTABLE_MEMORY depends on MMU depends on ARCH_HAS_SET_MEMORY default y + +config TEST_PROTECTABLE_MEMORY + bool "Run self test for pmalloc memory allocator" + depends on MMU + depends on ARCH_HAS_SET_MEMORY + select PROTECTABLE_MEMORY + default n + help + Tries to verify that pmalloc works correctly and that the memory + is effectively protected. diff --git a/mm/Makefile b/mm/Makefile index 6a6668f99799..802cba37013b 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -66,6 +66,7 @@ obj-$(CONFIG_SPARSEMEM_VMEMMAP) += sparse-vmemmap.o obj-$(CONFIG_SLOB) += slob.o obj-$(CONFIG_MMU_NOTIFIER) += mmu_notifier.o obj-$(CONFIG_PROTECTABLE_MEMORY) += pmalloc.o +obj-$(CONFIG_TEST_PROTECTABLE_MEMORY) += test_pmalloc.o obj-$(CONFIG_KSM) += ksm.o obj-$(CONFIG_PAGE_POISONING) += page_poison.o obj-$(CONFIG_SLAB) += slab.o diff --git a/mm/test_pmalloc.c b/mm/test_pmalloc.c new file mode 100644 index 000000000000..032e9741c5f1 --- /dev/null +++ b/mm/test_pmalloc.c @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * test_pmalloc.c + * + * (C) Copyright 2018 Huawei Technologies Co. Ltd. + * Author: Igor Stoppa + */ + +#include +#include +#include +#include + +#include "pmalloc_helpers.h" + +#define SIZE_1 (PAGE_SIZE * 3) +#define SIZE_2 1000 + +/* wrapper for is_pmalloc_object() with messages */ +static inline bool validate_alloc(bool expected, void *addr, + unsigned long size) +{ + bool test; + + test = is_pmalloc_object(addr, size) > 0; + pr_notice("must be %s: %s", + expected ? "ok" : "no", test ? "ok" : "no"); + return test == expected; +} + + +#define is_alloc_ok(variable, size) \ + validate_alloc(true, variable, size) + + +#define is_alloc_no(variable, size) \ + validate_alloc(false, variable, size) + +/* tests the basic life-cycle of a pool */ +static bool create_and_destroy_pool(void) +{ + static struct pmalloc_pool *pool; + + pr_notice("Testing pool creation and destruction capability"); + + pool = pmalloc_create_pool(); + if (WARN(!pool, "Cannot allocate memory for pmalloc selftest.")) + return false; + pmalloc_destroy_pool(pool); + return true; +} + + +/* verifies that it's possible to allocate from the pool */ +static bool test_alloc(void) +{ + static struct pmalloc_pool *pool; + static void *p; + + pr_notice("Testing allocation capability"); + pool = pmalloc_create_pool(); + if (WARN(!pool, "Unable to allocate memory for pmalloc selftest.")) + return false; + p = pmalloc(pool, SIZE_1 - 1); + pmalloc_protect_pool(pool); + pmalloc_destroy_pool(pool); + if (WARN(!p, "Failed to allocate memory from the pool")) + return false; + return true; +} + + +/* tests the identification of pmalloc ranges */ +static bool test_is_pmalloc_object(void) +{ + struct pmalloc_pool *pool; + void *pmalloc_p; + void *vmalloc_p; + bool retval = false; + + pr_notice("Test correctness of is_pmalloc_object()"); + + vmalloc_p = vmalloc(SIZE_1); + if (WARN(!vmalloc_p, + "Unable to allocate memory for pmalloc selftest.")) + return false; + pool = pmalloc_create_pool(); + if (WARN(!pool, "Unable to allocate memory for pmalloc selftest.")) + return false; + pmalloc_p = pmalloc(pool, SIZE_1 - 1); + if (WARN(!pmalloc_p, "Failed to allocate memory from the pool")) + goto error; + if (WARN_ON(unlikely(!is_alloc_ok(pmalloc_p, 10))) || + WARN_ON(unlikely(!is_alloc_ok(pmalloc_p, SIZE_1))) || + WARN_ON(unlikely(!is_alloc_ok(pmalloc_p, PAGE_SIZE))) || + WARN_ON(unlikely(!is_alloc_no(pmalloc_p, SIZE_1 + 1))) || + WARN_ON(unlikely(!is_alloc_no(vmalloc_p, 10)))) + goto error; + retval = true; +error: + pmalloc_protect_pool(pool); + pmalloc_destroy_pool(pool); + vfree(vmalloc_p); + return retval; +} + +/* Test out of virtually contiguous memory */ +static void test_oovm(void) +{ + struct pmalloc_pool *pool; + unsigned int i; + + pr_notice("Exhaust vmalloc memory with doubling allocations."); + pool = pmalloc_create_pool(); + if (WARN(!pool, "Failed to create pool")) + return; + for (i = 1; i; i *= 2) + if (unlikely(!pzalloc(pool, i - 1))) + break; + pr_notice("vmalloc oom at %d allocation", i - 1); + pmalloc_protect_pool(pool); + pmalloc_destroy_pool(pool); +} + +/** + * test_pmalloc() -main entry point for running the test cases + */ +void test_pmalloc(void) +{ + + pr_notice("pmalloc-selftest"); + + if (unlikely(!(create_and_destroy_pool() && + test_alloc() && + test_is_pmalloc_object()))) + return; + test_oovm(); +} -- 2.14.1