From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752976AbdA3MGV (ORCPT ); Mon, 30 Jan 2017 07:06:21 -0500 Received: from mail-eopbgr40112.outbound.protection.outlook.com ([40.107.4.112]:47211 "EHLO EUR03-DB5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753289AbdA3MFR (ORCPT ); Mon, 30 Jan 2017 07:05:17 -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: [PATCHv4 3/5] x86/mm: fix 32-bit mmap() for 64-bit ELF Date: Mon, 30 Jan 2017 15:04:30 +0300 Message-ID: <20170130120432.6716-4-dsafonov@virtuozzo.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170130120432.6716-1-dsafonov@virtuozzo.com> References: <20170130120432.6716-1-dsafonov@virtuozzo.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [195.214.232.6] X-ClientProxiedBy: VI1P194CA0011.EURP194.PROD.OUTLOOK.COM (10.175.178.21) To HE1PR0801MB1740.eurprd08.prod.outlook.com (10.168.150.7) X-MS-Office365-Filtering-Correlation-Id: 5eba906e-23ec-4220-b94a-08d4490833c1 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:HE1PR0801MB1740; X-Microsoft-Exchange-Diagnostics: 1;HE1PR0801MB1740;3:wwYJnzV5af9qIID9IgGKVMBnjLMXsrxzHN/HV01/KU7p04orIVsWQ8DjUiTCgDg2TdhDQo2fCTo720MPUQ8Rrx7WI2d+BCEPecpOfFUetj8GOrqCoxmUq7s5rGKClMD86ZgFu/TTmzGljVScni3tvsu21g8K2bPnFp9TnhyyQVaMHSsDW6GmliF/Z+WunZx1XtKfcdM8/rttVrervNatc7PGZ/2zhZPHz0a9tMncg4GqaZHtDplTTwUk82p41qg5ehGttahSLq62rrcu54OJPg== X-Microsoft-Exchange-Diagnostics: 1;HE1PR0801MB1740;25:eSkOQXuko514LUjDe7Hoh53/Vd8j+RPveTgQdIQxyc33uxB5WcrcZba2/LmtXpMc1TDBELTzx+85Us7FTqUbcdOVZqL43iNEJEcxz/x/frXQPdMQ8ypzDSvhbKn5QUUTDKyC8T12z6J4TGlFa+jE8lzxG+TuvUMkDaQHYeVnU0FGlslJrm6qWyjB73TEO06QCda4hz0CuQPLSudOCErA4deVlQUhVeOZ7JQy06UEWL7rkW92ObtG/Zsco8D9GPOmlOYO697AsaoM2ibqD/eRc7JSfhjNhkjhL7M6DQq2jlnYqnX+L+AfljhVX7of/u3UAXRSdDPPcy3LyUOSJunpWgG0D0QmQvM3shsIVBVcl71vB/Xa6zx6OI1ClZsMHVVLKodw/k1eo2zMogorDm1G2tnikWzJR8BGrJqYa3NFQ+RJ7OBpaBm0LWEonyVl6H10F1oa4qls01/IzvWf7zJA6hczTqETlzt4ulcm6lIhXPz88SQNu24DuRrmxPznJT8xq+EO9lraIjFgoyTcKlAtaQxmI2jbniqOm0PWg/h89avr6B0odWcdXsepUzNF/B/BnfsUtRLieGB4lvnW6EcsuphOn1eOBXyG1lJHfTg3iq/zJFuMbtXBV6Sv9rrNbROpjF3M9k0+fjUODkDrndmsZn0TPXen0GBHtovOfSV2yxPsOYMargRGedl7DXoTa7amyxw65W+0jBMltvV14gtTSA== X-Microsoft-Exchange-Diagnostics: 1;HE1PR0801MB1740;31:TRye5gA/QLQNDnh0ss7ajp78PDbml0MLWyqYzOHU2TTLsoBgBOC/+o1j8sxC67NU2BWZ8D1AKobtt2cD4q8cOzJ9AW4nsbRkbzUIBzkceWnTB586DfsKiipaiYR6uBi948LKYXBsjJO/8/yeldFK1820sPR4OlT7FGb/94NtOr966WwzwwWCpu4wdbaasHzOV6tAOL59KVw9tJudEt4equSTmAUoKuPnpOQfwKiN3Sa/6Z/ZcPdR0Yp3UKNLTXPUlk15FRgbzr2UCbh+fAAdIw==;20:mdVy7RExf/4fbABKKicVQydf+iGoV4/XUHGFQTi4TgyVJai+haxz6tYzSQuWEO89RV6rMgVihpbnWvFO4+zd2b0GVVjnTfzMtII4iC3mMG4ourmfHYeS1cC997REAd3cY0Y+Od4/6bYr6rQOBJGHO8H5wfOWy7oS55zEAQ82xXBparIi16dcnHoi7d34vOYkH2i2abhjqAGD5g5KOCJEdsEgn6WvwCFX4/zz+g/JUS/hmgnLmtq0d/xLdCRoFdfM X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(278428928389397); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040375)(601004)(2401047)(5005006)(8121501046)(10201501046)(3002001)(6041248)(20161123564025)(20161123555025)(20161123562025)(20161123560025)(20161123558021)(6072148);SRVR:HE1PR0801MB1740;BCL:0;PCL:0;RULEID:;SRVR:HE1PR0801MB1740; X-Microsoft-Exchange-Diagnostics: 1;HE1PR0801MB1740;4:QayM6j66SuUhv/Ze0Fi1jcB+BeLdZX9WsAEJMgZUM3kKS7Dz/I2twEsEgTmPdkJA7IeDTATBbfZjvKh+2awIMoplJUGhqIYe70hzDQC4mpxhNm5ogMGldD6Slo3Wne/HOnjqGeNR6YuuITWSfGtHknuUCSGmBdT2Vx5WvdFJkiCEfT0jim1Xt9vYqd8QmXAZaSu6Gn2RvGlLX5ppcV1DVnZ22xaluI4WUgIV0sMkiRGuvDMXoWdpCtBqj6J3jk2uGGp1T/8FHa0u3J0rtMwv3frZR+JFUSlKsztpKczTRUnB50U1ZXZ/uaEFvREW2mHPDFNp+mC80kpy/eWd3OH+2GkSniSjr32L99pH8fiZqI6tLvLqZHc6K0NsEOV2Hb6EjJe+tKl+XYdrFkM9wKEtNsImy+vrVc1Dkr8v/qRspAIvdmz6/D1Y2Pb7BrpiKa1DRebNNPIeDcQs6dbzsuUN4NfYZkCRPB2cmkgyR50RiAAJXftT7vSg8PcBaZm/PeYh8iyncX/zPt76HKwtSxqA4uu+tjJXYd/QkY0ExZnKjxuAtanTKk6Ns4UutDeXXedltZ8DBdTTyFr+KUUb3sydyYIiYRoiRrPt1oVahsVgG5qtkSVIHcdZ/r9NZ9XECaJBMRP3o5C59AOcKYGhyebFwg== X-Forefront-PRVS: 0203C93D51 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(4630300001)(6009001)(7916002)(39450400003)(199003)(189002)(7736002)(92566002)(189998001)(110136003)(53936002)(33646002)(4326007)(39060400001)(1076002)(53416004)(38730400001)(68736007)(97736004)(5003940100001)(6486002)(8676002)(305945005)(2906002)(6666003)(105586002)(50466002)(6506006)(6916009)(2950100002)(48376002)(106356001)(69596002)(86362001)(50986999)(47776003)(54906002)(6512007)(36756003)(76176999)(66066001)(2351001)(42186005)(81166006)(3846002)(6116002)(81156014)(25786008)(50226002)(101416001)(5660300001);DIR:OUT;SFP:1102;SCL:1;SRVR:HE1PR0801MB1740;H:dsafonov.sw.ru;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;HE1PR0801MB1740;23:Zb1GT8OcaXb3lFSQ3aSJm7T5T8xW0G48rBBHQzn?= =?us-ascii?Q?o5VAQ4Fcms7b2nwFa0COmsU4fdBIh2MCU32f7e9uHBqPx8R14Tvyq9KE1ore?= =?us-ascii?Q?DXBxOT6u/BjfkfyY9kay2fff7JJISGAukUs3siz9tEctfvQJgri5RqgxS9LG?= =?us-ascii?Q?RQpofqgrd/IElENdrY962hNpeJlcEyaOgqsO2jipugWPDb4r/JW6e9f4c2Kd?= =?us-ascii?Q?EdCyUldd/BzpKtBFexaUJqJ77rt1YU47hRgpnFM7dr3VcTIzehnGyM8h3FBp?= =?us-ascii?Q?f8lSySfbtpYOSnefcK2n2YVbqr4Xv9ir7ZGOWBqFB7TCWblbHI7U0zfax6Xw?= =?us-ascii?Q?mTLxLUcSoAaNAjhRA+CjhErhRwEbUskMnNdPD52H11XgvZN6E8PcY2piRnWy?= =?us-ascii?Q?5iR6heebSy3pW2cTHsOySaViH+eg4xPg8re057LIROvI46s9zFV/piIu7cMY?= =?us-ascii?Q?NnxHkun3U2UfW3D+BZQZ2zYmy9TvXBTsdJHB0ARIMTC4I2cjgPkRkOes7WyK?= =?us-ascii?Q?iRZahs3/E6ObdqsZB5HpTv0WHyVz3aAwHKZ/2ELbCpVQfo24qwc9+Auxx6P+?= =?us-ascii?Q?9X6McNN2VaGID9iX3pPeNFu6JH1NSIepaBAeKqQ7k89NE4M3B547x5pBIozl?= =?us-ascii?Q?AmXkmqIl0ogk6FGa3p+lWa5j4j/n0upVEKokEjhvZu+0qzFS68u1LdOpLqDy?= =?us-ascii?Q?lijnsFvGq+/yvqNt6hoMz0GA9bCsM8jRMiGPJUznIxndEUKIQEjpEfU8szGD?= =?us-ascii?Q?yBc0NXypqrqah9NqsApWmP8hQMR7xGgirPnUsH+xfEQKzNB2zpLw6wZifEWe?= =?us-ascii?Q?czRn7aHqyPzoniDrRQaZSdtZIcjhZeno9Yayvv4C9gEISaDTaOqWfcELqz9j?= =?us-ascii?Q?VoDB2k6IIsO047Ep3jIZExyE7SPpAlqyayX4ivPiaQfqqSnjyf9aUJDS2fwm?= =?us-ascii?Q?bWo/xeieaGipI3ETJ3x2C3fGhBdpjtFKbssBk5g1GjVE9e/JGauewRXBoolb?= =?us-ascii?Q?OhgqXkrtouOMpfs8nSgjq5uHzxwMjBj70WXekD+SFrhNRsfI/vicU0y5m2KT?= =?us-ascii?Q?RhsK/8auD+JjKBNdl7p/n151kONHOAVkMyolDwhSsOKVKkOSQNHtKrvRLqz+?= =?us-ascii?Q?6MbdKxjMBRIs84+Tqhu+k8JswbEgH+4AukYFltEIjhw0EKVnlnIvfa9rzfaD?= =?us-ascii?Q?A2WpCRcOkctl2O+aD0+8i9MjZxVYF9hbuX2wPqMwwt4VygcSwDPCy/9QfCA?= =?us-ascii?Q?=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1;HE1PR0801MB1740;6:gws3KJnNnSDbzhpWUQVeB14n6jclQdn7akXaMS8qk901LilkhTf3YuifF3utbSMvQZaU9C3zm2Bfu2OVB8SX5dqZuCONWn6anqbYqFQq83keqZ2kNieatEmMGwSSK5JOTZ6mSCh6VL1HpahaHocixya4YnS1uElw/w9PPTUkWwGgjFqML7uNDoCLY2BwkgbhKyra94aMOYlAv8pEJ2ru1sgLfeFOsL7rnQvkSD1b2KSf1U3QFGw59qxXnw4Hz3ay9ni0ErxQ2PoAXQKUUKqosw4/QIxKIyAp6sw0Xy/ewXGTiwTAZwMo4sNT/TIWoUagaE8jc0sMb6Eg72o5aesuNgTvRjn0mOzHHtqliFLgN+TaOEm0wb+SsUV4/iLA+KFhs7UzNCgeexA5Ofr8117ZT6J1PCpi36nJC1a04tEI4ok=;5:F/Pm0xRCMLtehdHzgDwStiUT49O9R/f0w5tF3KD7hId/Z7z58byENsLi4s2cl2dF2tDG4U5zKDHwOPKdpsEE29p5XN4dEI5oFz6+6A6ZK+6uMkRvdcMcTerqO6FFsfvqVCWK5OQebcojjatYKjQP/OQRrCrQ9NUymSk9pJBFORc=;24:IXRG+zN/aekMm5kHcsZSNr7IBZLFDD0EWJB4Kenob17XPmNcchJ5/bzqjwZWQcjJpA6+/u3r7h3w0vLVwT8fKxCgzpYOdztKJYTvMGRuS9Q= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;HE1PR0801MB1740;7:EVQ0o/AbtYHGvbQYbIIeR+EnPSOuC2oyt/qyCS5hQanAjbIofZRdrNqejNUIGFRfFa6A/225VdZq+TpbP7XhkLw5g8V75h5qUP7M83TeG4icIXfTPSZ0r/oUR6GV8RtBkEBXHTNQ0ve6pKEZUdjk9VnSDXUwM47utQXnt1WXjtRquhR+LccFngtwRYV54v+me2hY0fPCzNY1ceezLYBJ9ZmHnZHCf3dVxl1uUjDBTGn0y9dqkWbmHbMYK9OpWoZdSnIkJC8RTX8F4vnsNCKs8EQz10G93KV0PtIycqZzTnuLeLLPnpszPRJI0UxhWHsnxGeNTUmS7nxkmTetc2h3641Iq8ugpLW1K42kF9kgeuQdJvuu0E11imBvr57gPYZVIHcHRJdzfqY6j1VERzgEEu8vgC1x5qpvNML/32W0PqFoMUho+L4QhnroinySG4lmYoNbMW2DBsFWg357svH57w==;20:8aLaWllkLTmvD/lXirb5rKuuetcfAEGGmalQLHoWG1ZfsKEGrEuTAUzW78PrYFBJFQv11tBoyc5at8J4Cd3rgyy/1DChcWJzswNbnvb3AMbYHJkWkFpHgZf/9gktRH+GL76hdLQqVkr43ORaY7KK2L37zbsbiHYj/im6auurQEo= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Jan 2017 12:04:53.1382 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: HE1PR0801MB1740 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Fix 32-bit compat_sys_mmap() mapping VMA over 4Gb in 64-bit binaries and 64-bit sys_mmap() mapping VMA only under 4Gb in 32-bit binaries. Introduced new bases for compat syscalls in mm_struct: mmap_compat_base and mmap_compat_legacy_base for top-down and bottom-up allocations accordingly. Taught arch_get_unmapped_area{,_topdown}() to use the new mmap_bases in compat syscalls for high/low limits in vm_unmapped_area(). I discovered that bug on ZDTM tests for compat 32-bit C/R. Working compat sys_mmap() in 64-bit binaries is really needed for that purpose, as 32-bit applications are restored from 64-bit CRIU binary. Signed-off-by: Dmitry Safonov --- arch/Kconfig | 7 +++++++ arch/x86/Kconfig | 1 + arch/x86/kernel/sys_x86_64.c | 28 ++++++++++++++++++++++++---- arch/x86/mm/mmap.c | 36 ++++++++++++++++++++++++------------ include/linux/mm_types.h | 5 +++++ 5 files changed, 61 insertions(+), 16 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 99839c23d453..6bdca6d86855 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -671,6 +671,13 @@ config ARCH_MMAP_RND_COMPAT_BITS This value can be changed after boot using the /proc/sys/vm/mmap_rnd_compat_bits tunable +config HAVE_ARCH_COMPAT_MMAP_BASES + bool + help + If this is set, one program can do native and compatible syscall + mmap() on architecture. Thus kernel has different bases to + compute high and low virtual address limits for allocation. + config HAVE_COPY_THREAD_TLS bool help diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index e487493bbd47..b3acb836567a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -102,6 +102,7 @@ config X86 select HAVE_ARCH_KMEMCHECK select HAVE_ARCH_MMAP_RND_BITS if MMU select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT + select HAVE_ARCH_COMPAT_MMAP_BASES if MMU && COMPAT select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRANSPARENT_HUGEPAGE diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c index a55ed63b9f91..90be0839441d 100644 --- a/arch/x86/kernel/sys_x86_64.c +++ b/arch/x86/kernel/sys_x86_64.c @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -113,10 +114,19 @@ static void find_start_end(unsigned long flags, unsigned long *begin, if (current->flags & PF_RANDOMIZE) { *begin = randomize_page(*begin, 0x02000000); } - } else { - *begin = current->mm->mmap_legacy_base; - *end = TASK_SIZE; + return; } + +#ifdef CONFIG_COMPAT + if (in_compat_syscall()) { + *begin = current->mm->mmap_compat_legacy_base; + *end = IA32_PAGE_OFFSET; + return; + } +#endif + + *begin = current->mm->mmap_legacy_base; + *end = TASK_SIZE_MAX; } unsigned long @@ -157,6 +167,16 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, return vm_unmapped_area(&info); } +static unsigned long find_top(void) +{ +#ifdef CONFIG_COMPAT + if (in_compat_syscall()) + return current->mm->mmap_compat_base; + else +#endif + return current->mm->mmap_base; +} + unsigned long arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, const unsigned long len, const unsigned long pgoff, @@ -190,7 +210,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, info.flags = VM_UNMAPPED_AREA_TOPDOWN; info.length = len; info.low_limit = PAGE_SIZE; - info.high_limit = mm->mmap_base; + info.high_limit = find_top(); info.align_mask = 0; info.align_offset = pgoff << PAGE_SHIFT; if (filp) { diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c index 98be520fd270..99e6a81d9c87 100644 --- a/arch/x86/mm/mmap.c +++ b/arch/x86/mm/mmap.c @@ -70,6 +70,8 @@ static int mmap_is_legacy(void) #ifdef CONFIG_COMPAT static unsigned long arch_compat_rnd(void) { + if (!(current->flags & PF_RANDOMIZE)) + return 0; return (get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1)) << PAGE_SHIFT; } @@ -77,6 +79,8 @@ static unsigned long arch_compat_rnd(void) static unsigned long arch_native_rnd(void) { + if (!(current->flags & PF_RANDOMIZE)) + return 0; return (get_random_long() & ((1UL << mmap_rnd_bits) - 1)) << PAGE_SHIFT; } @@ -112,22 +116,30 @@ static unsigned long mmap_legacy_base(unsigned long rnd, * This function, called very early during the creation of a new * process VM image, sets up which VM layout function to use: */ -void arch_pick_mmap_layout(struct mm_struct *mm) +static void arch_pick_mmap_base(unsigned long *base, unsigned long *legacy_base, + unsigned long random_factor, unsigned long task_size) { - unsigned long random_factor = 0UL; - - if (current->flags & PF_RANDOMIZE) - random_factor = arch_mmap_rnd(); - - mm->mmap_legacy_base = mmap_legacy_base(random_factor, TASK_SIZE); + *legacy_base = mmap_legacy_base(random_factor, task_size); + if (mmap_is_legacy()) + *base = *legacy_base; + else + *base = mmap_base(random_factor, task_size); +} - if (mmap_is_legacy()) { - mm->mmap_base = mm->mmap_legacy_base; +void arch_pick_mmap_layout(struct mm_struct *mm) +{ + if (mmap_is_legacy()) mm->get_unmapped_area = arch_get_unmapped_area; - } else { - mm->mmap_base = mmap_base(random_factor, TASK_SIZE); + else mm->get_unmapped_area = arch_get_unmapped_area_topdown; - } + + arch_pick_mmap_base(&mm->mmap_base, &mm->mmap_legacy_base, + arch_native_rnd(), TASK_SIZE_MAX); + +#ifdef CONFIG_COMPAT + arch_pick_mmap_base(&mm->mmap_compat_base, &mm->mmap_compat_legacy_base, + arch_compat_rnd(), IA32_PAGE_OFFSET); +#endif } const char *arch_vma_name(struct vm_area_struct *vma) diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 808751d7b737..48274a84cebe 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -404,6 +404,11 @@ struct mm_struct { #endif unsigned long mmap_base; /* base of mmap area */ unsigned long mmap_legacy_base; /* base of mmap area in bottom-up allocations */ +#ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES + /* Base adresses for compatible mmap() */ + unsigned long mmap_compat_base; + unsigned long mmap_compat_legacy_base; +#endif unsigned long task_size; /* size of task vm space */ unsigned long highest_vm_end; /* highest vma end address */ pgd_t * pgd; -- 2.11.0 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ot0-f197.google.com (mail-ot0-f197.google.com [74.125.82.197]) by kanga.kvack.org (Postfix) with ESMTP id 434036B0266 for ; Mon, 30 Jan 2017 07:04:58 -0500 (EST) Received: by mail-ot0-f197.google.com with SMTP id 36so125091441otx.0 for ; Mon, 30 Jan 2017 04:04:58 -0800 (PST) Received: from EUR03-DB5-obe.outbound.protection.outlook.com (mail-eopbgr40119.outbound.protection.outlook.com. [40.107.4.119]) by mx.google.com with ESMTPS id r20si5336833oie.95.2017.01.30.04.04.56 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 30 Jan 2017 04:04:57 -0800 (PST) From: Dmitry Safonov Subject: [PATCHv4 3/5] x86/mm: fix 32-bit mmap() for 64-bit ELF Date: Mon, 30 Jan 2017 15:04:30 +0300 Message-ID: <20170130120432.6716-4-dsafonov@virtuozzo.com> In-Reply-To: <20170130120432.6716-1-dsafonov@virtuozzo.com> References: <20170130120432.6716-1-dsafonov@virtuozzo.com> MIME-Version: 1.0 Content-Type: text/plain Sender: owner-linux-mm@kvack.org List-ID: To: linux-kernel@vger.kernel.org Cc: 0x7f454c46@gmail.com, Dmitry Safonov , Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , Andy Lutomirski , Borislav Petkov , x86@kernel.org, linux-mm@kvack.org Fix 32-bit compat_sys_mmap() mapping VMA over 4Gb in 64-bit binaries and 64-bit sys_mmap() mapping VMA only under 4Gb in 32-bit binaries. Introduced new bases for compat syscalls in mm_struct: mmap_compat_base and mmap_compat_legacy_base for top-down and bottom-up allocations accordingly. Taught arch_get_unmapped_area{,_topdown}() to use the new mmap_bases in compat syscalls for high/low limits in vm_unmapped_area(). I discovered that bug on ZDTM tests for compat 32-bit C/R. Working compat sys_mmap() in 64-bit binaries is really needed for that purpose, as 32-bit applications are restored from 64-bit CRIU binary. Signed-off-by: Dmitry Safonov --- arch/Kconfig | 7 +++++++ arch/x86/Kconfig | 1 + arch/x86/kernel/sys_x86_64.c | 28 ++++++++++++++++++++++++---- arch/x86/mm/mmap.c | 36 ++++++++++++++++++++++++------------ include/linux/mm_types.h | 5 +++++ 5 files changed, 61 insertions(+), 16 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 99839c23d453..6bdca6d86855 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -671,6 +671,13 @@ config ARCH_MMAP_RND_COMPAT_BITS This value can be changed after boot using the /proc/sys/vm/mmap_rnd_compat_bits tunable +config HAVE_ARCH_COMPAT_MMAP_BASES + bool + help + If this is set, one program can do native and compatible syscall + mmap() on architecture. Thus kernel has different bases to + compute high and low virtual address limits for allocation. + config HAVE_COPY_THREAD_TLS bool help diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index e487493bbd47..b3acb836567a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -102,6 +102,7 @@ config X86 select HAVE_ARCH_KMEMCHECK select HAVE_ARCH_MMAP_RND_BITS if MMU select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT + select HAVE_ARCH_COMPAT_MMAP_BASES if MMU && COMPAT select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRANSPARENT_HUGEPAGE diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c index a55ed63b9f91..90be0839441d 100644 --- a/arch/x86/kernel/sys_x86_64.c +++ b/arch/x86/kernel/sys_x86_64.c @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -113,10 +114,19 @@ static void find_start_end(unsigned long flags, unsigned long *begin, if (current->flags & PF_RANDOMIZE) { *begin = randomize_page(*begin, 0x02000000); } - } else { - *begin = current->mm->mmap_legacy_base; - *end = TASK_SIZE; + return; } + +#ifdef CONFIG_COMPAT + if (in_compat_syscall()) { + *begin = current->mm->mmap_compat_legacy_base; + *end = IA32_PAGE_OFFSET; + return; + } +#endif + + *begin = current->mm->mmap_legacy_base; + *end = TASK_SIZE_MAX; } unsigned long @@ -157,6 +167,16 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, return vm_unmapped_area(&info); } +static unsigned long find_top(void) +{ +#ifdef CONFIG_COMPAT + if (in_compat_syscall()) + return current->mm->mmap_compat_base; + else +#endif + return current->mm->mmap_base; +} + unsigned long arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, const unsigned long len, const unsigned long pgoff, @@ -190,7 +210,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, info.flags = VM_UNMAPPED_AREA_TOPDOWN; info.length = len; info.low_limit = PAGE_SIZE; - info.high_limit = mm->mmap_base; + info.high_limit = find_top(); info.align_mask = 0; info.align_offset = pgoff << PAGE_SHIFT; if (filp) { diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c index 98be520fd270..99e6a81d9c87 100644 --- a/arch/x86/mm/mmap.c +++ b/arch/x86/mm/mmap.c @@ -70,6 +70,8 @@ static int mmap_is_legacy(void) #ifdef CONFIG_COMPAT static unsigned long arch_compat_rnd(void) { + if (!(current->flags & PF_RANDOMIZE)) + return 0; return (get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1)) << PAGE_SHIFT; } @@ -77,6 +79,8 @@ static unsigned long arch_compat_rnd(void) static unsigned long arch_native_rnd(void) { + if (!(current->flags & PF_RANDOMIZE)) + return 0; return (get_random_long() & ((1UL << mmap_rnd_bits) - 1)) << PAGE_SHIFT; } @@ -112,22 +116,30 @@ static unsigned long mmap_legacy_base(unsigned long rnd, * This function, called very early during the creation of a new * process VM image, sets up which VM layout function to use: */ -void arch_pick_mmap_layout(struct mm_struct *mm) +static void arch_pick_mmap_base(unsigned long *base, unsigned long *legacy_base, + unsigned long random_factor, unsigned long task_size) { - unsigned long random_factor = 0UL; - - if (current->flags & PF_RANDOMIZE) - random_factor = arch_mmap_rnd(); - - mm->mmap_legacy_base = mmap_legacy_base(random_factor, TASK_SIZE); + *legacy_base = mmap_legacy_base(random_factor, task_size); + if (mmap_is_legacy()) + *base = *legacy_base; + else + *base = mmap_base(random_factor, task_size); +} - if (mmap_is_legacy()) { - mm->mmap_base = mm->mmap_legacy_base; +void arch_pick_mmap_layout(struct mm_struct *mm) +{ + if (mmap_is_legacy()) mm->get_unmapped_area = arch_get_unmapped_area; - } else { - mm->mmap_base = mmap_base(random_factor, TASK_SIZE); + else mm->get_unmapped_area = arch_get_unmapped_area_topdown; - } + + arch_pick_mmap_base(&mm->mmap_base, &mm->mmap_legacy_base, + arch_native_rnd(), TASK_SIZE_MAX); + +#ifdef CONFIG_COMPAT + arch_pick_mmap_base(&mm->mmap_compat_base, &mm->mmap_compat_legacy_base, + arch_compat_rnd(), IA32_PAGE_OFFSET); +#endif } const char *arch_vma_name(struct vm_area_struct *vma) diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 808751d7b737..48274a84cebe 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -404,6 +404,11 @@ struct mm_struct { #endif unsigned long mmap_base; /* base of mmap area */ unsigned long mmap_legacy_base; /* base of mmap area in bottom-up allocations */ +#ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES + /* Base adresses for compatible mmap() */ + unsigned long mmap_compat_base; + unsigned long mmap_compat_legacy_base; +#endif unsigned long task_size; /* size of task vm space */ unsigned long highest_vm_end; /* highest vma end address */ pgd_t * pgd; -- 2.11.0 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org