From patchwork Mon Aug 22 04:01:34 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josh Max X-Patchwork-Id: 9292905 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 88B2660574 for ; Mon, 22 Aug 2016 04:17:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7C682288B8 for ; Mon, 22 Aug 2016 04:17:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 70B10288EA; Mon, 22 Aug 2016 04:17:30 +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 C4182288B8 for ; Mon, 22 Aug 2016 04:17:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752514AbcHVERN (ORCPT ); Mon, 22 Aug 2016 00:17:13 -0400 Received: from mail-bl2nam02on0135.outbound.protection.outlook.com ([104.47.38.135]:31572 "EHLO NAM02-BL2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752183AbcHVERL (ORCPT ); Mon, 22 Aug 2016 00:17:11 -0400 X-Greylist: delayed 908 seconds by postgrey-1.27 at vger.kernel.org; Mon, 22 Aug 2016 00:17:11 EDT Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Jmax@mail.greenriver.edu; Received: from nullbox.sinuous.gov (73.97.96.61) by CO2PR03MB2295.namprd03.prod.outlook.com (10.166.92.152) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id 15.1.587.9; Mon, 22 Aug 2016 04:01:58 +0000 From: Josh Max To: CC: , , Josh Max Subject: [PATCH] binfmt_misc: allow selecting the interpreter based on xattr keywords Date: Sun, 21 Aug 2016 21:01:34 -0700 Message-ID: <1471838494-29672-1-git-send-email-JMax@mail.greenriver.edu> X-Mailer: git-send-email 2.8.1 MIME-Version: 1.0 X-Originating-IP: [73.97.96.61] X-ClientProxiedBy: BN3PR10CA0027.namprd10.prod.outlook.com (10.161.211.37) To CO2PR03MB2295.namprd03.prod.outlook.com (10.166.92.152) X-MS-Office365-Filtering-Correlation-Id: 0637ed2d-06b6-47b5-bcd1-08d3ca411186 X-Microsoft-Exchange-Diagnostics: 1; CO2PR03MB2295; 2:jYA9UXdnTGw+DvfO9LQImEMxf5z5gbXSedkrNkr2AmDC274XqRIxSq4LQbKInAe7gg603wdw6d1e9LNnXGAJ/l+z+OxuhXIIGDZC8+MyDJR4Fz7Ev5WJitYHdRKOiDs5oTRsifssH2fkND8TeUe7REuOC6ftvAfqacegMqwVKqwC7JkMKtsa2KViyAeE7vUO; 3:EE+yp2+FvewHbiF1Qy39esirbbqaaZxxv0ICEYobxzHfT/zZBNBg1PxLGLi2SF1LguSUhjC2iQOh32IXsx+DMFS9ShBQgwME2vHdxIGxRe0zdF4M2+8IGDtKZKoKsr74 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:CO2PR03MB2295; X-Microsoft-Exchange-Diagnostics: 1; CO2PR03MB2295; 25:P5YhpFTfHbpQK/BFWUaO+zskqZxqgLo+ZQTba2/5kR5BatEg6w5G2h1VTtqOOwwe51VKyH8Pos71+6y0GzeOo0GJHf7N5QWRsNVOsf/EwaDXOSXLwVw6n0bMQD5VwX/oIEMFdiUCIVucp4gz6BLHwCGBHqCRIP+iFO4f+hFC5dkco6XFyS39iwefSV8XxzXz6cbO4SRTqKgNxg+iFhjAj9cry62cDXbKUg0DNXi7PLVUESyTM0WpWU1DcJAeiWJgkVpdA1not0THS0mEaonTzuHbP86QbL2xm6Foz9gaZgTQ1jp8/AEYARsEqWWy0MKWq2Bqd+L3earfO9TNEtQPmKUpYAuMXDFPj4YyEQ4P13AcLwU7a/DQFPsqqbszo7Nu2e/cKvAHoyscJFOmzHwn9WQk6hYRUscgOsZtlrDqyT5B4fEyO0TbF1v9fsfYaNBhMgd0dqb1oIigf8GtDSab6d1+DU/ZiG7n6gPJmJlXJhtCbgTqG8siRy1kbgQhWamk26caG67CrlwSznmSaeWnyjyyb6kXuu4f1NNE0n0EXrnd3KIjUwAdtB4Td5GTSugVhEpESB+J15QeO3E8m9zWbspMwmedZKmDWqx+LTWCtOo1NMq/U2QrLyy3ASa/RhfFy6WrnCj7vmrw/8R9YQ44/DUHPWXGgpr6T14QASiAk2ys2T1M8tg8FolBADT2/BG+2yH17SRw9o5DHoTh9/JoFaK/5cb3Tyo1GA6EsY5ffsQ= X-Microsoft-Exchange-Diagnostics: 1; CO2PR03MB2295; 31:gnNCnKW1JXCi5G3T01r3Wj1QswKErnEXNRLWmPDQa29PGcuE3bdDkznlF7ZSLwPrFOOl9L8SN7md0YAeK6X+fVLdKyLNJnS2jqX2OJ4rMefkGRXFKcbpHvVWURsH7YmmW3+TZ08Dq1fVHO5sz0GKWcesTPFYSCF1iw1sYwXD9bbTAT3GpgEivjPtTlHDktbQEZywZkp+000SlBNCMl4cY4K5talwkJwMD7q1k0L5WyY=; 20:lL+KTfdQtDmUq4ms128SgPiMGn99LwWK2fMjPAdl5ajZ69H3LQmSwecwmlQTMMIRLoKzY+kHUDUlEcfSbcEQWYwaEoVwXqybld7fdfzOnoHcazf8bZvrxw4PWuAUEhZE5zcPMDzRDNP2IjfiqUz8hIj0rmRJyt8jv6fYe3smEeLOOi32lA64wh4NSxWyFrC5VaY9PU2VPpTW5YGnR726oDKYNx+/P3GNA1M+riUok748hwAneRktYbxGWTT3jgU4K+D25xkClpEXQlbvs08ZTs2jRIXglgkZ7RArc3XCXx9lVqtS26nUr04NBVyCk3+nzVQe3Knv5kMlNFFoE1Zu/mhESw8h2w7sLztjMm6ZQ6g= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040176)(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001); SRVR:CO2PR03MB2295; BCL:0; PCL:0; RULEID:; SRVR:CO2PR03MB2295; X-Microsoft-Exchange-Diagnostics: 1; CO2PR03MB2295; 4:oXEpFBufQWjWYVE4oqQEpGx7UcphBQLAOgCICE9vHyjZ4FK2gF2G5U+XHMQJUz5AuuV2FvrNSi2fkguaLP/rWezjPRl2Mg3wLmnuMbbbUR92CXJs0XPfg+J7u1mw4SKvX3MOdPrVsK/QFUUUgXflKcsEcRx1jEAQQp7A2SLOep/cFrhNSYHzS5wtw0X+Is7PYFKiwnuxkjckpv9sOgwQJh4lY0kqP+y43DvkrYhd8Y1PM73l/iuwIptVZjGOsWmcNm41g++4phvCOhNofzvUQqWnFAY2bnZ7J690Nb/MFpflLBrC5ldzvkLh7npFRA6FvUPLE6/acLghd/D2DYQX8F+oWXGorTHMzPRVp8BCoJmSUzLUiuqo5OHcVqOk9+yWy4iRrOuFxcvG8+4TAUW1+Q== X-Forefront-PRVS: 00429279BA X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(4630300001)(6009001)(7916002)(189002)(199003)(42186005)(68736007)(66066001)(2351001)(88552002)(7846002)(7736002)(97736004)(110136002)(305945005)(229853001)(4326007)(2906002)(53416004)(5003940100001)(189998001)(105586002)(107886002)(50986999)(101416001)(48376002)(586003)(50226002)(69596002)(106356001)(75432002)(92566002)(81156014)(19580395003)(50466002)(81166006)(19580405001)(6116002)(89122001)(8676002)(80792005)(47776003)(86362001)(4001430100002)(77096005)(5660300001)(3846002); DIR:OUT; SFP:1102; SCL:1; SRVR:CO2PR03MB2295; H:nullbox.sinuous.gov; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; Received-SPF: None (protection.outlook.com: mail.greenriver.edu does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; CO2PR03MB2295; 23:cFU3b1oaz5qZCgAnm+jAkxxculBFyzksfUWwkT+ez?= =?us-ascii?Q?S7N6pwlvOpbhW0Ey+mu8P1af2sx3nD64ynRUS3zgJN0aKC3rz1QxLqZ1pSlj?= =?us-ascii?Q?z/OUKnzE9uAUhuYdW3Vt1hgICYUYdFZDyQdfs36sFLxWEmOxzPHt32/BFcIY?= =?us-ascii?Q?QSLWWJtH0LYEzOg55jiAgAwwQL5dZLy8bjVghFVgZfMU8cjymAVW/ctQuWzd?= =?us-ascii?Q?VPgi1uHrMLn56ZGbhlVaqMfj1Ov2DK0tbuOF4ABHGYKeHoTKNHs8Me5YVoM9?= =?us-ascii?Q?MBV359qwP/NleTdIIB5tJKFiv/qCgqCqJnHgRf+ubX3T8G3BJf73HeGhADJE?= =?us-ascii?Q?rwi6zdaaKbzBXnz4fASqoXXdgUKY1YWfJVqOdbrCU2dziESbBkgV0jg65GZq?= =?us-ascii?Q?QVVNsuJNQvhBsWbN0PpPlIgdR0t0Imq9aKmZGFGLKeyoZFaY7pLXB+/VgVyZ?= =?us-ascii?Q?CBBRxamfXz8WrQ48m5ZQxaLB9lZGK+smGpwKnICebeq2YDGhqpYBToITLigZ?= =?us-ascii?Q?UdGdZISIgXI0lTaafGE6/UlACsj06erM15PhQbrFhApuZlzXEtosb8HAYkuZ?= =?us-ascii?Q?xdSPHU85spSXHn2im4CnWU88Kud/IXEPyjNXY+favD/Td1P3TlZSTCCwXiMe?= =?us-ascii?Q?QKeW2qH61zNo9QhBUiGvfrYaXLQhft7S21L9ijgyBO8fYiNY01xc8JrSblJc?= =?us-ascii?Q?VpdujxeFFrfQOHrW99ZblGvMs/dRhsnvEQCo1kbHRZ2S+CeckVE/sjooPck+?= =?us-ascii?Q?fttbdEOWi8oaxPwsorJ+YcAn8XvnsLpZnH5+ICDSgV/gzK5i6ghlG/7rt1tP?= =?us-ascii?Q?FQuoe2+BO12waKXKWAPXYTlsuOZ14BBVZ6IBnZb+iFCyVeopolCN0gI37s0Y?= =?us-ascii?Q?qcKd+1hXnGdI5Qb9GPBUT+rhkbGK8L9Vf/aJPLe3cFPGkcTY+nXD7z514AfQ?= =?us-ascii?Q?mibQFVnboiQhw5/rMunCKR65SiVQj5+WHMmRjHmnNdLkkkRYM/E0ze45fpXS?= =?us-ascii?Q?xlAtFMpb1J8Um5aDafYPPFtAJWRCYhm2R1A4K+GCfAGIbQVOiiSqQ4vibj/C?= =?us-ascii?Q?AVWflzvgJ2v43AgI4KHczSYILenis+mY7eFJA8BCV71rrAy3HD6D6uWDOEQV?= =?us-ascii?Q?KMvv/txAWPgjkKSKn7iyEZuTxiKJjsY?= X-Microsoft-Exchange-Diagnostics: 1; CO2PR03MB2295; 6:XYPFoGrJQmCQyEcMyOSsvNqWPLPvjjVcDaaz2EljADa4i6tzrK8KgDRq6k0jKWay8q28jgGm68W2knK9MSQuOJqFQiyy5oClah0SIVpuz3stYjf6E2/k5lCuRWWG/ybVi5InEyl3lCUXVhRxPNvqmyI7hGoOabbbvBxonw6MSQtsO5I8wVECMMazFWFjQHeVTp7FK6GnPzWkYUJhFo+t9Tli7djO1KHyDVxLK9bE/4RJrbPQm+wuYw9HIdc3lEdI15x/i3pe86YxGVjz+wPg+/8V3jpB3rhRjBpz1xE0pvk=; 5:yiFqCH3hY+SGXJAVMIV+dfY+/TJBjJIzfe+u98w9iKiLccM+zOajA2eBrU0vnY197HWINHeBUE8y5lHi+XFlHjxtGA1XQ98b3BErqTykHTYAcJsO+7r2EeIn/iIiv16Pa7wOLVGJSAs4IEEZ9+aNVQ==; 24:8VK5sJ6wSG9yWNIJmQmE5Tk403pzv9a13R1OCrfGAS8GfsgfcYL2VdMrpUgnefkPkXqBxkTBGYYKETYkzetP72ZDgSDWwe+ZU8k6lJEzxiY=; 7:SZC06WXQrP5MfwB8kmgp0CQ/ox208cqVneD4fC3jpbuA83ubWLgBaAwRd0wYTafqRb0LBlPIZLCvYmbRo7AagFSRguPeh0OBxU0phapr7FapUbkeag1HwJKr+Cvmm13GiX4TNHRGf0XEEi9KSJhPxshdbj1OvFZdF+rd3uVsHcSwiWICpoAYXp+r9E5WWhMR459A8L7uG2ALYeV3oZ82FIUq5mgnx2TUwFK2x64L5LabGW22NnLkmt8Euz7zyWuy SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: mail.greenriver.edu X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Aug 2016 04:01:58.9716 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO2PR03MB2295 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 patch allows binfmt_misc to select the interpeter for arbitrary binaries by comparing a specified registered keyword with the value of a specified binary's extended attribute (user.binfmt.interp), and then launching the program with the registered interpreter. This is useful when wanting to launch a collection of binaries under the same interpreter, even when they do not necessarily share a common extension or magic bits, or when their magic conflics with the operation of binfmt_elf. Some examples of its use would be to launch some executables of various different architectures in a directory, or for running some native binaries under a sandbox (like firejail) automatically during their launch. Signed-off-by: Josh Max --- fs/binfmt_misc.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index 6103a63..86d93c7 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "internal.h" @@ -41,12 +42,17 @@ enum { static LIST_HEAD(entries); static int enabled = 1; -enum {Enabled, Magic}; +enum {Enabled, Magic, Keyword}; #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) +#define XATTR_BINFMT_PREFIX XATTR_USER_PREFIX "binfmt." +#define XATTR_BINFMT_INTERPRETER_SUFFIX "interp" +#define XATTR_NAME_BINFMT (XATTR_BINFMT_PREFIX XATTR_BINFMT_INTERPRETER_SUFFIX) +#define XATTR_VALUE_MAX_LENGTH 128 + typedef struct { struct list_head list; unsigned long flags; /* type, status, etc. */ @@ -61,6 +67,7 @@ typedef struct { } Node; static DEFINE_RWLOCK(entries_lock); +static int get_xattr_interp_keyword(struct file *file, char *buf, size_t count); static struct file_system_type bm_fs_type; static struct vfsmount *bm_mnt; static int entry_count; @@ -87,6 +94,8 @@ static int entry_count; */ static Node *check_file(struct linux_binprm *bprm) { + char k[XATTR_VALUE_MAX_LENGTH]; + int k_len = get_xattr_interp_keyword(bprm->file, k, sizeof(k)-1); char *p = strrchr(bprm->interp, '.'); struct list_head *l; @@ -100,6 +109,16 @@ static Node *check_file(struct linux_binprm *bprm) if (!test_bit(Enabled, &e->flags)) continue; + /* Do matching based on xattrs keyword */ + if (test_bit(Keyword, &e->flags)) { + if (k_len <= 0) + continue; + k[k_len] = 0; + if (!strcmp(e->magic, k)) + return e; + continue; + } + /* Do matching based on extension if applicable. */ if (!test_bit(Magic, &e->flags)) { if (p && !strcmp(e->magic, p + 1)) @@ -309,6 +328,20 @@ static char *check_special_flags(char *sfs, Node *e) } /* + * Check to see if the filesystem supports xattrs + * and grab the value so it can be checked against + * the list of keywords in binfmt_misc for a match + */ +static int get_xattr_interp_keyword(struct file *file, char *buf, size_t count) +{ + + if (unlikely(!file->f_inode->i_op->getxattr)) + return -ENOENT; + return file->f_inode->i_op->getxattr(file->f_path.dentry, file->f_inode, + XATTR_NAME_BINFMT, buf, count); +} + +/* * This registers a new binary format, it recognises the syntax * ':name:type:offset:magic:mask:interpreter:flags' * where the ':' is the IFS, that can be chosen with the first char @@ -366,6 +399,10 @@ static Node *create_entry(const char __user *buffer, size_t count) pr_debug("register: type: E (extension)\n"); e->flags = 1 << Enabled; break; + case 'K': + pr_debug("register: type: K (xattrs keyword)\n"); + e->flags = (1 << Enabled) | (1 << Keyword); + break; case 'M': pr_debug("register: type: M (magic)\n"); e->flags = (1 << Enabled) | (1 << Magic); @@ -453,7 +490,7 @@ static Node *create_entry(const char __user *buffer, size_t count) } } } else { - /* Handle the 'E' (extension) format. */ + /* Handle the 'E' (extension) and 'K' (keyword) format. */ /* Skip the 'offset' field. */ p = strchr(p, del); @@ -469,7 +506,10 @@ static Node *create_entry(const char __user *buffer, size_t count) *p++ = '\0'; if (!e->magic[0] || strchr(e->magic, '/')) goto einval; - pr_debug("register: extension: {%s}\n", e->magic); + if (test_bit(Keyword, &e->flags)) + pr_debug("register: keyword: {%s}\n", e->magic); + else + pr_debug("register: extension: {%s}\n", e->magic); /* Skip the 'mask' field. */ p = strchr(p, del); @@ -563,7 +603,10 @@ static void entry_status(Node *e, char *page) *dp++ = '\n'; if (!test_bit(Magic, &e->flags)) { - sprintf(dp, "extension .%s\n", e->magic); + if (test_bit(Keyword, &e->flags)) + sprintf(dp, "keyword %s\n", e->magic); + else + sprintf(dp, "extension .%s\n", e->magic); } else { dp += sprintf(dp, "offset %i\nmagic ", e->offset); dp = bin2hex(dp, e->magic, e->size);