From patchwork Sat Oct 13 13:39:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Ellerman X-Patchwork-Id: 10640161 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CEE4369B1 for ; Sat, 13 Oct 2018 13:40:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B16EE2AE94 for ; Sat, 13 Oct 2018 13:40:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9EC252AEBF; Sat, 13 Oct 2018 13:40:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DFEBE2AE94 for ; Sat, 13 Oct 2018 13:40:09 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id B1FFE6B0003; Sat, 13 Oct 2018 09:40:08 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id ACE7A6B0005; Sat, 13 Oct 2018 09:40:08 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 997946B0006; Sat, 13 Oct 2018 09:40:08 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pf1-f198.google.com (mail-pf1-f198.google.com [209.85.210.198]) by kanga.kvack.org (Postfix) with ESMTP id 579F16B0003 for ; Sat, 13 Oct 2018 09:40:08 -0400 (EDT) Received: by mail-pf1-f198.google.com with SMTP id y73-v6so895879pfi.16 for ; Sat, 13 Oct 2018 06:40:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to:cc :subject:date:message-id; bh=DEfZFzLDlTKbUd1ZDADOxqJsvMajGLJAT5ytM4D8LLE=; b=oIlqnJu9SjedXKMkmplP1CcM1Ak7KvfBKCo5OF24WUh2nYc7oR1psvxSzB3yVzxJE2 daaPiPjQHIIKTNqrR4BY3Y4d2FSvh6UpjbCkSGsP3luVf1v5pbezOOrJwJYUSBqCwYP1 BW9nzMeK5GSTiYcCi7DjNiYbu25Mv9hY2ryR/76rF/FKFoqVKUcNTApAhWf85vvqczNO PUGPN+97Qn9+IoQH4QBVqbCf0/lAA5s0r0FXJlhZ2/yJSXLt8Vx/sCSw4ld7efa2cvQ6 WSGsw9Vox2GT2uzkemZWQpWsungjzjiYKH15avemid7pYN4biPykLLhgkhb4jTCxong4 n5JQ== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of michael@ozlabs.org designates 203.11.71.1 as permitted sender) smtp.mailfrom=michael@ozlabs.org X-Gm-Message-State: ABuFfojAaFRcCwS2ZmpaTBJoxd2gousO2vij5ho7EfArpjVecIQqHVSa ypdFVN7z+MEV2v5ADYeRStcHmt+Zqahgkgyim62TflB3yB1KHKEHPpEAZA4aUyw5LcKH5F0N0MG 1zjkzwbSrfypsCTpyacZMAZpUAoNt8kzQX7LrDY9M9hffP1U01Ch7AEkGmBAcqRE= X-Received: by 2002:a17:902:3041:: with SMTP id u59-v6mr9743062plb.99.1539438008011; Sat, 13 Oct 2018 06:40:08 -0700 (PDT) X-Google-Smtp-Source: ACcGV61uqqMSs72msBfhrO7au1DE0cS2emGAnY1O+OUEra8qirAKd/4FpcV4SbHRJuvuNSpcDKLA X-Received: by 2002:a17:902:3041:: with SMTP id u59-v6mr9742988plb.99.1539438006891; Sat, 13 Oct 2018 06:40:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539438006; cv=none; d=google.com; s=arc-20160816; b=SOPJkMYqpxsTwqTypsoTv2tw9m/j1ttStVLZIVAjIa7fSPT+cpB2p5dswPYvJ3dssP Z4SGE6yyL1LTGxFSq1SD64QaR+BzWYAdqi5SbMNgqC28mx006B4KZN+AoYNGErfRJQA+ UFpQXVo+IvW7kv7KqOVzQtPDgd040B1yTRn9E4quR/p7rfaTav14FR5EvLced0RrH0eg 8zfkk17j7jR+zpmMMjuokzBSTOwBNHl//99Ntu4LNXBJdMk1dv43hXxtMv3cqTIcL69d 0lAkJ1kPVZzpDLBPUXQddNmyZ7jYCyqZx0OegXESxJgwBL9jPmKhe/9p2T6+zvQpxGNg JG+Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=message-id:date:subject:cc:to:from; bh=DEfZFzLDlTKbUd1ZDADOxqJsvMajGLJAT5ytM4D8LLE=; b=EkG8U4jugZkN3C5sjPcX6xoERj8o0TdoYOnGlWzKVg58qcgLMDUOgujbfalOW1rjRD P2QdvR9wbl5d2sHXJM6Zwm1zWSWeQaKw2JjxUJPo+Ddm7XqrwZwMMNW23ZHGTc7BOMJY 43DPzCVukBc3c+6tDqR6tfRGDEFUPjEvEl9XgRZXgcR+n3nWJ9R0+DR+FNKPUqvntU5T Jxez3lTE4FHLDdUXI1ttfNokeMiEqOxxSm9j57+hv6mBFlpG8S/T6WDaaKPYK5whU3jE VJ2YgZ0JLQG0M0T6Lw00iRQv+yIEVsSQe8BkWQUxvIuXpQgc3g3vYAEhsLBag97PGkUM +swQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of michael@ozlabs.org designates 203.11.71.1 as permitted sender) smtp.mailfrom=michael@ozlabs.org Received: from ozlabs.org (ozlabs.org. [203.11.71.1]) by mx.google.com with ESMTPS id k28-v6si4508895pgf.308.2018.10.13.06.40.06 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 13 Oct 2018 06:40:06 -0700 (PDT) Received-SPF: pass (google.com: domain of michael@ozlabs.org designates 203.11.71.1 as permitted sender) client-ip=203.11.71.1; Authentication-Results: mx.google.com; spf=pass (google.com: domain of michael@ozlabs.org designates 203.11.71.1 as permitted sender) smtp.mailfrom=michael@ozlabs.org Received: by ozlabs.org (Postfix, from userid 1034) id 42XQmz5rwkz9sCW; Sun, 14 Oct 2018 00:40:03 +1100 (AEDT) From: Michael Ellerman To: akpm@linux-foundation.org Cc: linux-kernel@vger.kernel.org, jannh@google.com, mhocko@suse.com, linux-mm@kvack.org, khalid.aziz@oracle.com, aarcange@redhat.com, fweimer@redhat.com, jhubbard@nvidia.com, willy@infradead.org, abdhalee@linux.vnet.ibm.com, joel@jms.id.au, keescook@chromium.org, jasone@google.com, davidtgoldblatt@gmail.com, trasz@freebsd.org, danielmicay@gmail.com Subject: [PATCH] selftests/vm: Add a test for MAP_FIXED_NOREPLACE Date: Sun, 14 Oct 2018 00:39:29 +1100 Message-Id: <20181013133929.28653-1-mpe@ellerman.id.au> X-Mailer: git-send-email 2.17.1 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: X-Virus-Scanned: ClamAV using ClamSMTP Add a test for MAP_FIXED_NOREPLACE, based on some code originally by Jann Horn. This would have caught the overlap bug reported by Daniel Micay. I originally suggested to Michal that we create MAP_FIXED_NOREPLACE, but instead of writing a selftest I spent my time bike-shedding whether it should be called MAP_FIXED_SAFE/NOCLOBBER/WEAK/NEW .. mea culpa. Signed-off-by: Michael Ellerman Reviewed-by: Kees Cook Reviewed-by: Khalid Aziz Acked-by: Michal Hocko --- tools/testing/selftests/vm/.gitignore | 1 + tools/testing/selftests/vm/Makefile | 1 + .../selftests/vm/map_fixed_noreplace.c | 206 ++++++++++++++++++ 3 files changed, 208 insertions(+) create mode 100644 tools/testing/selftests/vm/map_fixed_noreplace.c diff --git a/tools/testing/selftests/vm/.gitignore b/tools/testing/selftests/vm/.gitignore index af5ff83f6d7f..31b3c98b6d34 100644 --- a/tools/testing/selftests/vm/.gitignore +++ b/tools/testing/selftests/vm/.gitignore @@ -13,3 +13,4 @@ mlock-random-test virtual_address_range gup_benchmark va_128TBswitch +map_fixed_noreplace diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile index e94b7b14bcb2..6e67e726e5a5 100644 --- a/tools/testing/selftests/vm/Makefile +++ b/tools/testing/selftests/vm/Makefile @@ -12,6 +12,7 @@ TEST_GEN_FILES += gup_benchmark TEST_GEN_FILES += hugepage-mmap TEST_GEN_FILES += hugepage-shm TEST_GEN_FILES += map_hugetlb +TEST_GEN_FILES += map_fixed_noreplace TEST_GEN_FILES += map_populate TEST_GEN_FILES += mlock-random-test TEST_GEN_FILES += mlock2-tests diff --git a/tools/testing/selftests/vm/map_fixed_noreplace.c b/tools/testing/selftests/vm/map_fixed_noreplace.c new file mode 100644 index 000000000000..d91bde511268 --- /dev/null +++ b/tools/testing/selftests/vm/map_fixed_noreplace.c @@ -0,0 +1,206 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Test that MAP_FIXED_NOREPLACE works. + * + * Copyright 2018, Jann Horn + * Copyright 2018, Michael Ellerman, IBM Corporation. + */ + +#include +#include +#include +#include +#include + +#ifndef MAP_FIXED_NOREPLACE +#define MAP_FIXED_NOREPLACE 0x100000 +#endif + +#define BASE_ADDRESS (256ul * 1024 * 1024) + + +static void dump_maps(void) +{ + char cmd[32]; + + snprintf(cmd, sizeof(cmd), "cat /proc/%d/maps", getpid()); + system(cmd); +} + +int main(void) +{ + unsigned long flags, addr, size, page_size; + char *p; + + page_size = sysconf(_SC_PAGE_SIZE); + + flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE; + + // Check we can map all the areas we need below + errno = 0; + addr = BASE_ADDRESS; + size = 5 * page_size; + p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0); + + printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); + + if (p == MAP_FAILED) { + dump_maps(); + printf("Error: couldn't map the space we need for the test\n"); + return 1; + } + + errno = 0; + if (munmap((void *)addr, 5 * page_size) != 0) { + dump_maps(); + printf("Error: munmap failed!?\n"); + return 1; + } + printf("unmap() successful\n"); + + errno = 0; + addr = BASE_ADDRESS + page_size; + size = 3 * page_size; + p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0); + printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); + + if (p == MAP_FAILED) { + dump_maps(); + printf("Error: first mmap() failed unexpectedly\n"); + return 1; + } + + /* + * Exact same mapping again: + * base | free | new + * +1 | mapped | new + * +2 | mapped | new + * +3 | mapped | new + * +4 | free | new + */ + errno = 0; + addr = BASE_ADDRESS; + size = 5 * page_size; + p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0); + printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); + + if (p != MAP_FAILED) { + dump_maps(); + printf("Error:1: mmap() succeeded when it shouldn't have\n"); + return 1; + } + + /* + * Second mapping contained within first: + * + * base | free | + * +1 | mapped | + * +2 | mapped | new + * +3 | mapped | + * +4 | free | + */ + errno = 0; + addr = BASE_ADDRESS + (2 * page_size); + size = page_size; + p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0); + printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); + + if (p != MAP_FAILED) { + dump_maps(); + printf("Error:2: mmap() succeeded when it shouldn't have\n"); + return 1; + } + + /* + * Overlap end of existing mapping: + * base | free | + * +1 | mapped | + * +2 | mapped | + * +3 | mapped | new + * +4 | free | new + */ + errno = 0; + addr = BASE_ADDRESS + (3 * page_size); + size = 2 * page_size; + p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0); + printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); + + if (p != MAP_FAILED) { + dump_maps(); + printf("Error:3: mmap() succeeded when it shouldn't have\n"); + return 1; + } + + /* + * Overlap start of existing mapping: + * base | free | new + * +1 | mapped | new + * +2 | mapped | + * +3 | mapped | + * +4 | free | + */ + errno = 0; + addr = BASE_ADDRESS; + size = 2 * page_size; + p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0); + printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); + + if (p != MAP_FAILED) { + dump_maps(); + printf("Error:4: mmap() succeeded when it shouldn't have\n"); + return 1; + } + + /* + * Adjacent to start of existing mapping: + * base | free | new + * +1 | mapped | + * +2 | mapped | + * +3 | mapped | + * +4 | free | + */ + errno = 0; + addr = BASE_ADDRESS; + size = page_size; + p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0); + printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); + + if (p == MAP_FAILED) { + dump_maps(); + printf("Error:5: mmap() failed when it shouldn't have\n"); + return 1; + } + + /* + * Adjacent to end of existing mapping: + * base | free | + * +1 | mapped | + * +2 | mapped | + * +3 | mapped | + * +4 | free | new + */ + errno = 0; + addr = BASE_ADDRESS + (4 * page_size); + size = page_size; + p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0); + printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p); + + if (p == MAP_FAILED) { + dump_maps(); + printf("Error:6: mmap() failed when it shouldn't have\n"); + return 1; + } + + addr = BASE_ADDRESS; + size = 5 * page_size; + if (munmap((void *)addr, size) != 0) { + dump_maps(); + printf("Error: munmap failed!?\n"); + return 1; + } + printf("unmap() successful\n"); + + printf("OK\n"); + return 0; +}