From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752685AbdBNSlJ (ORCPT ); Tue, 14 Feb 2017 13:41:09 -0500 Received: from mail-eopbgr00136.outbound.protection.outlook.com ([40.107.0.136]:45034 "EHLO EUR02-AM5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752397AbdBNSki (ORCPT ); Tue, 14 Feb 2017 13:40:38 -0500 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=dsafonov@virtuozzo.com; From: Dmitry Safonov To: CC: <0x7f454c46@gmail.com>, Dmitry Safonov , Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , Andy Lutomirski , Borislav Petkov , , , Cyrill Gorcunov , Shuah Khan , Subject: [PATCHv5 5/5] selftests/x86: add test for 32-bit mmap() return addr Date: Tue, 14 Feb 2017 21:36:21 +0300 Message-ID: <20170214183621.2537-6-dsafonov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20170214183621.2537-1-dsafonov@virtuozzo.com> References: <20170214183621.2537-1-dsafonov@virtuozzo.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [195.214.232.6] X-ClientProxiedBy: DB6P191CA0023.EURP191.PROD.OUTLOOK.COM (10.175.236.161) To DB6PR0801MB1736.eurprd08.prod.outlook.com (10.169.227.7) X-MS-Office365-Filtering-Correlation-Id: bd328925-a9aa-4455-88a4-08d45508f26b X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:DB6PR0801MB1736; X-Microsoft-Exchange-Diagnostics: 1;DB6PR0801MB1736;3:DbJyr8pvmNVCxTyaeZI5VMyfhrri2age42K0lZ6jSSZRep26jITbQPDYD2apxIXshM6YszGxzzhtp9VqTOOdDnhBfliszhidbwwXYUHonOmfm8NC+tfJ8qDAh4LqNVM+1EUDcdPY/rUDMCHSpEvE3J8OVc5EYyCgsrG7K+qy8hhUL54mDVi9gvOIlTJpqzpe8OlB9XGyaEk6PIHLu42EYTB5684DwPJnpjQ0FSnP8cHMOsSh1x6SUxSVHk9moGZNVVawOzPr2sFgyQ+/PwEmDA==;25:kOR2mdww9Lum9oxnerYv3YLBcZ5cZA9zSRjZIFu0BUEE6R4rvDB/Q0vGbAJlv3cUHSRPvAOFkUQ3ZQ3UHXYfMfu6QlTPw56wkivDP+ddC0JjkZyb1Na/FaMAVTHr0STSKmiBsK6D4w7n5OLLe2V1TbJ9oV2SA/G0KCtWdKg85k/lEJZWGw2tx7FlcGMkn8dEFXEVKEQZyEXI6RowBfqgurSuejlrNRQQbDErL9ClcYBZak4xFCKGWPC75nyoL/AGswDSzOIaaruvFgLNGA5cds7ZSZnwu6izX6sME/O39RbLFoQWAz6RBhrKDc+KCYj+otH10+lV1AfrOIKaZ4YgHu5BE8H7KfIOsY1SLlpWxBeAVfvDqY04b47eIK5BsOGDWYnip+o4+LJ7lzwihdA2MryVJJMq5oJg9IeFAdqo2u1Ixxj4TCQ/oyO5DfAIUtdWHOY9QQmeoJ48uTcS8ZZO0g== X-Microsoft-Exchange-Diagnostics: 1;DB6PR0801MB1736;31:/umTkqoaDURGCVV4Gt7UK21cGJU2iWF8IKPZp6vucYfr/mHPoOAFpANAWXkPicZkORtxP2eKgn2F2QYYr8TgQLkHGGt0iS1Fclt2ieys8StFejgyYn39Jx9B0/3f2/vJDLXWx9CjznUtDm4mBWh8RWMZhT8ZS0QNK+otPfyvVBYfFL1WJWo6W7DWHFDSAVhox/J40tXU7p5ONseOyu0VF/UX5c+14XO1ihXXKpoURYvEJgXcsTcuI+hXixIV77S9;20:vRVgXrQqHqp8yOKK+GQ0ssmRuMH66sh5ivQZ0L4l2Y7Q9kqTKfFFJAuaI2RA2Y5VSQw0DUnQYZ1v27vhjUsOGrL4CHFW21pSN9L7DfvSHd2Gc0B4zGAbIfqSYdnNYtbA9Dl11m55b3S002JWXdgpNV//y7FJQ78/8meZMifllfnpqBfbItHHmRVdo4Rked8+M+v+kSGZwSIt1zj+fupjXs57Z3hTEma40NEB96nFGMOs6qFzO6dfjzigh3y3irgKP4fbO364lam1G3z2X7BW/3NV7ycPmsY1TjNbncrIWMtrTAfVFUqPG2i3jTeyXpzJtD0OMqggvdcyW2rg834kPv70zGT9TJgIdEMS0xxragqngey1kI7RbA0EW7gQFWMsT5f/t81hvmZpUhkTK7RIB8J2GeU8V6ROlQITGnFon5U= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(9452136761055); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040375)(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001)(6041248)(20161123560025)(20161123555025)(20161123558025)(20161123562025)(20161123564025)(6072148);SRVR:DB6PR0801MB1736;BCL:0;PCL:0;RULEID:;SRVR:DB6PR0801MB1736; X-Microsoft-Exchange-Diagnostics: 1;DB6PR0801MB1736;4:oXQjmcNs5O+W0ekMIHQMuukZL17nQxzOfsRclQvwssqIfwTg0PyBIfB3HF7MiX03DfilurcRyvUSHc5fSiot3VnlUrT1AJIN/diI/eSq/lCyTwaau5nKjWZ4RNzK4JiEFaQc2/wBEtOQ0PvGCinM37gvO71dTFQMlKpbB+bCF48uZw453qx/WXQU+ECj/CZdSp47wKX/nlk57o6XbNXjUls1580rSuXiOpBg5TEQAl76ycJ0+adTxSntBahfbKYlAXqb4aufznzORA9A9A2jQ0Hjl4OCMpsu5/2aclBbcbPkMAfEZX/7pqRKwdqyopwzBV2/1a1Dsg4WFqKKbKPtCEWtLpH+zSCKP4waYtcMPNxCIHBsYIhB1wIEuxj0S/DxtQNJ+Hs1J2HAplx/WWVjEw840Db5Vb9+Hi/SHhKn4idcNtZuLT8ynxO4+fJ+hAteVhsyjela33IXfnOASHu5/nGaKZpsSwzeDQ0CPSxifZ6DSsG7c/hw9U5Ku73yEj0+UlYXCccj0BP3Sh1KI84a7H6T0VtAiqIuJGfxG72Ou0eafBGTLEo2G2IamTB5WlBfJqnHJXKe0XsVmfSn7R2vivYJ9DhSIYqh1UwBhOTZCdINvdXTQgwYB76JKMx3fJqEVjemmk2Angi6ru/NQINcyw== X-Forefront-PRVS: 0218A015FA X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(4630300001)(6009001)(7916002)(39450400003)(189002)(199003)(47776003)(48376002)(305945005)(76176999)(3846002)(1076002)(2906002)(50466002)(33646002)(101416001)(66066001)(189998001)(4326007)(7736002)(81003)(50986999)(81156014)(8676002)(50226002)(81166006)(38730400002)(86362001)(42186005)(105586002)(2351001)(97736004)(36756003)(106356001)(110136004)(7416002)(68736007)(53936002)(5003940100001)(5660300001)(54906002)(2950100002)(6666003)(25786008)(6486002)(6506006)(92566002)(6916009)(53416004)(6512007)(6116002)(69596002)(2004002);DIR:OUT;SFP:1102;SCL:1;SRVR:DB6PR0801MB1736;H:dsafonov.sw.ru;FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;DB6PR0801MB1736;23:5LwNJHvKOhsR9JxX1ihLbQ1hxqvvyOywBjyxQq3?= =?us-ascii?Q?cc4dkeGP0ckHNlg1BByKGP839vwnik/HxztC1Fdu4P0GHuHQ7sOJ1PdFXCBs?= =?us-ascii?Q?jf7/BNpC/Rc9gyQGNW6DI+Aj1q58eo6v4e8cA8uny+QkY3y2WnVHBOgd64+2?= =?us-ascii?Q?B/69U7qCEKTg52NV9xf7aJy+BczozM6f6EwDmB6DXWzqkZ2AzoG6j4WvRJ9J?= =?us-ascii?Q?TgpeFjQ+wUsBcCi0jcTrvezyTN9DTxddUyDKAugo8ZhXknwlctV6GHbg7FCc?= =?us-ascii?Q?04D19FFf0DvMXeWE3rgT9zErEklr8SuDxGNONYRfqqAoAGsn7DjnQkWqWzYZ?= =?us-ascii?Q?gtCIFpkGrkL6p/RQGwz0sqJrrinHlpyNPGwAvka7XhNfoqk96D0GYxxhk5J4?= =?us-ascii?Q?D3DWPsejBWW8MbqRWL4N30p++Ou7r3vpdFBp0bNlFeIB38RQZ4IveAsowQTi?= =?us-ascii?Q?dbhqcu6kDxHBX7M/PIevurEhuB/AK5XxeUo9F+UOOODgF10n/a7GcKMxQEjo?= =?us-ascii?Q?gdrIYllvSW4KdXvUwJjQKrUDtnXo4sIhLJjNFBuYyl3voqb6qtnXc+SWf6Nq?= =?us-ascii?Q?2viiyzVxoVtLxtoBaR26hhVoCkJOJeskUm8mlXl3rTq2p8LxH6u9RIaUUQ/p?= =?us-ascii?Q?52io2hOAvSY9iLpYXFiIN1OllpyHea8FGHXAVqLdgacMZA/v1c7HWAj7gMiL?= =?us-ascii?Q?D0y0EJcU3IdmlUnGLEzcYPudDRwVdnN7GdsTKCG+sdRQN09lqYca2dATcDWb?= =?us-ascii?Q?ux2f8CLF8VqDoSJToAs/0PQgWDf9hTP0+kvE1OQIiaE5yG3CNAFop6Ssuwk4?= =?us-ascii?Q?ppemnTgoEX/N1N7EF+70gF4+pmC/JSJDmREl5xeFfCyOb4+vd30P6hwkDnLc?= =?us-ascii?Q?MC2v7uUHdYuJiANS6+x+0NBau/i0xhaoE1KDNxmWgAb06dkk7t6cZNNzTj0D?= =?us-ascii?Q?Co5mruiLIRZxkAQfd+XUpZ2xENwIN2Q8qXIpVP7KKONBW8jkxyi6x7/u8l5F?= =?us-ascii?Q?hRC51On5+OJ+qUhGRp4bztOW3Jj85muqgqTRIrGX5+NZ7c0yaBKmQLcNR9Pw?= =?us-ascii?Q?CgXr8Q0U1PxgzGY3LQ3SPNnton6XOM28hBGGoSuFOOnljnf113Io/Lfuikkb?= =?us-ascii?Q?xyt4OY+H/SyjfH+ddAh+nJc7xteJv1eHEot7JcUJwtW+Eqm1RwZNGDIwnn1k?= =?us-ascii?Q?YwqOxsnfx0Y2GStRL7qy6CcQxuvIDL0WSrh750Vb/pG8D1x3CwwKVP2FDwoV?= =?us-ascii?Q?tAijj1X76EYU71CFGh50=3D?= X-Microsoft-Exchange-Diagnostics: 1;DB6PR0801MB1736;6:pvPpsuAwqlZoe0rNTz/7eo8HzOhpVyrQVTL5hpZ7+ii+/a1h6rQu0H/z/fvtd/FEhji+zO7kSx5yOxRo7PyhzU5O0Kj603Xy+D48IYYSj4IURfzLuIc9FJefVSqad3Ygv/Tpqf9zPWWhRRMlPtBlnhFEXENOdACU9UV3iZ8D1rxkdfNVbEFwxjTOc+Vdf0KTIAB75Iwq6WsBe5hN6CIn14dOQYEX50IghI/MoNQH+mhQgIpI3c9c1FPK4HDoBNsS2nuF13I95OK688/t2CvA5G+9376JwtUHn+ivEzXI3IPC4hxQ31mr+rKRzLNPGgGzaiee+p1YiisyHpQZTtFB/psLaUbE6El7e5pksbEXe+Oo52YxHIClRBiU4QHnhiqca9j0eH4QhpR37o+q1pF03A==;5:U6mA2R4oa8wMv20gaBdT6k9vOc4s77X2VQZqoA5KQs5uTb7k1kt06iivGUWgl+NnVFUFN1V8vBUav2FXMHykRhu9bw12FT7cEwqwvStvmEOLwf3cenRGJGWPdZ6zhc8rv63YU9ED9jPr2e74aMx15g==;24:fRJrbR4FDpw0MPWytd7u8vTHKKPLetRCHdfM9YIf5voAhN8wxCzGu5wjDeFh4K8uq7X04V/yNNZYqr6ry+noze1yj6kySh8trdLqtPJsnUQ= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;DB6PR0801MB1736;7:OLrCWCZS3Wsl4XCNtHsBhBA1APDV5aPtOuLOOTATbT65j99JBTaEVw9p/1QRxNxZ4MxpfA2wIy6vkjPe008l52gKLZqE7INWJ2UFI4fL0fXsU7ZUAeDMM7IB2CJC+9HGSNH/9yPeENQxe3k3TZWv0Snok/6dXWMa8KQmBXmFLp3gYmnCoU6EiEDLw6ol5oNY4jJnHOdN7IfvNLDaUX0RKkbOAObTj3Up2p0hD3G1gPsJYmRv+jVB3p5U4GxEhi9e6153AN7Q7sI1wemlcdA3l5EHK2kA8EeYWWs0A3lznUH+2xZMYKraDzNgwMIFN4p9RsDnhPBiRMzn4u5mZtbrRMbSA4oYf7MH9tVgo77upApmTfqeBUZoLxIQyDbT+NpQAi6UrhGEyM0mV3N+HofLblXF/1ZHUcTt1Fit6K+ylKfstKMZgP2onOG1zfBHJ5wKM8waB9hbdwkWs4ZUtj15ePEeCc94F1nAS22gCg2bdKF5A9s4PVZ8CRZ/7FyxuX9p4/iUox0/obj8WuPJQWCxMA==;20:o6Y9x4Kzht+jF9AvwdR99MqdVOI0+ybgOP6T3WiwpWkGQCsoJBg8cdzR3rhs7VFDICWmCMX4U5vTkq2p0daOivsArmYn/CQI7qEqS6mwVt3xkfFngEO0BFrEfjh7rhlYVh78xYhVlsVxoolvdsis99TFPBlMm1khugHzSDTW3/g= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 14 Feb 2017 18:40:27.1297 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB6PR0801MB1736 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This test calls 32-bit mmap() through int 0x80 and checks /proc/self/maps for allocated VMA's address - it should be downer than 4 Gb. Just accessing allocated with mmap pointer will not work, as we could have some VMA placed on the same address as lower 4 bytes of the new mapping. As allocation is top-down by default (unless legacy personality was set), we can expect that mmap() will allocate memory over 4Gb if mmap_base has been computed not correctly. On failure it prints: [NOTE] Allocated mmap 0x6f36a000, sized 0x400000 [NOTE] New mapping appeared: 0x7f936f36a000 [FAIL] Found VMA [0x7f936f36a000, 0x7f936f76a000] in maps file, that was allocated with compat syscall Cc: Shuah Khan Cc: linux-kselftest@vger.kernel.org Signed-off-by: Dmitry Safonov --- tools/testing/selftests/x86/Makefile | 2 +- tools/testing/selftests/x86/test_compat_mmap.c | 208 +++++++++++++++++++++++++ 2 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/x86/test_compat_mmap.c diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index 8c1cb423cfe6..9c3e746a6064 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile @@ -10,7 +10,7 @@ TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_sysc TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ test_FCMOV test_FCOMI test_FISTTP \ vdso_restorer -TARGETS_C_64BIT_ONLY := fsgsbase +TARGETS_C_64BIT_ONLY := fsgsbase test_compat_mmap TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY) TARGETS_C_64BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_64BIT_ONLY) diff --git a/tools/testing/selftests/x86/test_compat_mmap.c b/tools/testing/selftests/x86/test_compat_mmap.c new file mode 100644 index 000000000000..245d9407653e --- /dev/null +++ b/tools/testing/selftests/x86/test_compat_mmap.c @@ -0,0 +1,208 @@ +/* + * Check that compat 32-bit mmap() returns address < 4Gb on 64-bit. + * + * Copyright (c) 2017 Dmitry Safonov (Virtuozzo) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +#include +#include + +#include +#include +#include +#include +#include + +#define PAGE_SIZE 4096 +#define MMAP_SIZE (PAGE_SIZE*1024) +#define MAX_VMAS 50 +#define BUF_SIZE 1024 + +#ifndef __NR32_mmap2 +#define __NR32_mmap2 192 +#endif + +struct syscall_args32 { + uint32_t nr, arg0, arg1, arg2, arg3, arg4, arg5; +}; + +static void do_full_int80(struct syscall_args32 *args) +{ + asm volatile ("int $0x80" + : "+a" (args->nr), + "+b" (args->arg0), "+c" (args->arg1), "+d" (args->arg2), + "+S" (args->arg3), "+D" (args->arg4), + "+rbp" (args->arg5) + : : "r8", "r9", "r10", "r11"); +} + +void *mmap2(void *addr, size_t len, int prot, int flags, + int fildes, off_t off) +{ + struct syscall_args32 s; + + s.nr = __NR32_mmap2; + s.arg0 = (uint32_t)(uintptr_t)addr; + s.arg1 = (uint32_t)len; + s.arg2 = prot; + s.arg3 = flags; + s.arg4 = fildes; + s.arg5 = (uint32_t)off; + + do_full_int80(&s); + + return (void *)(uintptr_t)s.nr; +} + +struct vm_area { + unsigned long start; + unsigned long end; +}; + +static struct vm_area vmas_before_mmap[MAX_VMAS]; +static struct vm_area vmas_after_mmap[MAX_VMAS]; + +static char buf[BUF_SIZE]; + +int parse_maps(struct vm_area *vmas) +{ + FILE *maps; + int i; + + maps = fopen("/proc/self/maps", "r"); + if (maps == NULL) { + printf("[ERROR]\tFailed to open maps file: %m\n"); + return -1; + } + + for (i = 0; i < MAX_VMAS; i++) { + struct vm_area *v = &vmas[i]; + char *end; + + if (fgets(buf, BUF_SIZE, maps) == NULL) + break; + + v->start = strtoul(buf, &end, 16); + v->end = strtoul(end + 1, NULL, 16); + //printf("[NOTE]\tVMA: [%#lx, %#lx]\n", v->start, v->end); + } + + if (i == MAX_VMAS) { + printf("[ERROR]\tNumber of VMAs is bigger than reserved array's size\n"); + return -1; + } + + if (fclose(maps)) { + printf("[ERROR]\tFailed to close maps file: %m\n"); + return -1; + } + return 0; +} + +int compare_vmas(struct vm_area *vmax, struct vm_area *vmay) +{ + if (vmax->start > vmay->start) + return 1; + if (vmax->start < vmay->start) + return -1; + if (vmax->end > vmay->end) + return 1; + if (vmax->end < vmay->end) + return -1; + return 0; +} + +unsigned long vma_size(struct vm_area *v) +{ + return v->end - v->start; +} + +int find_new_vma_like(struct vm_area *vma) +{ + int i, j = 0, found_alike = -1; + + for (i = 0; i < MAX_VMAS && j < MAX_VMAS; i++, j++) { + int cmp = compare_vmas(&vmas_before_mmap[i], + &vmas_after_mmap[j]); + + if (cmp == 0) + continue; + if (cmp < 0) {/* Lost mapping */ + printf("[NOTE]\tLost mapping: %#lx\n", + vmas_before_mmap[i].start); + j--; + continue; + } + + printf("[NOTE]\tNew mapping appeared: %#lx\n", + vmas_after_mmap[j].start); + i--; + if (!compare_vmas(&vmas_after_mmap[j], vma)) + return 0; + + if (((vmas_after_mmap[j].start & 0xffffffff) == vma->start) && + (vma_size(&vmas_after_mmap[j]) == vma_size(vma))) + found_alike = j; + } + + /* Left new vmas in tail */ + for (; i < MAX_VMAS; i++) + if (!compare_vmas(&vmas_after_mmap[j], vma)) + return 0; + + if (found_alike != -1) { + printf("[FAIL]\tFound VMA [%#lx, %#lx] in maps file, that was allocated with compat syscall\n", + vmas_after_mmap[found_alike].start, + vmas_after_mmap[found_alike].end); + return -1; + } + + printf("[ERROR]\tCan't find [%#lx, %#lx] in maps file\n", + vma->start, vma->end); + return -1; +} + +int main(int argc, char **argv) +{ + void *map; + struct vm_area vma; + + if (parse_maps(vmas_before_mmap)) { + printf("[ERROR]\tFailed to parse maps file\n"); + return 1; + } + + map = mmap2(0, MMAP_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (((uintptr_t)map) % PAGE_SIZE) { + printf("[ERROR]\tmmap2 failed: %d\n", + (~(uint32_t)(uintptr_t)map) + 1); + return 1; + } else { + printf("[NOTE]\tAllocated mmap %p, sized %#x\n", map, MMAP_SIZE); + } + + if (parse_maps(vmas_after_mmap)) { + printf("[ERROR]\tFailed to parse maps file\n"); + return 1; + } + + munmap(map, MMAP_SIZE); + + vma.start = (unsigned long)(uintptr_t)map; + vma.end = vma.start + MMAP_SIZE; + if (find_new_vma_like(&vma)) + return 1; + + printf("[OK]\n"); + + return 0; +} -- 2.11.1