From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933330AbcIENfh (ORCPT ); Mon, 5 Sep 2016 09:35:37 -0400 Received: from mail-db5eur01on0119.outbound.protection.outlook.com ([104.47.2.119]:9632 "EHLO EUR01-DB5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1754902AbcIENf3 (ORCPT ); Mon, 5 Sep 2016 09:35:29 -0400 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=dsafonov@virtuozzo.com; From: Dmitry Safonov To: CC: <0x7f454c46@gmail.com>, , , , , , , , , , Dmitry Safonov Subject: [PATCHv5 3/6] x86/arch_prctl/vdso: add ARCH_MAP_VDSO_* Date: Mon, 5 Sep 2016 16:33:05 +0300 Message-ID: <20160905133308.28234-4-dsafonov@virtuozzo.com> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20160905133308.28234-1-dsafonov@virtuozzo.com> References: <20160905133308.28234-1-dsafonov@virtuozzo.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [195.214.232.10] X-ClientProxiedBy: AM3PR03CA038.eurprd03.prod.outlook.com (10.141.191.166) To DB6PR0801MB1733.eurprd08.prod.outlook.com (10.169.226.148) X-MS-Office365-Filtering-Correlation-Id: 78066f21-511c-4cd7-feea-08d3d5917dce X-Microsoft-Exchange-Diagnostics: 1;DB6PR0801MB1733;2:7spUfN8qpXPXpUenDAo5lwkH96JCsYPScQcssQy0CZ/CtCq3VuAIJNA9OSlNFhw5xJSNlPwM/LFuXFAdj1cpbkIx8S4DLGtP38+xBjN3I6/uSOiZ5lRM7wodRFq0co8LD4Pi4+RPI60Wgz7Rh9qE5a1lR7VsGBmuCO7kAVkkHO78QrpsiNwpyDJR0v4C1+xR;3:1m7ecZOaSM010dIwPq+2liMZiMQHKOjxkXVMHyadNp0VPYP79MYfgVLhHDiJonCqJ2+dt/QXSBlqpqcVjk55tWRLi7X+xSfZlla+deBo/AQogMI2viY/wruDEsx7A7lK;25:gHTWkBsCtTmDVBP7tTM6NtaWGgtpJl7Oq4sc2Ap2prHReppEaAmKDhEN4bRh2TyU06aTHaTnVxTLtydY3K1yfirPcagS4b15pf5jrc+D9Cey0RJgQlaV4ADYFcT2q5t5Hw6NjyKDxz81g+ASCrWPnXHIobTr2dGvk2w2c4J0Fx4rEPxKS85VOo0zdaLw2GrEsUcO/7XQGLYovLhDwJ01nbz8kItzx3ZB+KcNspkQhxLuSgi2ataQaixhg3B26/jkZ1ReUuzAyTjxQrC1WTAutx5BrlBggQ761H7tF//bcnMI074+I35L5vUiQ7yxKNzcUabQ4mkd8zjhNZO2mdcnbw1sflJ/HZGmCrH3Yw2X9UqgjvCuug9tRwTssBN2q8EFnp418PUN0tQAuUoyTfW6NdqLdXuKhhUpwltg6B96d9Q= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:DB6PR0801MB1733; X-Microsoft-Exchange-Diagnostics: 1;DB6PR0801MB1733;31:X9eRDEEmsLly1vtN3T0t0IeG1Bpcdq6KpZOEOac3YDKuirLDLAlqu5ebKBOF79U0opK8gED/bCtHhE+aYmzXUG+ccobdNufk2QO2VGJ9Fdon2yNw7aF6ckYyqXz+0C2F3Xc1v6ALQLihN0szmhELl61cwIs8xdeIIF3GpdF7r0g+9Kz5e01GCqtPZkdsqkqvcXmHgD7X17iKjVb1EuVghBSBAQNn8BStKx86EZj+R2o=;4:6UQGcUGChz2Zt2slQ1uhYr1/TVWYeCGrwL9JHYDE3So/9eYBewenZCwFavoy+MJ2w09DaqtwbWyFq+a5Q6omkmBCO/ZEOqh6nmXF6vLJ/nJp/FOKgL5t9MwJEqOkcIg3lgvjbtOv/9CvAG5Aps+bdoFFvzpNrPbhlC27FCnKdS2Ecw3GV6NHgiPKLmaYUZBa/7sXMmpUsuUbnzd+NWJDgcaLUnPnVXLVDzrkxqTf7Tin5qhxjkLVgzlXX7UP9CRkiKmPVZCyEt3jaX57RRDOfDZP6lZivMajGLDt2sLwl0SDEPZSp0MXdTbVc3tJ8MazrJRDHdUM9IZVvaSfyvRFEF0fdDcnsh/zsVQK3YaBHqwroGAMXL1II843apD0HgdBoXJmC/3pTuW3Pc0zVfynsxv8aIxJJatFBcZcMckgPoc= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040176)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046)(6043046)(6042046);SRVR:DB6PR0801MB1733;BCL:0;PCL:0;RULEID:;SRVR:DB6PR0801MB1733; X-Forefront-PRVS: 005671E15D X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(4630300001)(6009001)(7916002)(199003)(189002)(33646002)(2351001)(50226002)(105586002)(106356001)(76176999)(19580405001)(4326007)(586003)(5003940100001)(189998001)(69596002)(50986999)(2906002)(305945005)(66066001)(1076002)(19580395003)(6116002)(8676002)(48376002)(107886002)(97736004)(3846002)(110136002)(101416001)(86362001)(7846002)(36756003)(77096005)(7736002)(53416004)(81166006)(229853001)(81156014)(50466002)(2950100001)(47776003)(4001430100002)(5660300001)(92566002)(575784001)(68736007)(42186005);DIR:OUT;SFP:1102;SCL:1;SRVR:DB6PR0801MB1733;H:dsafonov.sw.ru;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;DB6PR0801MB1733;23:jqQXKNFn7s9o004sp6tmdrTKQClDOMEzqW5jSoR?= =?us-ascii?Q?9kdS5859Oo1R8Apjfq9l2knKhxb9ljuuoUeeRxj9w9mO+cIlunCylwjNrhgN?= =?us-ascii?Q?aylXOiPL1bikZppn17/E47xZYhPinlOQqZNLgLKYk/OMqPWYhxG7W2cvXaey?= =?us-ascii?Q?Uey9mGif/fglTGXIqEZEpK3QnDFl5xnvypCLnHCfi6dP7w22faFlhlqTvE3S?= =?us-ascii?Q?1u55u7LkiiPVLO+2dx+i0GU4Ig1biNdigz95ka92kM9VQrnyGc+aJli4XJIY?= =?us-ascii?Q?XjBk7q+TlA/sWdScdk+38z6IGi4ckex4NwEJz2FCELeETCxW9b7HhX3isUgq?= =?us-ascii?Q?fuRAn6RCvA+xD4XdmeFijLHPFDhkqAj7f2RtJ0nbteu8JZarAZVZUGs8ZrU0?= =?us-ascii?Q?0BhUiemZx/eiL5gOu9Tb30g5Be2BYrEtGGL1GGgC0oYMxuSnQ7k3RW2i4LkR?= =?us-ascii?Q?kQEIbv3qi0R56pmHMAOw1R0fZ8MbWYX0Ki4eNX0ocMNUHdoaCfxhu5tCu0al?= =?us-ascii?Q?PgTr7PeTFC+N7gjOCKad71UKR8fGe2RInsdSBLnzrQzoFklfra+z9EeEPCMD?= =?us-ascii?Q?QnJjOzPn1SfyM+xQ8pKa0HbgTlTS+vtUqLsgkDRJJL6CucFNpT0FYYLQ6dvX?= =?us-ascii?Q?/aN1NymEXB35lclDDhkbPN+gZ1T/mDEQLsXrIWuFfGfn6YT5+kM8jl5/jAIU?= =?us-ascii?Q?/CTBV4QDHmN8rewNlfABZrSu4z0wrbLwDXqU9jZGqRTeoFALkhX3JEO7zQcT?= =?us-ascii?Q?eeWBagFXUU+QcawBsIjeavAIats0BORo6pQo03xE8gcqMXe97hcpp1yxAlhr?= =?us-ascii?Q?ApU+XBFKScd/FALoPGDdBxC8coydzqVw7Dc6NK88ZAyhXAJU14/+O0YqIANO?= =?us-ascii?Q?QJEdKG0Y/p6HoQm6L99bI3tV5DpFdy1Z0oIwFGTQYfu4kn+Rs9SH5Ovsivej?= =?us-ascii?Q?z3Y5ZU1X1SHarsvRzcNb6JZ2yTYrOq1B0TB+Ln2BwnYBiT8nT3mgujv7xCJI?= =?us-ascii?Q?DOl1xlFF/yPwb/NdxUvVpIUHCsXVMx4aNFsJAr5kU09QI1LsLBLp+imUJZ+e?= =?us-ascii?Q?w9PXEFMRfl7HilsYTX89Tr6K4i4dU5ii0q2HudJM3s/8StNXfU/FBF3VJcIV?= =?us-ascii?Q?M+9FbErBxVy1jlO0juWsxzot5Optn7bz6BO7zdEkwsKW1A+69D5kkqwyJrdC?= =?us-ascii?Q?2FlRT0je7ZarjNOh3m3Nf5SCQoJC2knyC4CJHAZVZXzmDbbIrhEJEDgMY1A?= =?us-ascii?Q?=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1;DB6PR0801MB1733;6:6M9KYDbue51hKa5f2iZhkzh3IvmXu1jJuUXF2XSiBLb152sllCHr5RBWq2RG/zdiwqBvxhDlHAaow+EkN0ftlrAsi/m9IhQ5JRQ0lY9cYo54rfz0/oT9WivkHIFiIFyh6nT+/0ieSiudD1p0xJTi530tXffbw6JUPnWz10eXxGXOtGlkddHIPVbc7OEhStsXzHYn+F8vn448041/6VXs1AdWpXrNAnaOohxfdUqQmyVaLefq3d42YLg6bxvwgCCjVjq5b80sPTqnbpyzsL+OWFEB+AIjPmrKLaupYw6a9fuF/JPhJaY2v1IgxFQ5XfQa;5:ZuOPWa6mXYEknTVifAN4qy5hkxYaFDOYp/WlaDkZAaiWRb8F5KtskkEchJrv8z317EqzwKS7K7WTlz7UgZR3bGmJ0G57kIbQk78/QRbbjqTtrMKGB+pg1zTySQwe1RsyEOwaUZnt5NvG/tdps2ydhQ==;24:BflbujeKZVj+lPQhd1dx5Kup4UgGB56URWEH46E+6dxA/E192qVqu07uxV1ytSh2mLQe2ISpvj9PdqYpq73nQ6ZIrWfbu7J0m3yVwatgUXU=;7:SseXFK9FijxnOQa0ekRL9vrjD/MEFjv1Gwwxpx1ngStgL0i9VchS4zMOSv1C9z9Hu9FDkWjHNcNjiSGRTatjNMQrmeF8iwE3UjszTsJxpOPqOS3YYeN/Ejbe9bKxLzbsG7yz5AvtYo5MXqjzcmUepxOYisDeiKGQKWnAxhRUIB2+TKiO3XFnYyd7rkF8sbbKtjdIZO5FHoj7ZkpktaHoB1b0dmKBBZsBAfb64tJDWf2tgnZoYWqJ5L8QdGu022d9 SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;DB6PR0801MB1733;20:qQn+FA8Cm3XAgPR+WYTd4Vxuxp2MJ+gU9dK8idyHErH8/l46ZPfuDI16hcERc+YIJ/l57UGSJf+Qhkzvb3pVSRepZ8EvfX4jK0SaYdBGFXjXfaBhyHQ1LwQw2yF0zyBIC+wXSr5FQKn2Mb0xdEGzqqkRlqY0DZ17vtjRN+XMz4U= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Sep 2016 13:35:23.4594 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB6PR0801MB1733 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add API to change vdso blob type with arch_prctl. As this is usefull only by needs of CRIU, expose this interface under CONFIG_CHECKPOINT_RESTORE. Cc: Andy Lutomirski Cc: Oleg Nesterov Cc: Thomas Gleixner Cc: "H. Peter Anvin" Cc: Ingo Molnar Cc: linux-mm@kvack.org Cc: x86@kernel.org Cc: Cyrill Gorcunov Cc: Pavel Emelyanov Signed-off-by: Dmitry Safonov --- arch/x86/entry/vdso/vma.c | 45 ++++++++++++++++++++++++++++++--------- arch/x86/include/asm/vdso.h | 2 ++ arch/x86/include/uapi/asm/prctl.h | 6 ++++++ arch/x86/kernel/process_64.c | 25 ++++++++++++++++++++++ include/linux/mm.h | 2 ++ mm/mmap.c | 8 +++++++ 6 files changed, 78 insertions(+), 10 deletions(-) diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c index 5bcb25a9e573..4459e73e234d 100644 --- a/arch/x86/entry/vdso/vma.c +++ b/arch/x86/entry/vdso/vma.c @@ -176,6 +176,16 @@ static int vvar_fault(const struct vm_special_mapping *sm, return VM_FAULT_SIGBUS; } +static const struct vm_special_mapping vdso_mapping = { + .name = "[vdso]", + .fault = vdso_fault, + .mremap = vdso_mremap, +}; +static const struct vm_special_mapping vvar_mapping = { + .name = "[vvar]", + .fault = vvar_fault, +}; + /* * Add vdso and vvar mappings to current process. * @image - blob to map @@ -188,16 +198,6 @@ static int map_vdso(const struct vdso_image *image, unsigned long addr) unsigned long text_start; int ret = 0; - static const struct vm_special_mapping vdso_mapping = { - .name = "[vdso]", - .fault = vdso_fault, - .mremap = vdso_mremap, - }; - static const struct vm_special_mapping vvar_mapping = { - .name = "[vvar]", - .fault = vvar_fault, - }; - if (down_write_killable(&mm->mmap_sem)) return -EINTR; @@ -256,6 +256,31 @@ static int map_vdso_randomized(const struct vdso_image *image) return map_vdso(image, addr); } +int map_vdso_once(const struct vdso_image *image, unsigned long addr) +{ + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + + down_write(&mm->mmap_sem); + /* + * Check if we have already mapped vdso blob - fail to prevent + * abusing from userspace install_speciall_mapping, which may + * not do accounting and rlimit right. + * We could search vma near context.vdso, but it's a slowpath, + * so let's explicitely check all VMAs to be completely sure. + */ + for (vma = mm->mmap; vma; vma = vma->vm_next) { + if (vma_is_special_mapping(vma, &vdso_mapping) || + vma_is_special_mapping(vma, &vvar_mapping)) { + up_write(&mm->mmap_sem); + return -EEXIST; + } + } + up_write(&mm->mmap_sem); + + return map_vdso(image, addr); +} + #if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION) static int load_vdso32(void) { diff --git a/arch/x86/include/asm/vdso.h b/arch/x86/include/asm/vdso.h index 43dc55be524e..2444189cbe28 100644 --- a/arch/x86/include/asm/vdso.h +++ b/arch/x86/include/asm/vdso.h @@ -41,6 +41,8 @@ extern const struct vdso_image vdso_image_32; extern void __init init_vdso_image(const struct vdso_image *image); +extern int map_vdso_once(const struct vdso_image *image, unsigned long addr); + #endif /* __ASSEMBLER__ */ #endif /* _ASM_X86_VDSO_H */ diff --git a/arch/x86/include/uapi/asm/prctl.h b/arch/x86/include/uapi/asm/prctl.h index 3ac5032fae09..ae135de547f5 100644 --- a/arch/x86/include/uapi/asm/prctl.h +++ b/arch/x86/include/uapi/asm/prctl.h @@ -6,4 +6,10 @@ #define ARCH_GET_FS 0x1003 #define ARCH_GET_GS 0x1004 +#ifdef CONFIG_CHECKPOINT_RESTORE +# define ARCH_MAP_VDSO_X32 0x2001 +# define ARCH_MAP_VDSO_32 0x2002 +# define ARCH_MAP_VDSO_64 0x2003 +#endif + #endif /* _ASM_X86_PRCTL_H */ diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 63236d8f84bf..f240a465920b 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -49,6 +49,7 @@ #include #include #include +#include asmlinkage extern void ret_from_fork(void); @@ -524,6 +525,17 @@ void set_personality_ia32(bool x32) } EXPORT_SYMBOL_GPL(set_personality_ia32); +static long prctl_map_vdso(const struct vdso_image *image, unsigned long addr) +{ + int ret; + + ret = map_vdso_once(image, addr); + if (ret) + return ret; + + return (long)image->size; +} + long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) { int ret = 0; @@ -577,6 +589,19 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) break; } +#ifdef CONFIG_CHECKPOINT_RESTORE +#ifdef CONFIG_X86_X32 + case ARCH_MAP_VDSO_X32: + return prctl_map_vdso(&vdso_image_x32, addr); +#endif +#if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION + case ARCH_MAP_VDSO_32: + return prctl_map_vdso(&vdso_image_32, addr); +#endif + case ARCH_MAP_VDSO_64: + return prctl_map_vdso(&vdso_image_64, addr); +#endif + default: ret = -EINVAL; break; diff --git a/include/linux/mm.h b/include/linux/mm.h index ef815b9cd426..5f14534f0c90 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2019,6 +2019,8 @@ extern struct file *get_task_exe_file(struct task_struct *task); extern bool may_expand_vm(struct mm_struct *, vm_flags_t, unsigned long npages); extern void vm_stat_account(struct mm_struct *, vm_flags_t, long npages); +extern bool vma_is_special_mapping(const struct vm_area_struct *vma, + const struct vm_special_mapping *sm); extern struct vm_area_struct *_install_special_mapping(struct mm_struct *mm, unsigned long addr, unsigned long len, unsigned long flags, diff --git a/mm/mmap.c b/mm/mmap.c index ca9d91bca0d6..6373ebd358c0 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -3063,6 +3063,14 @@ out: return ERR_PTR(ret); } +bool vma_is_special_mapping(const struct vm_area_struct *vma, + const struct vm_special_mapping *sm) +{ + return vma->vm_private_data == sm && + (vma->vm_ops == &special_mapping_vmops || + vma->vm_ops == &legacy_special_mapping_vmops); +} + /* * Called with mm->mmap_sem held for writing. * Insert a new vma covering the given region, with the given flags. -- 2.9.0