Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932855AbdCaLP0 (ORCPT ); Fri, 31 Mar 2017 07:15:26 -0400 Received: from mail-he1eur01on0105.outbound.protection.outlook.com ([104.47.0.105]:11542 "EHLO EUR01-HE1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S932522AbdCaLPY (ORCPT ); Fri, 31 Mar 2017 07:15:24 -0400 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 , Adam Borowski , "H. Peter Anvin" , Thomas Gleixner , , Andrei Vagin , Cyrill Gorcunov , Borislav Petkov , "Kirill A. Shutemov" , , Andy Lutomirski , Ingo Molnar Subject: [PATCHv5] x86/mm: make in_compat_syscall() work during exec Date: Fri, 31 Mar 2017 14:11:37 +0300 Message-ID: <20170331111137.28170-1-dsafonov@virtuozzo.com> X-Mailer: git-send-email 2.12.0 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [195.214.232.6] X-ClientProxiedBy: DB6PR1001CA0038.EURPRD10.PROD.OUTLOOK.COM (10.168.69.152) To HE1PR0801MB1740.eurprd08.prod.outlook.com (10.168.150.7) X-MS-Office365-Filtering-Correlation-Id: f311d635-7d45-42c7-9aeb-08d47827375d X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(201703131423075)(201703031133081);SRVR:HE1PR0801MB1740; X-Microsoft-Exchange-Diagnostics: 1;HE1PR0801MB1740;3:ua+axaauYEZI5B05h+JkaOssjuUafcpIZ5zxnNhQQlQP2eDJJJJxq1EgDPOo2k25qc9P7OXOWbN9wkRwiAdYdixlL5Z+WeVwzEGvRGC7n3W7rb2k4Zo1f/XiY3X8tu1y5ufqKudSAl4m6XPTV4EtrZyjFbFKR9xoYRyLQJGhMZE1/m4XQHvmR8rZwtrFj9V6yXG1E1bNYUwwEkZZMT9SXfDfNOXiDmQque4uDGIX/mcS6JF86qn2r1m3IAz6nGXC6r5aiioZ2UdIpGSFA9K+g8jWil1BJfvwiC/rotepkmKfgwiPzTDmYQKMQROUuG/iSuxC+WqXBH9BZ5Tm6eOKrA==;25:BOmHSVKEGkb8N+MtJVUdzjIim4mpusmtBYCCMqBrHt77C/z3m0GAAwflH5Va0JpyrHkMyMRGrhRrC3i7xjW8KCRt8aNg+p6RCXxlDEB7mBtMT9W+Mb4m+x/oTxzw21a2eyoiMbz1rfYzx1XHX6GP4wtCFBCqnvLpeTH7NChhT3PxhghIaEkvr4iW/u4RpQJVSCm4EGMGt8jtBW5Cah54kLC1hPsU9DGDyc6BUHhLAfwGAgYHpqh0sY13lCTP1q9G1rO5Ll4D9nE8QI31hojL1UGuw1Al56RKxcg9SkVdcBaz+ANnoR/5eJpGl3mo/ncfMsC43FIzS7LHgD3g/iMKESVhj+4ZBZHYer6qBk/+imx+FLH9zbImY5S4jbql498YoR4V1UT18jFb1Nfw7ub3ZksZwGnMfX2QUuEj6S5Y2ysZ+y5dqJmt8TxOlOEWQ4zEh4BPp0qJbtQKIwWuszA5tg== X-Microsoft-Exchange-Diagnostics: 1;HE1PR0801MB1740;31:nn3czU9+/f3UMZWvFYx7eh0ZYNtu3PSabZHHPD7SM9VMzIDvtjKlp5gZEgzhzp0f9DeQyMYFbqXWqnhzlOY/IFuFLfZS/wZzU85OgK2oiJ4ayTWnMcdygRkYMKtDsPtSjYcgjE1sZBhTg2rXzt8lWWk2srOdZ6nNfThgmm989cM6jS6tuUGsncndEUuxan6q/vWr2xH6l0qHE2HOciA2uYsGVkSKs+0lUVdp8AJl62o=;20:49Bl31TChFyyu+5CLubcv0kORvBttcYc4iLVoqff+xGvofqYsy7IqV+rfHFBnT9MIaHQIZWJmBIw1mAWXd5i+rvH2aMfoFXXxuV70uRJ+wxOKWKGutYHjKj2BELZaJxUtTTdk1Io3DuNkEYOKzuSaAz1JWTO1O8XGnDj3IkYN7l6pU/oDTsufhlpywDDvLJC6W9gXRdbEE4GxXGLW7iwMFpgQJOCIeNBMtxYFBBlUOrcHfK7dCLtalAvUvlZoGfmxlczYBqdHS64VskEyXferI39b7hWR4gD7gReRxbqrJuA1/kD3GQ5jYrh00Pf5jawbdCmJhdiz1wkDfG+rrXpCwu9hAZHsil1jZ8vCed5bix6siNNVi7VImAoToctzF9hIx2rzrP9EIDxU4pIb2ZEs6y0htQBXFspztQb2kHBhgE= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(228905959029699); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040450)(601004)(2401047)(8121501046)(5005006)(10201501046)(93006095)(93001095)(3002001)(6041248)(20161123560025)(20161123564025)(20161123555025)(201703131423075)(201702281528075)(201703061421075)(20161123562025)(6072148);SRVR:HE1PR0801MB1740;BCL:0;PCL:0;RULEID:;SRVR:HE1PR0801MB1740; X-Microsoft-Exchange-Diagnostics: 1;HE1PR0801MB1740;4:5InGUHrF6z8ggeiTfgkFerabkTNYvDL6BvarZyEc0llwTRfNOD8VL7kdBx1kcD4xMQ9DLXe4vHNMuDcqiMmttlopRDA0FIiO+hb+n15u8aJXW3Hunt7cqc5jzn3rq1u4Z4YFCv37wRE4+f4ABwx/zWrKlrO095bbIeOhwTDXgNRm2229EAL/nbFs1k7jwd165EIQjXfjuTJfFVE4bSt6WwivCdbfHkPcMXtWKqIRfwsW1GoJoKijwFqHsLOPgV3pzdiSoOviX84csTOpGDZEkyNDnOD0jS6ueY7DMNnhShj7SkgijzjOeot2i02Be3mTvlULc6kT9Gr37nA4h7bJjirMRVe+6um7KP0/tgBcQO1LzG+gt1PgKxDtHU1Y8f/TPmook8gXkKREyTvSynDNTDLiRM6r4/UshquDe7RHjRtKwIiegpkquZtz4LomlCTRwTdGZ4Swif8eX1fTBZTesjZRy28No+3APWeCFXxB6oge/eFtMlf0UEme280p9z6wcug50qVhyUOKWmBFvE2NgufNS3lCy8iC4Uzo713Q5wK9tVtw433Xd4HRj+dAE3Z38ZpGaLSMrlg32yivqTLFGnBjD8p2mlR/7RqvRYsSHWlFBgnYiV7D0mHbFAEFPP/Xxk3qyF6jC6OcmN8TCzaEnhJ2DmXtgNly3fNFVk8RGosUJivJNKErrsPpFqLj+v+Iv8d1+2A3m2hZm0TnTiwryoouGUbMBrX6NrHLgj4wxlOJyT5CUHEmZJyHpWQtx83UlryOkBGs9BSN1+eE0rFNWA== X-Forefront-PRVS: 02638D901B X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(4630300001)(6009001)(39410400002)(39400400002)(39450400003)(39830400002)(48376002)(6506006)(53416004)(110136004)(4326008)(38730400002)(2906002)(6486002)(6916009)(1076002)(189998001)(3846002)(6116002)(54906002)(36756003)(6666003)(2351001)(42186005)(25786009)(33646002)(6512007)(5660300001)(7736002)(305945005)(53936002)(86362001)(50226002)(8676002)(81166006)(5003940100001)(50986999)(66066001)(7416002)(47776003);DIR:OUT;SFP:1102;SCL:1;SRVR:HE1PR0801MB1740;H:dsafonov.sw.ru;FPR:;SPF:None;MLV:sfv;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;HE1PR0801MB1740;23:cAtcdpfnGCl34QyugIHP/g0QdXgbNmUBHxD0MQB?= =?us-ascii?Q?BiS5a7yS0xYXwy33U+1APVnNYatBhww3XM2G+wsqaue95P2Xq8sqa7/9anNC?= =?us-ascii?Q?XTON96e6POYjg3azlMil+Cb2xJmhc482INj34jVIizpfNB/yjP0kanYZ67vQ?= =?us-ascii?Q?Na3qHqWKz2X3ORkeIZpqFmkMxnoVI6DbfasS1WGg1OCG1B130CHRjbzEMswF?= =?us-ascii?Q?LlKO2yNGnfApGY42S9nVjdG8zzeuRJYuUQx4U8UjwNHvvd0Ab9i9wOLm3GM/?= =?us-ascii?Q?Bydod/f+zAPZeIVnA9FRSxfyZgTxNc3KP04UYigBQYcKrj5pBV4KRf27rmkA?= =?us-ascii?Q?MIfJJ7ksN802ZVbleDgGOK3M1eQ7D21xIW6QH1hBTW84JTTBbRBKqufcE46I?= =?us-ascii?Q?ehNjm1ZW17KrgcPK7W8C6p22beV3URxrbg83YXiZ0e3QmgQC+C7uj9OPbCfQ?= =?us-ascii?Q?QEle8TO4u2V97KL1o43pwS1I8fMTSQCJHw8+kTsHY+sYISWEnWfqS1VMMslI?= =?us-ascii?Q?uDwAbFL8+kNLdc+VJCMOa8Gd/HG38fijRl2ssoy5fn0JnrtV0yYwqmADKf2y?= =?us-ascii?Q?qf8z+FXkh67wwli7i/+DqT5nrAvYp0uPbYEqLfE/UDpTTHwgcxfQIkbei+i2?= =?us-ascii?Q?kuQBTph+AJRQuIjvG5Nk0QFK6Rh0W0PLGTiaArJ4ZEY+agwMTRMcPaCbIFeB?= =?us-ascii?Q?9HSkbgI2VCNLBiSWuk/yMc4hPDdzPT/IYh+8HnXFVtfpWVyizvmEaLd3yofT?= =?us-ascii?Q?Q3zC96AU8pWLDj1cJntBUh4dupCmFQsYtduAeH6Lk/NING0pYTFcA+uGxRiK?= =?us-ascii?Q?Mt0rv8hNusHyFul2sK85andKROj0ljYNjY9eYz/iV9Oe/9mRMogBtP52WgaV?= =?us-ascii?Q?CtOkNRajrrspii0tZtKUbs/dDzKz2V9CBJiTZD+6NbzQmRiBOtSRc0E4LAEx?= =?us-ascii?Q?qFyKAzMQaQ7gpUWlmglNQI+cKBzBV0tce+jRv3QNp70nv3wzR4LsVAnKm8Xg?= =?us-ascii?Q?WxEmIrkrcxTIHPGJfWKmRVx+w?= X-Microsoft-Exchange-Diagnostics: 1;HE1PR0801MB1740;6:UbMP/J7eeJY+B+XjSFdZDT0FNo8xbN3Mbmv+gOpj8Ozpf9dJmvhxZ9JHuohplFJIjkaBkmhbrsICro9G4gQwAjgfmFvRF8ou4LFD22Et6t5PNLY69VgIrqOoUINtqWdJcDr1GTYJxla8esz7vWGm3DdL81pCf77TTq+vJcTUZ1uSTxt0p6CV77fgZzPIN33Mk2vHx+Mfl4j9MBoK5pxNPYZcygydWyojHWInV2sEaEjL3Lujo+m0S3NUuirxUc2KCn/bK/eitAn3QD6wKIJbtHH4AO+bSi4C6d81f7/BYRsXwpIvCg7k0AabQ2qV5ZdZccFDSWRmdn+HefY/WoVABO41Y6GDJJ35ekaYvzLR7Qtvo5uMXHgk1h355v1WddZ5oxirgpm+dXjPnMNgcGT0Vw==;5:Jhp+huursacaBOfWDLxAarPJQ3SWf/CCyoeW4OeUiwVOi9Xo0nUaBZ+XFpt6pG1QBA8Z/pB8e/SSwnnJgRaqgilS62UaRZz7pDrStT+EGzCwzrPbzDTfeVj39q0CHD0bopFgobHiTPgTNHu1yJKVSA==;24:NB2/0yMCu29guOGJ7PNebDyt/4KkJDRjLhpF836iWntGWmIWEHxKdFXLawFmA7AXxstpVS9oN1EKZADkjJSYRO7uHLLzXl92BlcmeczlP90= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;HE1PR0801MB1740;7:C1eN098d1x7JPZfJoT33xY82ZOrWuK7a4d8xlMuJ8KyDD5qrDnqgOyuLHoZaCCKHKWFsT+Wu+Vsooo7BJ0fJRRyrnL6Ht3u0bIKYBPCx/KxMh86as6ESkfopMlLh6mVfAKdZSvHn2gHHpuvPzho1858bGdn+bR2uWO3v2+tRr+skbipMBk6HeHuCA/6bbuUQMcy/EA0eleZgVPDBUoqzRHJnt/5AIfPSiNmJ2tyv9wbUEv90I+siX5FR54Ic1HRJYVz1EcMrzseMtTBxUVKqpac9I4BlodnEaqJ8lBRx93ZCOfmJD3sBlaRO+uUyn1d9VbaCBgE/HTDWCVDaQqzaMA==;20:Ov/EQmGi+kUidvfgSKTyrdg6fGERFGERPTjrrSrHynq8J+cgGTmIi6XEUF5VfLlcPllbv420xL0T8gMRB0ZbukqQnekWTRhIUbi/QXm4j2Xu0QQoo7NU/JQIwLZkake+gbW7yURvMEY1+a0CuNu0X1uwcEE5z3zhb6v3uXHzDww= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 31 Mar 2017 11:15:17.6396 (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 Content-Length: 5027 Lines: 148 After my changes to mmap(), its code now relies on the bitness of performing syscall. According to that, it chooses the base of allocation: mmap_base for 64-bit mmap() and mmap_compat_base for 32-bit syscall. It was done by: commit 1b028f784e8c ("x86/mm: Introduce mmap_compat_base() for 32-bit mmap()"). The code afterwards relies on in_compat_syscall() returning true for 32-bit syscalls. It's usually so while we're in context of application that does 32-bit syscalls. But during exec() it is not valid for x32 ELF. The reason is that the application hasn't yet done any syscall, so x32 bit has not being set. But do_execve() calls load_elf_binary(), which adds mappings with elf_map(). That results in -ENOMEM for x32 ELF binaries as in_compat_syscall() says we're in 64-bit syscall and so mmap_base is used instead of mmap_compat_base. For i386 ELFs it works as SET_PERSONALITY() sets TS_COMPAT flag. As suggested by HPA and with diff by Thomas, make SET_PERSONALITY() change original syscall number to appropriate execve() number to pretend that we've come from the same bitness syscall as loading binary. Fixes: commit 1b028f784e8c ("x86/mm: Introduce mmap_compat_base() for 32-bit mmap()") Cc: 0x7f454c46@gmail.com Cc: linux-mm@kvack.org Cc: Andrei Vagin Cc: Cyrill Gorcunov Cc: Borislav Petkov Cc: "Kirill A. Shutemov" Cc: x86@kernel.org Cc: Andy Lutomirski Cc: Ingo Molnar Reported-by: Adam Borowski Suggested-by: H. Peter Anvin Suggested-by: Thomas Gleixner Signed-off-by: Dmitry Safonov --- v5: Use generated unistd includes than defining syscall numbers by hands. v4: Pretend that we've come from appropriate system call than only setting/dropping x32 bit. arch/x86/kernel/process_64.c | 70 +++++++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 21 deletions(-) diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index ea1a6180bf39..57a827f3ed5b 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -53,6 +53,13 @@ #include #include #include +#include +#ifdef CONFIG_X86_X32 +#include +#endif +#ifdef CONFIG_IA32_EMULATION +#include +#endif __visible DEFINE_PER_CPU(unsigned long, rsp_scratch); @@ -494,6 +501,8 @@ void set_personality_64bit(void) clear_thread_flag(TIF_IA32); clear_thread_flag(TIF_ADDR32); clear_thread_flag(TIF_X32); + /* Pretend that this comes from a 64bit execve */ + task_pt_regs(current)->orig_ax = __NR_execve; /* Ensure the corresponding mm is not marked. */ if (current->mm) @@ -506,32 +515,51 @@ void set_personality_64bit(void) current->personality &= ~READ_IMPLIES_EXEC; } -void set_personality_ia32(bool x32) +static void __set_personality_x32(void) { - /* inherit personality from parent */ +#ifdef CONFIG_X86_X32 + clear_thread_flag(TIF_IA32); + set_thread_flag(TIF_X32); + if (current->mm) + current->mm->context.ia32_compat = TIF_X32; + current->personality &= ~READ_IMPLIES_EXEC; + /* + * in_compat_syscall() uses the presence of the x32 + * syscall bit flag to determine compat status. + * The x86 mmap() code relies on the syscall bitness + * so set x32 syscall bit right here to make + * in_compat_syscall() work during exec(). + * + * Pretend to come from a x32 execve. + */ + task_pt_regs(current)->orig_ax = __NR_x32_execve | __X32_SYSCALL_BIT; + current->thread.status &= ~TS_COMPAT; +#endif +} +static void __set_personality_ia32(void) +{ +#ifdef CONFIG_IA32_EMULATION + set_thread_flag(TIF_IA32); + clear_thread_flag(TIF_X32); + if (current->mm) + current->mm->context.ia32_compat = TIF_IA32; + current->personality |= force_personality32; + /* Prepare the first "return" to user space */ + task_pt_regs(current)->orig_ax = __NR_ia32_execve; + current->thread.status |= TS_COMPAT; +#endif +} + +void set_personality_ia32(bool x32) +{ /* Make sure to be in 32bit mode */ set_thread_flag(TIF_ADDR32); - /* Mark the associated mm as containing 32-bit tasks. */ - if (x32) { - clear_thread_flag(TIF_IA32); - set_thread_flag(TIF_X32); - if (current->mm) - current->mm->context.ia32_compat = TIF_X32; - current->personality &= ~READ_IMPLIES_EXEC; - /* in_compat_syscall() uses the presence of the x32 - syscall bit flag to determine compat status */ - current->thread.status &= ~TS_COMPAT; - } else { - set_thread_flag(TIF_IA32); - clear_thread_flag(TIF_X32); - if (current->mm) - current->mm->context.ia32_compat = TIF_IA32; - current->personality |= force_personality32; - /* Prepare the first "return" to user space */ - current->thread.status |= TS_COMPAT; - } + if (x32) + __set_personality_x32(); + else + __set_personality_ia32(); } EXPORT_SYMBOL_GPL(set_personality_ia32); -- 2.12.0