From patchwork Wed Jul 20 04:20:16 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Pitre X-Patchwork-Id: 9238849 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5D88F602F0 for ; Wed, 20 Jul 2016 04:24:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 53F371FF60 for ; Wed, 20 Jul 2016 04:24:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 48AB726C2F; Wed, 20 Jul 2016 04:24:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CF9111FF60 for ; Wed, 20 Jul 2016 04:24:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753125AbcGTEXG (ORCPT ); Wed, 20 Jul 2016 00:23:06 -0400 Received: from alt22.smtp-out.videotron.ca ([70.80.0.73]:28337 "EHLO alt22.smtp-out.videotron.ca" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751308AbcGTEUt (ORCPT ); Wed, 20 Jul 2016 00:20:49 -0400 Received: from yoda.home ([96.23.157.65]) by Videotron with SMTP id Pj02bi2EKPTiyPj03bBcsr; Wed, 20 Jul 2016 00:20:48 -0400 X-Authority-Analysis: v=2.1 cv=L469O7n8 c=1 sm=1 tr=0 a=keA3yYpnlypCNW5BNWqu+w==:117 a=keA3yYpnlypCNW5BNWqu+w==:17 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=cAmyUtKerLwA:10 a=KKAkSRfTAAAA:8 a=tBb2bbeoAAAA:8 a=6-zIpsv45UhBbMx_Gb0A:9 a=cvBusfyB2V15izCimMoJ:22 a=Oj-tNtZlA1e06AYgeCfH:22 Received: from xanadu.home (xanadu.home [192.168.2.2]) by yoda.home (Postfix) with ESMTP id 057A22DA05F0; Wed, 20 Jul 2016 00:20:46 -0400 (EDT) From: Nicolas Pitre To: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Alexander Viro , David Howells , Greg Ungerer Subject: [PATCH v3 04/12] elf_fdpic_transfer_args_to_stack(): make it generic Date: Wed, 20 Jul 2016 00:20:16 -0400 Message-Id: <1468988424-32671-5-git-send-email-nicolas.pitre@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1468988424-32671-1-git-send-email-nicolas.pitre@linaro.org> References: <1468988424-32671-1-git-send-email-nicolas.pitre@linaro.org> X-CMAE-Envelope: MS4wfBdCcepaGrIeqyRj6nWFfGbZPiESvWc6SZ/fZR4gIvE33QmA9HVbnliLgp8MK+hlc5Icx38cFA+zEBxAuDMIm4iYwgEZpBDl2/plp5LbWZhgX93iaX9V vDlCaRqg62c0nmw1jfvCQqjg7R2GwQKvF978st6VvtFqTID9IP4uvtP+8Hi93iWK85kxzzX+kN3jdqb00Pm61Zcjh4dSEUWoX4u/V8ErhIx/Zu76yp8H4MnH RPLrEWJhcmhpA0fW07UQdyQPACcUW7LS3LjZ1yUXrCUTDh+L8erjx8KBI1TdMict6c2GQXJewlEIvP+xIUBYBw== Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This copying of arguments and environment is common to both NOMMU binary formats we support. Let's make the elf_fdpic version available to the flat format as well. While at it, improve the code a bit not to copy below the actual data area. Signed-off-by: Nicolas Pitre Reviewed-by: Greg Ungerer --- fs/binfmt_elf_fdpic.c | 38 ++------------------------------------ fs/exec.c | 33 +++++++++++++++++++++++++++++++++ include/linux/binfmts.h | 2 ++ 3 files changed, 37 insertions(+), 36 deletions(-) diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 203589311b..464a972e88 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -67,8 +67,6 @@ static int create_elf_fdpic_tables(struct linux_binprm *, struct mm_struct *, struct elf_fdpic_params *); #ifndef CONFIG_MMU -static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *, - unsigned long *); static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *, struct file *, struct mm_struct *); @@ -515,8 +513,9 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm, sp = mm->start_stack; /* stack the program arguments and environment */ - if (elf_fdpic_transfer_args_to_stack(bprm, &sp) < 0) + if (transfer_args_to_stack(bprm, &sp) < 0) return -EFAULT; + sp &= ~15; #endif /* @@ -711,39 +710,6 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm, /*****************************************************************************/ /* - * transfer the program arguments and environment from the holding pages onto - * the stack - */ -#ifndef CONFIG_MMU -static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *bprm, - unsigned long *_sp) -{ - unsigned long index, stop, sp; - char *src; - int ret = 0; - - stop = bprm->p >> PAGE_SHIFT; - sp = *_sp; - - for (index = MAX_ARG_PAGES - 1; index >= stop; index--) { - src = kmap(bprm->page[index]); - sp -= PAGE_SIZE; - if (copy_to_user((void *) sp, src, PAGE_SIZE) != 0) - ret = -EFAULT; - kunmap(bprm->page[index]); - if (ret < 0) - goto out; - } - - *_sp = (*_sp - (MAX_ARG_PAGES * PAGE_SIZE - bprm->p)) & ~15; - -out: - return ret; -} -#endif - -/*****************************************************************************/ -/* * load the appropriate binary image (executable or interpreter) into memory * - we assume no MMU is available * - if no other PIC bits are set in params->hdr->e_flags diff --git a/fs/exec.c b/fs/exec.c index 887c1c955d..ef0df2f092 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -762,6 +762,39 @@ out_unlock: } EXPORT_SYMBOL(setup_arg_pages); +#else + +/* + * Transfer the program arguments and environment from the holding pages + * onto the stack. The provided stack pointer is adjusted accordingly. + */ +int transfer_args_to_stack(struct linux_binprm *bprm, + unsigned long *sp_location) +{ + unsigned long index, stop, sp; + int ret = 0; + + stop = bprm->p >> PAGE_SHIFT; + sp = *sp_location; + + for (index = MAX_ARG_PAGES - 1; index >= stop; index--) { + unsigned int offset = index == stop ? bprm->p & ~PAGE_MASK : 0; + char *src = kmap(bprm->page[index]) + offset; + sp -= PAGE_SIZE - offset; + if (copy_to_user((void *) sp, src, PAGE_SIZE - offset) != 0) + ret = -EFAULT; + kunmap(bprm->page[index]); + if (ret) + goto out; + } + + *sp_location = sp; + +out: + return ret; +} +EXPORT_SYMBOL(transfer_args_to_stack); + #endif /* CONFIG_MMU */ static struct file *do_open_execat(int fd, struct filename *name, int flags) diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index 314b3caa70..1303b570b1 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -113,6 +113,8 @@ extern int suid_dumpable; extern int setup_arg_pages(struct linux_binprm * bprm, unsigned long stack_top, int executable_stack); +extern int transfer_args_to_stack(struct linux_binprm *bprm, + unsigned long *sp_location); extern int bprm_change_interp(char *interp, struct linux_binprm *bprm); extern int copy_strings_kernel(int argc, const char *const *argv, struct linux_binprm *bprm);