From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S939384AbdAKSVY (ORCPT ); Wed, 11 Jan 2017 13:21:24 -0500 Received: from mail-eopbgr00136.outbound.protection.outlook.com ([40.107.0.136]:12409 "EHLO EUR02-AM5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S939338AbdAKSVH (ORCPT ); Wed, 11 Jan 2017 13:21:07 -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 , Subject: [PATCH 2/2] selftests/x86: add test to check compat mmap() return addr Date: Wed, 11 Jan 2017 21:17:30 +0300 Message-ID: <20170111181730.12458-3-dsafonov@virtuozzo.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170111181730.12458-1-dsafonov@virtuozzo.com> References: <20170111181730.12458-1-dsafonov@virtuozzo.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [195.214.232.6] X-ClientProxiedBy: AM4PR01CA0027.eurprd01.prod.exchangelabs.com (10.164.74.165) To DB6PR0801MB1734.eurprd08.prod.outlook.com (10.169.226.149) X-MS-Office365-Filtering-Correlation-Id: 1d99099a-18b1-4fd2-a3a7-08d43a4e99e9 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:DB6PR0801MB1734; X-Microsoft-Exchange-Diagnostics: 1;DB6PR0801MB1734;3:v9CedSwEAk1ps2SvxeDvEYEk6kFEYdPJk2GYQQg0b0zTQlDseUnrlmbwr/59tIw4gY8vIp2XdltBp98Aufk9XUnGVhXbsBRpNozuZxFCS8/0bhDr/+x0mArETryULzdSURpfyPhOYpK5YQZ6NBIF/4i0DEYSOyEOcxCsUO4ljQ3TRRQc0G+jD/G0dk8eHhTMRQBIonIkr/n85SCTHskzikiadHu0hUiUzHOe3xE/YwBebE08dpHaGUxM3Sc/1wIgQTs0MKGBWeNUMDW5WLf5Nw== X-Microsoft-Exchange-Diagnostics: 1;DB6PR0801MB1734;25:RyNDVXQ56vJsSO2ZuCaJjZBZ3+hzY+Z1RN7vVc1dloOFltnZZfTdC/dnQfjiTTrxJ7neQnM01UA0PxfL2jiRR5E6A0VmJyIW9Ie44EtOYYjUuYrQzoieQlz9jkswi7N/tXAWesbucFEJT3VxnuxRfnyx9klqvVNwJ1hO4LLcP41OHb20K8ve2w+uTP6dELCva3rtI2c2PeD1VlR6hgMvfGQ12vpy1jbZYzlhCiEMeUVYgUcqNdQv0FTkIEWH6061fk+E8tNG1xzfcG2tyQEpeE7KYEq+Kkv2URCNSw+GeBFDYhJm4ZJgGV3zeHAKv49EZQCvO+f7a+UsfvoSr3mWYpjVuhRZ14LFz6daovX0TG1kWdE6OsuwB+Hsp78/N2G9u0FacmdnUfbZ7xzquT9JDs8fmASiW2MpVSK0skhX1VdLFJ+tJWsjw0AHA2XlS89yQuXXl+a+PjkRjZ5DPlXL8JROMRCaMsCE3sLZlYVejYEOWvDB5Y9JidGoeLusNE0OcXwVR9/YiJhlx6UTW6afTsR7E9oII0kd1EHhMDqdajWelSOqJLixaHtpVz+zI/vJEj8GHc5QcIKSde43vt88P4T429XB9SMiBaCdisY5ZXjWtMLL4izoN8+j0dk5bhtoQzkVepVqbxuWAknjneYHD0PLDThikXJFFROcoOoq0IWRbU4jx1OhgOkzU1IesvpD7AWZbBZTr4fvt34dzlflG2fzFLBHtWXTOYU8YH2NnL6i4G8csEhKGHDFAstDAx2x X-Microsoft-Exchange-Diagnostics: 1;DB6PR0801MB1734;31:qBb5aPlTOYcrKhzG601sxNy7tp3HCijawXkHJlMSn+d2MRunqUf4jiCFooj0pu0u+WiBSP/ATDmT1CTdFIz36byUFd3gWWEjRvBmBwaXGU/C5bhAPBkcmVoCH0ZnikATv9UZGu0IdQzuUGjeLNELuvpr5KAEMFPvLNYU9Y0MeZJsDSgGYxJznaNNY8nMGcuWq6RLHFVPCUoPSCuxVr7W4TokJZVemo0FM9rJykkQLV2BvKTqXRWeUh5h62/RmafMKBBIHNuoHtJAzkOMvvsKHg==;20:EGxFR+XT8TyIRTLtzQtMe83/sJ535qHdw0794WRB26lHSoOknTEY/iIbnW0XJBFi0d5fnmqMhdBGP2RTm+CzorXM/UMyIbEAy+qYlNARFeY+kpG6k7bAAARy0srWvPYFjb2bGMQCw00FLBR9gy8DRDFsRO5+kDnqMUgvN2+Rq/GRbPX+u5S6gu+M4fbr/ud9uVRsJnClAToHn6UGLV4HDfFZZfZgbKV5Jn3q095Avo093FTSVhMRU8mwkuu3a9QW X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040375)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046)(6041248)(20161123562025)(20161123555025)(20161123564025)(20161123560025)(6072148);SRVR:DB6PR0801MB1734;BCL:0;PCL:0;RULEID:;SRVR:DB6PR0801MB1734; X-Microsoft-Exchange-Diagnostics: 1;DB6PR0801MB1734;4:icnyJ+shYUsVQXtpydo34zVlF2EnTdPkh0K7ORjOPgmwiXy5YfzL2odfzxeSv/e7oDb5UlPJZ3G3jnQU2daoM9HzBJEqyAunZXqS9U+uGo7tV6b6fs/5p1Au0i8msV9qXiF9QQ93pnZ3od8xCwVjzmBXXGAivypTRsavwqs6WVob21jarlyzeronFoqZdBF5xPFqGUCbyBO9d3ZgwBcTr6c1sjjrqvrxuNYuJUQUHanK3XseiKy3M28sqyGV0GI5pKnwnzgasdWcB69oUYjE1qOidVVnTYuKkRbnY+eajBEY7astqjeA2ZkarwL1dMh9P1sItCyDvCGDyAxCby3hWlKxmZKfbzFhAwwJn3j47a4vGofKSH9I0Tki4b/xkFlTGcrLTkLJlXPerCF63L9BSNiDiMK/WzVPUwXIjfwQTb2ZrdjtC7sypr2PyLS62hDczu2zQ561rDONCcrWHzBYwKcxPUbTShBaN3OzQd9kOfBaLF6bS80Qr2ukPhCh30Q0Ar/5tlY42ydQZILBJ5SuBR9K68jOOnxWAjAEQJC2qp/7EzylT7RdfJzOPwRa8JaTSI6TWV8KQr/grI2MqcWYIA== X-Forefront-PRVS: 01842C458A X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(4630300001)(6009001)(7916002)(39450400003)(39830400002)(39410400002)(199003)(189002)(50226002)(81156014)(8676002)(2351001)(36756003)(47776003)(76176999)(101416001)(106356001)(33646002)(5003940100001)(6666003)(86362001)(42186005)(53416004)(105586002)(97736004)(6116002)(3846002)(1076002)(92566002)(66066001)(6512007)(5660300001)(68736007)(48376002)(2950100002)(2906002)(6916009)(50466002)(81166006)(50986999)(305945005)(69596002)(7736002)(189998001)(54906002)(38730400001)(4326007)(25786008)(6506006)(39060400001)(110136003)(6486002)(2004002);DIR:OUT;SFP:1102;SCL:1;SRVR:DB6PR0801MB1734;H:dsafonov.sw.ru;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;DB6PR0801MB1734;23:AgNg70EGavHESUvAw3wE/YUAA3PcJGHedsnFZT8?= =?us-ascii?Q?b3D0N6KmD7IYVPj5viElCsFXwt9KtrurKnfqaYijmObJp2RnbnkSRZWLT2XM?= =?us-ascii?Q?B0cnhPvMuYgTT5RMIZhTIrNxE3brQBPp9564/0lPpzHkmcHQvu1t4kPdqGvW?= =?us-ascii?Q?wa8o3pafFgLvqPHjcC06wMgADp26SaevzZUplSlikirgZ73OOp8eJhWtnJxs?= =?us-ascii?Q?m3xs8MCHyYeFiKZT+9EQKHXXd6gYTz+l0wWDdgkuy+UzYSw7Zvn/yuWi+RlY?= =?us-ascii?Q?v4Ws4rBjKqLc2LBG7wrDpn7iYEhstLjQvxNn1hqwOa7CHeL8W+xbq+2F1HHl?= =?us-ascii?Q?wooT62qzLlJ+JEyoDx9Y+iJb8zliHxB0Nou2IXHHnfIJ8dK1k9py0BZtaZ9J?= =?us-ascii?Q?l17algSfPweJrsFB9k5hKfCnZuVEdOX9yohR1VQXr/rLR3SgG5uVn/9VSqi4?= =?us-ascii?Q?gRKtc5sR6tvEq7Xf/ezhpf0sZmJidpJ0xTIIwKDW1db8UODTcqxj1GXCa9qg?= =?us-ascii?Q?9vZgJvBuFhvPBcg3VZFphN6nzWRenHCPONRhhEzubwwwWqPAiJEYvk0/kjEK?= =?us-ascii?Q?mdTDApMmurW24NQ7sg0E3Qvbzh5cPhWfzO6eddOyrvvgmOQ9A3ouOZuQNKgS?= =?us-ascii?Q?Vh7XTthnLQTLLANpfZdrNZ6yowC0wlfmCpdObZSGp5l3+oQ0GqJ+V20yKA1W?= =?us-ascii?Q?HY/agoMDi++mZVPPI/Lo4XDvigbwc8ghrQmqjkyzzZnC1yeDc70ZpGWh85R+?= =?us-ascii?Q?X5DsM9w3b5GqweDRq841lrndvpF+YwEaOe6Qj99JIMD2NgmNbM74xnEmAGED?= =?us-ascii?Q?Tsyy7etfr4i45pz3I5vRTmvGJookXgZHo9llE3Z5Q8wngMp8CudOblVlXVdC?= =?us-ascii?Q?35BqWys0zPNRDxaT2q6RcHmzYUV1/bSXdhEV3HhJwA8eh+dB32/fp4Y4hTyI?= =?us-ascii?Q?OXR5aYgQjEohALNMIUUEFkRCPuD8xqI0fHLOCUl8mXHGaC9optqDbLTgx09Q?= =?us-ascii?Q?whSasbArZ8M222rMRWchUb4fkAOoXJ8Jlo3nZ6iIoh2+L//JyAd4Kdc0L+Ex?= =?us-ascii?Q?ec8AkI4rSFjJw3brYqym1eXypmEoaeoKHSfmrjLPv33qvNX/0gakWGfMeLwp?= =?us-ascii?Q?/Dhp3heSr/wKddX68Ahzfhffe1xsLFt7+fHO6vg04HIrZALkKrTG/f7RtuzM?= =?us-ascii?Q?3c6Ur3+sFADiWloa+9NmnqVgPjBgZUOcE4+o05cIc2c1nYuddISVPBGFc0A/?= =?us-ascii?Q?AOruXU99+ZPtiojlQXxTHYdC344JxQGS/9RDCcaRa?= X-Microsoft-Exchange-Diagnostics: 1;DB6PR0801MB1734;6:OLsjszXb23i6N8xzkaQ95OIZx792ce6SZVgnfv8O5f3WDe9WyLOPe6CX5yyB24G6ZF1eQ6CtE+PTEAl3spxZHbToxKl37zR/gKnQaIlI4NI085QfbUE16F2pnE91hPC2K4fa/rbnZNVB7QJkNpf4BgFbmuZ29ZkIxTHngt+JX/CUVt3MjXIZUVrndtA+yOu7AnRjss1SQ8lHg260rr+W8m+i55oVNMprKp7TvAICaok1tzxEOS1ExIDrLPgc5tXN4JH5b2aTy/6nwKXShImtv7MLSTj+cf07JW/QnwRIuOuVaqM2IwY54vfOJ1IzlMQf2eiEhvnc3ghbfb5d1XLg0X0H38S9+9+U+FIvXkmhAnbFeMqtcEas1rh8wxWoIlrzmqK2cQsTgnR6A0FVYAJWXEFWVdW40GyguXJlyb3xYG8=;5:jsOe1wyQ9m/VgjX+JJ8NRGs08S0MgvcNfUGw0Mw/k+4R6vUS2Qti7mJGlQE7+/jBmEgNpU9zgAi1kwWXCbnSb7QqUkhGrXCszBnfz5I9viAoyAVVh/buLp4xxDG6AlOLd64ajhQ3Y1HI2sxb0tWSGrNPQks0MfMn7x/F+0UlFKw=;24:Cvr8ii3KVzMaKxhvgROvGJ1OLu8I0yjHMhcUNWa3KdceqWOqf/AeOBnqIy8B/chnx0ypgRlXMEHGmaRixnrPtPylsHug9Nt/U/i/T315dMI= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;DB6PR0801MB1734;7:1ZlJ5ChtBZuxuRHeZdVez2LY/nwmEzB2Xk23Du5EvYRJ0DPRuVZeSqft239vdjrKmRp6Rih9KWK7gHgeFH/MUhia+SHxobcpTKPm9m4czjwcvqfesei/pyf25JaKROGQkb+FLZDGNtMqsrILO6Lqzw95YjWxaNp2PC/p3yOdV2dC74jfiV83CTmeBJcGJ8alskSJEG+TLCIQtHvZu8pfUwO1I0OJnAYWtzqjpTByHevhvTBR3B95G4reQ0t/Efcl7m70/5QLu020aFEHI0nkZUCif57jafqBbSNOVPFs0Ud+P1PZVYJ0gsqrDsIj+F8bsEURLjOZaiWLY1TyP6xBBjSapE/i8yu+gz0eH7blqh7ej25Rl34ylZdiXF7pNEH/fb3QJ2ULMzGDbPxSGRMsewpxGbinemdQ3KOsyC2pToXp2y06kNnxy+LeAYOOAlsTooMm+4Ey6mxakM1PhOGe6Q==;20:ArGQfn3zvgjqVnBN4AxCNlY02B2q3/Cyhud1faWtfOlIa1v/MP2boeGpXCrNmL4J7CgPDnKdLOOrl6e3QxU/BbArBMBQCfFHy63/EfOcD9zvFHVDUrzwOgcBgYzF+WN9m5CDEc/eqvhiu2R/cSofaYmc4xKLtcM+Mp5w82v07/s= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Jan 2017 18:21:02.3412 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB6PR0801MB1734 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org We can't just add segfault handler and use addr, returned by compat mmap() syscall, because the lower 4 bytes can be the same as already existed VMA. So, the test parses /proc/self/maps file, founds new VMAs those appeared after compatible sys_mmap() and checks if mmaped VMA is in that list. 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 Signed-off-by: Dmitry Safonov --- tools/testing/selftests/x86/Makefile | 2 +- tools/testing/selftests/x86/test_compat_mmap.c | 200 +++++++++++++++++++++++++ 2 files changed, 201 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..4736695afea0 --- /dev/null +++ b/tools/testing/selftests/x86/test_compat_mmap.c @@ -0,0 +1,200 @@ +/* + * 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); + } + + 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 */ + j--; + + 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 (map == MAP_FAILED) + printf("[WARN]\tmmap2 failed\n"); + 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.0