Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754146AbdCFREa (ORCPT ); Mon, 6 Mar 2017 12:04:30 -0500 Received: from mail-eopbgr50096.outbound.protection.outlook.com ([40.107.5.96]:48448 "EHLO EUR03-VE1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753521AbdCFREW (ORCPT ); Mon, 6 Mar 2017 12:04:22 -0500 Authentication-Results: vger.kernel.org; dkim=none (message not signed) header.d=none;vger.kernel.org; dmarc=none action=none header.from=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 , "Kirill A. Shutemov" Subject: [PATCHv6 2/5] x86/mm: add task_size parameter to mmap_base() Date: Mon, 6 Mar 2017 17:17:18 +0300 Message-ID: <20170306141721.9188-3-dsafonov@virtuozzo.com> X-Mailer: git-send-email 2.11.1 In-Reply-To: <20170306141721.9188-1-dsafonov@virtuozzo.com> References: <20170306141721.9188-1-dsafonov@virtuozzo.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [195.214.232.6] X-ClientProxiedBy: DB6PR1001CA0021.EURPRD10.PROD.OUTLOOK.COM (10.171.79.31) To VI1PR0801MB1742.eurprd08.prod.outlook.com (10.168.67.20) X-MS-Office365-Filtering-Correlation-Id: 3b799a1c-ab3e-4c6e-8b64-08d4649c0ffd X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:VI1PR0801MB1742; X-Microsoft-Exchange-Diagnostics: 1;VI1PR0801MB1742;3:rsnS+hfc+ROUqhewSIJNmt8i6nhLxdZ6ytcG6uUCQmsAv6ycnllwGDpbAT/khf/E/ODQlGhnyhI4VAtE6gcHL8i1AOt71+UZ3DaWvTvkZHgMBby3F9NXea0zH9I2t0fOWIBSKspHgzl+Q+8/rcs14zZ3KovdpEhi4Z8nKr8pLmc+skGUWApbu2NaJJtePii6zqf8uBfyIqbGd9AcO0iavOrS2qX70aQK4+RLxwgIZ2E+meMR/tWSE84UhbOn1NI5vluNTqaIJYuzjhe67aUEIg==;25:8Spj3X3hpOt1P+EUFpfturZ2MheloGY0jA+PqGYc4eftGBxtu5iyxyoVQlACQLdHiXonq/eAQT6btETeZpKgl11MX9Oz89qePeKDOHUJqVYmuyY0fja5r5E30SWYE/pjyIopSvQrk/pihOmSgt5POIWWyFElcYQID9pYCLzGZzZbO0WiRS2C2nQzPYr78+dxr0cXkoRwAiUaY5NK2tdLNlby/CiIToNQWRQeEhcvUAZWCe/icTXoiThHP1R4rUL0AnXfxzv9pOyaGYjQJJoTR5T6OgkA09ynmPtUHvYzMzOMfqNANTiBela+vIKZAw/5UFgOdVF2C1LcercK8e7Xcfw8cWSUwgKMgpe1C0KeSAieqVg9IH2AYQB69Q4chpr3/REkw6JF1lbnUSMq4v+F09fOqmBSxkslvrmoDGoToMxMGdtYDN8gEt8RFL7+sXVzueV7ul1abOQotXjJRLn4QA== X-Microsoft-Exchange-Diagnostics: 1;VI1PR0801MB1742;31:rgnFyxiqhfPlNshdksfYGMvBUriLQRcAx5Lu44tm1dXINBfemJyL24sk+/PSeZU3AjecnrFlYEgoCATTKy0046jExmXpIh0FtAKMcKkgrjJ2EdGzfGTdkdafFLA00InBir2pY9xp6l01HvcWPx5vm6UcBi3xAxf6bmGCSiHZRpakof4l4P8HO3k/xlMgCtSFQ6wx4G5EUg708MFzBIO/juGoh2X6o74HP39kuC3uCliYmepRYTAr/wJx+kkasBin;20:FhRFTht/MlXEGfR47Byn3OHSABocL9kLIZAwplOg9B5OYuwkLOE4ghXBuwkZXD/FgGKw525ML51TwRndeIbHzCCOZLUszz9RoIoWicPrjF2YqYQxHEKa0/+aMPJRp/8tnpPCeNghApM+tBDNhdPEoy/mVMeENV1OFeDnke8am1F613M2CnKM6puaWj2eLwFy0C8WrS/pjXbhDw5NBlLK84g4aFmgX4eHz9eyBviKFruoMDPxNaF9FUps+tZ/fYP3i2/JLuoZn0ykw33etndhjmTBzkarvePMIEbHGEbZd1QWbohSMt3luYnTnBZdAqwhv5+trYkXcmY7fqm5HdgPQdO1ShpdZS7+01iLELrF9VWChOCSps+RGJVQ0xydAQ+kMuQXMNcHIrBVY7E89aV2hvzkz8hXjN6uNgbwwqzjsw4= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040375)(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046)(6041248)(20161123560025)(20161123562025)(20161123555025)(20161123564025)(20161123558025)(6072148);SRVR:VI1PR0801MB1742;BCL:0;PCL:0;RULEID:;SRVR:VI1PR0801MB1742; X-Microsoft-Exchange-Diagnostics: 1;VI1PR0801MB1742;4:nQr50TZ3cmIzsquCGjR512CiHsUR0HOnpCwpo67bA3BcsgS8b/CNm/aT+CdV/ky45h43UNr40CzLlGwF5WVXD8FiJRxi7wouNVwes2UIGONPFhQPzt3w8NxbbeprcA39ykpSHonCAM8lfB+LOXH+6sABrDbmjmjXj4PNS0ObF2WB4ugNXKOF6kM7dcn5EntO3lGpX3kCMBpdUYcw8jSKA6gY5HYgSSDDNvuOcO6O5alGy3uUszLYOe9LLgvZw9KmhWboPf9ZConOSCki3aQig5qv4+BWvjfenfFxKLz+7wePuPjeDl6197IJFv3f3o420Y4+BI2CA2eIn7yooq+rcOFkDOgxE8e6rl5uz/TgmRP+pXXaUv9ONhux60lgBtp3oQxks6k0mahLsjJkLLEvPrKSRhJPCkqWeTnECELsQWfQwFnQNSm1M3rhbtrP3EgYjbTLwyF5z/PmpqxmBM3aM4K2a0fm4DB7ZScVcSM9Gkt48zwXz2pGM2v9xUsq6nJ2SiE3JyavEZ1UKPfYIwr1O6jrtwZu04JnQUi0I3wsv++HMFfpBEVYgkjCxvcytBl+NoXhy5O6KvGOtTDBuNCSrq0GrKC0nS0UQ8XsZPq0MfE= X-Forefront-PRVS: 0238AEEDB0 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(4630300001)(6009001)(7916002)(39450400003)(2906002)(110136004)(6916009)(2950100002)(305945005)(8676002)(53416004)(38730400002)(81166006)(6512007)(50466002)(42186005)(7416002)(1076002)(7736002)(5660300001)(53936002)(5003940100001)(76176999)(50986999)(48376002)(25786008)(66066001)(575784001)(54906002)(86362001)(92566002)(189998001)(50226002)(2351001)(3846002)(4326008)(47776003)(33646002)(36756003)(6116002)(6506006)(6486002);DIR:OUT;SFP:1102;SCL:1;SRVR:VI1PR0801MB1742;H:dsafonov.sw.ru;FPR:;SPF:None;MLV:sfv;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;VI1PR0801MB1742;23:ICyGcTPoDCoV3tGwz0RjFkk51DMmZsxAVNWhL82?= =?us-ascii?Q?fJFUm38yt1+q/CGGDEaZlh9PE6/yvqVOIKTK+4qcZ6L7OYppJCAJLUPq0TQX?= =?us-ascii?Q?ReEiVTLMAnyYmZXSgC0SadsfhoCtHhTXOckinZ6PzE8ih87/8pqsUNPrSRoi?= =?us-ascii?Q?VB3VeLiYtkA7tGDMWNx39fkrAK2Z2fdVBEMcRGWjYG0jvajFaUExG8GMk/zF?= =?us-ascii?Q?5pTvNHlsPnxlR1NLnPfjiprGb+dIR8TxtLEUU6DnJnSxju5yJDj/+MNG4tqa?= =?us-ascii?Q?Dqy3b3GtS997m5LowM4iGcgwcAmYdHZfz7qnhw/8CEa8okFaRpEgEvrp2HFG?= =?us-ascii?Q?iezWlL70DV2P2pAB6VRR1Qn1+Flh0y3dAZoIQKrvmCnjj/ipyGpAUsA2Iv+W?= =?us-ascii?Q?32rg4kn3uU4AkRnkny8Cpg7AvDYhLEp3L1S+sbz/8P2QaOVhNM12vxrkvpwN?= =?us-ascii?Q?J6ChPc1wOkyRnJwWeEwelts3mO4/w8A8wfg6yvO1JoMQx7GE9SfpsdtD/FDE?= =?us-ascii?Q?QkbYqcMIavjwfa8l5QyysuKlIgevlK/sbhYegaS0ItVCajwsG1TLjNHAUFVo?= =?us-ascii?Q?j5XqbGDYPMoO2aHpJmyfmBKuUvTLPxuFdfqj0xxTbRyNHXxAiyeSIjvOSXzh?= =?us-ascii?Q?A968jgsnJqnXkqYrAhSFW4ZGYRsdi06JW5b24di0xl37A9yLcJgkg4jjdwes?= =?us-ascii?Q?iM4QVdZRMe8NERymaMn1vUM/TQJeiKAz3Ke9aiyoyt+0vW4Bm7SDH0eEb9l6?= =?us-ascii?Q?mW4k2yaEMHbfqMFyIvcw6HndAO6XT6HldSaj6z1Htt1AgBdxLxxnk+5PtDZB?= =?us-ascii?Q?gmulUyBgx6LesY9cBEISV2Gvt44bnLvKZRZ+A4cpGL6N0lWV6eKQb2YIxXLl?= =?us-ascii?Q?FZ+8GkEXLXvrE/G9/MZzRyca0vcIbPax95ip9XT2Op/rMIOVAbHV6jUlQsJf?= =?us-ascii?Q?LlunaAX/w/uoACmE2Syyo7hCM6RR8cOtAw2WKOwzfjCaXexNY0r8cJfz+lF2?= =?us-ascii?Q?k67/jxYdvp/uSiGLMU7COwNrreO7LImjGb+0e/NBAiU4LcQ=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1;VI1PR0801MB1742;6:c7ZxwxNivmeYBYWYQBZU1spRU0J38WZUeeTa8v4x24XCYrOWUsx9uBY/J1ETqBOHKn+wLWt90pvazn9AXa8M9GX2WCZrdRbxrmEoc65nd13H5Mgnlbh/MCecyvHdq5OXew2VH8MVl6Oglpr2myzTQ8iX/xVgLNUIff5iqQGpz/sYAqQK0gCAcbAzZ3VENELH3wRyhqG5/D9EPPLp+Tl99k3Cle3A8mbuZYVhfxRCaGQ9dbMLWQ/04HpQvk1ktr3VtWpWQSll9EUyFrhQEkDSv8GVXDI9a/PZ1ZQitinBPlP02Xb3I/FdQQlwTOP/6pCnmhIzPGC33ds2rDz/uGkV5y12drz9scM3KF8HYKURvIvGI0LOHLFrAGsCnx/+dSiiBNyIbzK7TgtemT15CO4Hmw==;5:DvpRaiwWDcZM7OdbrVcGnEGOOeTkEED4T3e87NN1ylxGdyVTKb8+POEIUSmPOTS/3Y+83dPVtOkPY9KzYoiMs81EOojZgnw4HQf9hMwdrQqe0yo0DYyQEZzT65lV+65ghw+ioMqLwL6YO5nXsMUxcw==;24:QTJ0RR0tkiIR2rZYDekYKPjPEy8HGdsSmJ3Bx+rIlTDfflxPXymG5w9gmW/pS2//iBn1fQkDAZjhcyBnkSjBmMGiOBI32/UHDHzUzSj4hiM= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;VI1PR0801MB1742;7:aHfD+zXH1i3Ymgii0Yowc/K5qBNpbnZRKhOU3KpQgFm8e9W3pyqny8YwW5zr6oYiUc8RGRFWeKENU6lrcYgkuiLwHjWij3uStR0Ouk8NdDiTpj+6nCy2phuFcXdhgYjmoEO6QXG6aV7mvb3lj7gQtlj6hCsS2laF2wdsD4F3QMu7oaeXwC6y0dqNarIG9XlMi5WVlFXw/Iu3FL1UNm5U+heNZMGjViqzmsa+Tl59XcFxboMBwVJLOqJ6K8Y0k9bSZFwDIu9w7VEthShbl5YDYx2ibnTpSdkEGbdPRNe2vjKBA8Z4t6MP/LES9hHBvYhOl8Vi5G1NRDi5uAPVc37N7A==;20:02muOTbWkZWAtwDP1qa+gPPxWHPX2JyvXNRf5fq8XBIH/MAWFKycWWZnDfI8VQdWYyMepfNpE3hNSCAmrECVA6euxL3g9RHO0jEuM8O2cB5c9ohEJj1gcG1UcUtyU8ulQ7XxgVqibuh9NU3NdiV7GFMykB50Y0txhZ/zfK2up6Y= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 Mar 2017 14:21:19.8321 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0801MB1742 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5875 Lines: 189 To correctly handle 32-bit and 64-bit mmap() syscalls, we need different mmap bases to start allocation from. So, introduce mmap_legacy_base() helper and change mmap_base() to return base address according to specified task size. It'll prepare the mmap base computing code for splitting mmap_base on two bases: for 64-bit syscall and for 32-bit syscalls. Signed-off-by: Dmitry Safonov --- arch/x86/include/asm/elf.h | 24 ++++++++++--------- arch/x86/include/asm/processor.h | 4 +++- arch/x86/mm/mmap.c | 50 +++++++++++++++++++++++++--------------- 3 files changed, 48 insertions(+), 30 deletions(-) diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h index 9d49c18b5ea9..b908141cf0c4 100644 --- a/arch/x86/include/asm/elf.h +++ b/arch/x86/include/asm/elf.h @@ -293,8 +293,19 @@ do { \ } \ } while (0) +/* + * True on X86_32 or when emulating IA32 on X86_64 + */ +static inline int mmap_is_ia32(void) +{ + return IS_ENABLED(CONFIG_X86_32) || + (IS_ENABLED(CONFIG_COMPAT) && + test_thread_flag(TIF_ADDR32)); +} + #ifdef CONFIG_X86_32 +#define __STACK_RND_MASK(is32bit) (0x7ff) #define STACK_RND_MASK (0x7ff) #define ARCH_DLINFO ARCH_DLINFO_IA32 @@ -304,7 +315,8 @@ do { \ #else /* CONFIG_X86_32 */ /* 1GB for 64bit, 8MB for 32bit */ -#define STACK_RND_MASK (test_thread_flag(TIF_ADDR32) ? 0x7ff : 0x3fffff) +#define __STACK_RND_MASK(is32bit) ((is32bit) ? 0x7ff : 0x3fffff) +#define STACK_RND_MASK __STACK_RND_MASK(mmap_is_ia32()) #define ARCH_DLINFO \ do { \ @@ -348,16 +360,6 @@ extern int compat_arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp); #define compat_arch_setup_additional_pages compat_arch_setup_additional_pages -/* - * True on X86_32 or when emulating IA32 on X86_64 - */ -static inline int mmap_is_ia32(void) -{ - return IS_ENABLED(CONFIG_X86_32) || - (IS_ENABLED(CONFIG_COMPAT) && - test_thread_flag(TIF_ADDR32)); -} - /* Do not change the values. See get_align_mask() */ enum align_flags { ALIGN_VA_32 = BIT(0), diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index f385eca5407a..7caa2ac50ea2 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -797,6 +797,7 @@ static inline void spin_lock_prefetch(const void *x) /* * User space process size: 3GB (default). */ +#define IA32_PAGE_OFFSET PAGE_OFFSET #define TASK_SIZE PAGE_OFFSET #define TASK_SIZE_MAX TASK_SIZE #define STACK_TOP TASK_SIZE @@ -873,7 +874,8 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_ip, * This decides where the kernel will search for a free chunk of vm * space during mmap's. */ -#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3)) +#define __TASK_UNMAPPED_BASE(task_size) (PAGE_ALIGN(task_size / 3)) +#define TASK_UNMAPPED_BASE __TASK_UNMAPPED_BASE(TASK_SIZE) #define KSTK_EIP(task) (task_pt_regs(task)->ip) diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c index f31ed7097d0b..1e9cb945dca1 100644 --- a/arch/x86/mm/mmap.c +++ b/arch/x86/mm/mmap.c @@ -36,25 +36,23 @@ struct va_alignment __read_mostly va_align = { .flags = -1, }; -static unsigned long stack_maxrandom_size(void) +static inline unsigned long tasksize_32bit(void) +{ + return IA32_PAGE_OFFSET; +} + +static unsigned long stack_maxrandom_size(unsigned long task_size) { unsigned long max = 0; if ((current->flags & PF_RANDOMIZE) && !(current->personality & ADDR_NO_RANDOMIZE)) { - max = ((-1UL) & STACK_RND_MASK) << PAGE_SHIFT; + max = (-1UL) & __STACK_RND_MASK(task_size == tasksize_32bit()); + max <<= PAGE_SHIFT; } return max; } -/* - * Top of mmap area (just below the process stack). - * - * Leave an at least ~128 MB hole with possible stack randomization. - */ -#define MIN_GAP (128*1024*1024UL + stack_maxrandom_size()) -#define MAX_GAP (TASK_SIZE/6*5) - #ifdef CONFIG_COMPAT # define mmap32_rnd_bits mmap_rnd_compat_bits # define mmap64_rnd_bits mmap_rnd_bits @@ -63,6 +61,8 @@ static unsigned long stack_maxrandom_size(void) # define mmap64_rnd_bits mmap_rnd_bits #endif +#define SIZE_128M (128 * 1024 * 1024UL) + static int mmap_is_legacy(void) { if (current->personality & ADDR_COMPAT_LAYOUT) @@ -84,16 +84,30 @@ unsigned long arch_mmap_rnd(void) return arch_rnd(mmap_is_ia32() ? mmap32_rnd_bits : mmap64_rnd_bits); } -static unsigned long mmap_base(unsigned long rnd) +static unsigned long mmap_base(unsigned long rnd, unsigned long task_size) { unsigned long gap = rlimit(RLIMIT_STACK); + unsigned long gap_min, gap_max; + + /* + * Top of mmap area (just below the process stack). + * Leave an at least ~128 MB hole with possible stack randomization. + */ + gap_min = SIZE_128M + stack_maxrandom_size(task_size); + gap_max = (task_size / 6) * 5; - if (gap < MIN_GAP) - gap = MIN_GAP; - else if (gap > MAX_GAP) - gap = MAX_GAP; + if (gap < gap_min) + gap = gap_min; + else if (gap > gap_max) + gap = gap_max; - return PAGE_ALIGN(TASK_SIZE - gap - rnd); + return PAGE_ALIGN(task_size - gap - rnd); +} + +static unsigned long mmap_legacy_base(unsigned long rnd, + unsigned long task_size) +{ + return __TASK_UNMAPPED_BASE(task_size) + rnd; } /* @@ -107,13 +121,13 @@ void arch_pick_mmap_layout(struct mm_struct *mm) if (current->flags & PF_RANDOMIZE) random_factor = arch_mmap_rnd(); - mm->mmap_legacy_base = TASK_UNMAPPED_BASE + random_factor; + mm->mmap_legacy_base = mmap_legacy_base(random_factor, TASK_SIZE); if (mmap_is_legacy()) { mm->mmap_base = mm->mmap_legacy_base; mm->get_unmapped_area = arch_get_unmapped_area; } else { - mm->mmap_base = mmap_base(random_factor); + mm->mmap_base = mmap_base(random_factor, TASK_SIZE); mm->get_unmapped_area = arch_get_unmapped_area_topdown; } } -- 2.11.1