From patchwork Thu Mar 31 14:56:19 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Bottomley X-Patchwork-Id: 8713981 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 8A94F9F38C for ; Thu, 31 Mar 2016 14:56:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8F0AF20279 for ; Thu, 31 Mar 2016 14:56:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9749E20272 for ; Thu, 31 Mar 2016 14:56:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757169AbcCaO4W (ORCPT ); Thu, 31 Mar 2016 10:56:22 -0400 Received: from bedivere.hansenpartnership.com ([66.63.167.143]:55076 "EHLO bedivere.hansenpartnership.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756811AbcCaO4V (ORCPT ); Thu, 31 Mar 2016 10:56:21 -0400 Received: from localhost (localhost [127.0.0.1]) by bedivere.hansenpartnership.com (Postfix) with ESMTP id 7D1B08EE341; Thu, 31 Mar 2016 07:56:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=hansenpartnership.com; s=20151216; t=1459436180; bh=xgFMNHuQWeibdGM4K6toFxKj9khzkCQyBJU5oSUTkPU=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=FRuxzo4cNCWwWiMnrOWmRpWbetSjrUICy5XGeGK8G6mZIv1gRxns3xVAaPjFm8ZoG dU/ak5EjgqnfqAKp3jLBStFl7VJgsLtp3wgq6GSlkvrvIDQt+IDyqxUH6synZu1PL3 2pruUJxkcAkh2rIFe/3jqIwo0t79BXMcmLR1DXxI= Received: from bedivere.hansenpartnership.com ([127.0.0.1]) by localhost (bedivere.hansenpartnership.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id wX87gKWPphR9; Thu, 31 Mar 2016 07:56:20 -0700 (PDT) Received: from [10.0.6.30] (unknown [64.55.107.3]) by bedivere.hansenpartnership.com (Postfix) with ESMTPSA id 2438B8EE0CD; Thu, 31 Mar 2016 07:56:20 -0700 (PDT) Message-ID: <1459436179.2958.23.camel@HansenPartnership.com> Subject: [Patch v3 2/3] binfmt_misc: add persistent opened binary handler for containers From: James Bottomley To: containers@lists.linux-foundation.org, linux-fsdevel Cc: Al Viro , Jan Kara Date: Thu, 31 Mar 2016 07:56:19 -0700 In-Reply-To: <1459436046.2958.21.camel@HansenPartnership.com> References: <1459436046.2958.21.camel@HansenPartnership.com> X-Mailer: Evolution 3.16.5 Mime-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Spam-Status: No, score=-7.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds a new flag 'F' to the binfmt handlers. If you pass in 'F' the binary that runs the emulation will be opened immediately and in future, will be cloned from the open file. The net effect is that the handler survives both changeroots and mount namespace changes, making it easy to work with foreign architecture containers without contaminating the container image with the emulator. Signed-off-by: James Bottomley Acked-by: Serge Hallyn --- fs/binfmt_misc.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index 3a3ced7..8a108c4 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c @@ -26,6 +26,8 @@ #include #include +#include "internal.h" + #ifdef DEBUG # define USE_DEBUG 1 #else @@ -43,6 +45,7 @@ enum {Enabled, Magic}; #define MISC_FMT_PRESERVE_ARGV0 (1 << 31) #define MISC_FMT_OPEN_BINARY (1 << 30) #define MISC_FMT_CREDENTIALS (1 << 29) +#define MISC_FMT_OPEN_FILE (1 << 28) typedef struct { struct list_head list; @@ -54,6 +57,7 @@ typedef struct { char *interpreter; /* filename of interpreter */ char *name; struct dentry *dentry; + struct file *interp_file; } Node; static DEFINE_RWLOCK(entries_lock); @@ -201,7 +205,13 @@ static int load_misc_binary(struct linux_binprm *bprm) if (retval < 0) goto error; - interp_file = open_exec(iname); + if (fmt->flags & MISC_FMT_OPEN_FILE && fmt->interp_file) { + interp_file = filp_clone_open(fmt->interp_file); + if (!IS_ERR(interp_file)) + deny_write_access(interp_file); + } else { + interp_file = open_exec(iname); + } retval = PTR_ERR(interp_file); if (IS_ERR(interp_file)) goto error; @@ -285,6 +295,11 @@ static char *check_special_flags(char *sfs, Node *e) e->flags |= (MISC_FMT_CREDENTIALS | MISC_FMT_OPEN_BINARY); break; + case 'F': + pr_debug("register: flag: F: open interpreter file now\n"); + p++; + e->flags |= MISC_FMT_OPEN_FILE; + break; default: cont = 0; } @@ -543,6 +558,8 @@ static void entry_status(Node *e, char *page) *dp++ = 'O'; if (e->flags & MISC_FMT_CREDENTIALS) *dp++ = 'C'; + if (e->flags & MISC_FMT_OPEN_FILE) + *dp++ = 'F'; *dp++ = '\n'; if (!test_bit(Magic, &e->flags)) { @@ -590,6 +607,11 @@ static void kill_node(Node *e) } write_unlock(&entries_lock); + if ((e->flags & MISC_FMT_OPEN_FILE) && e->interp_file) { + filp_close(e->interp_file, NULL); + e->interp_file = NULL; + } + if (dentry) { drop_nlink(d_inode(dentry)); d_drop(dentry); @@ -698,6 +720,21 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer, goto out2; } + if (e->flags & MISC_FMT_OPEN_FILE) { + struct file *f; + + f = open_exec(e->interpreter); + if (IS_ERR(f)) { + err = PTR_ERR(f); + pr_notice("register: failed to install interpreter file %s\n", e->interpreter); + simple_release_fs(&bm_mnt, &entry_count); + iput(inode); + inode = NULL; + goto out2; + } + e->interp_file = f; + } + e->dentry = dget(dentry); inode->i_private = e; inode->i_fop = &bm_entry_operations; @@ -716,7 +753,7 @@ out: if (err) { kfree(e); - return -EINVAL; + return err; } return count; }