From patchwork Thu Jul 28 14:09:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan McDowell X-Patchwork-Id: 12931334 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A2C4EC3F6B0 for ; Thu, 28 Jul 2022 14:09:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230199AbiG1OJY (ORCPT ); Thu, 28 Jul 2022 10:09:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38006 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230047AbiG1OJP (ORCPT ); Thu, 28 Jul 2022 10:09:15 -0400 Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2539020F7E; Thu, 28 Jul 2022 07:09:12 -0700 (PDT) Received: from pps.filterd (m0109334.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 26SA39HK028393; Thu, 28 Jul 2022 07:09:11 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=from : to : cc : subject : date : message-id : references : in-reply-to : content-type : content-id : mime-version; s=facebook; bh=TRQxI525O1sONmlMXp0vyGKZgiWiTs/6ZhGBzp1JYFk=; b=YE69gdOqMAUH7x8lFK/s0+B2obq61PCUWYtl9lz0FeA0+592jsdpEWo9jMUZQwEWzBI4 QHOfCPaxsVGJPYrvWarzfZYfkCxaez73UR4QI7Vo7SoyCwPGEXGEEqQ970YNM/LGTAVv 10/Fs432cTI5X9LtuHDUqlsvNZZSsoHE6Fs= Received: from nam12-bn8-obe.outbound.protection.outlook.com (mail-bn8nam12lp2176.outbound.protection.outlook.com [104.47.55.176]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3hkfsk3kc9-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 28 Jul 2022 07:09:10 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=IFb44V//Ko2bGSIYmBuZp6s+NsCNiVk42zOkXp11PF7xWvcxoJjlbsGIldnWtT0Dz0lfJUHsEdYE5TMs/vPYKO+VUVHvkL6UOuWAu7haHExRm2CdJyui504JRYHnRESPGbPiFTHv/Px41tc+JkgwtYu1Wng78yZvHIQpsVnXQZLB4Dt2iE7N4nlVxq5ycECcapa6uO4mm/IXyvj3mFaYp+BeTH0mN/eoQK4NPeq31jUheH69Wq0FC2yVtIDDDzs8zcgLLUHSg1BIpBz13BYuTnL/hxykmJKnyG9N8c5MQNnv2wtbl/cdIHgVLD2E6Sj68zxHbFE9KWfmMDg4MGA/LA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=TRQxI525O1sONmlMXp0vyGKZgiWiTs/6ZhGBzp1JYFk=; b=n4FjrGbVNNkZPRN9LC97HM8WXRtyoD/Un9MEbTkGUchHYlveLtQTvDWGvDcQha4s8nZkqNbwp+DQkQEAD36A1owHA6yXhokr8r9T73n47lo+KgnEdZX1VvatCuRUXapjtFmYmJXPnjEqiXfQulmr3RcdMxfEoP/RJRQp75UFnzJ+OSZ07Wf1DvLDImcO+orc6fz9gii5Ns3rtFvpXgYl8dWUyEBU47CR+BjXp3CytQnhhlBNjHXwM+H70ghwnaN4ioavEUGuM8P7zoZW1vijSVmNO6R7rx1FEdSUm4Xfb+qljWZKcmFebyro6SztPpIXknggpYQ0UD+59dLCEDk9/Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=fb.com; dmarc=pass action=none header.from=fb.com; dkim=pass header.d=fb.com; arc=none Received: from SJ0PR15MB4552.namprd15.prod.outlook.com (2603:10b6:a03:379::12) by MN2PR15MB4256.namprd15.prod.outlook.com (2603:10b6:208:fe::25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5458.25; Thu, 28 Jul 2022 14:09:04 +0000 Received: from SJ0PR15MB4552.namprd15.prod.outlook.com ([fe80::81f9:c21c:c5bf:e174]) by SJ0PR15MB4552.namprd15.prod.outlook.com ([fe80::81f9:c21c:c5bf:e174%8]) with mapi id 15.20.5458.025; Thu, 28 Jul 2022 14:09:04 +0000 From: Jonathan McDowell To: "linux-kernel@vger.kernel.org" , "linux-fsdevel@vger.kernel.org" , "linux-integrity@vger.kernel.org" , "linux-security-module@vger.kernel.org" CC: Alexander Viro , Mimi Zohar , Dmitry Kasatkin , James Morris , "Serge E. Hallyn" , Matthew Garrett , Dmitrii Potoskuev Subject: [RFC PATCH v2 1/7] initramfs: Move cpio handling routines into lib/ Thread-Topic: [RFC PATCH v2 1/7] initramfs: Move cpio handling routines into lib/ Thread-Index: AQHYoouYmGug1fd2iUm/OP4sgeIyNQ== Date: Thu, 28 Jul 2022 14:09:04 +0000 Message-ID: References: In-Reply-To: Accept-Language: en-GB, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 03cddf9b-4942-4ea8-57ee-08da70a2ba89 x-ms-traffictypediagnostic: MN2PR15MB4256:EE_ x-fb-source: Internal x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: Gug2OU3P/Qk9Q/y0boy28pagmwhJo7s7ohPpupszW9bN2p1fbSsnh0ffCXqGjq7bYJZ1Ko30pvfu5WrnzAXfgszP2aVa/fAXDVd8tchBZdsNWywlWkIMLKYtqXJq0mFWRNuWFXmFewB2OpUjg3uVGPv3D76uHUHo8Xs7BQ6UNNX5SeRLu85T9YSH34PsYNhOXQ6ksOwUCBZQUyiRwEt0J/RtIgQvnk4zyfdZ6pk68WIh97zw/OduPVUS7neeOi5Ta42tVupJOv3opbP5FIVQ9/74dYBY1M4v3HU56+VEItPoMJHuhSurkKYmddalASnWMV0vgfHUmXzEaJK/ZcEtGfbvn3pTVmhe+ITdlu01nsRHvz4dRdeBfrT6V/WBtQp144YGNcH9Ld9p0+wFHC+jdl9gkemfp/cvO+/V8wtiFccisk9ErWsjNIk8vg7sWZBpXw5oDDJb4EJh/y7rgpDfEWWQ1TovZ+QM7+/rsx8S1P8dUOsLFu4wt0K51eszin70qFLtTVNHl3yqqmvm1QXyw1CF5gwqANd/2DecpgtdivXhXB6fO8bagi3Z/DwA8V9QoLsZ6ZsCupkZASmUgTQgAPnLOeUmvlQLhwX+aasLGz9spI2tWwyLVtCpVnqennfo81X6BPo8ll0AcpQWAGgxcJQ46B3jq2s6f9HNRGKV+95K5mHkTRP+zsj7CN8AMcIZOLr6C0yEgizJX1diWxukQUILVLm6YI8GDsC5NYLZkXZRrNs2JpMwQgISTIemT44ibt+C6j64oWSLuGaThWe6YmVDniFuPps4/+Rg8e/ubb/N16qAXUXp7MDTg5CZ1p4T x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SJ0PR15MB4552.namprd15.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230016)(4636009)(346002)(376002)(366004)(136003)(39860400002)(396003)(7416002)(2616005)(2906002)(478600001)(122000001)(41300700001)(6506007)(86362001)(316002)(36756003)(186003)(30864003)(5660300002)(38070700005)(38100700002)(66476007)(4326008)(83380400001)(6486002)(6512007)(91956017)(110136005)(54906003)(26005)(71200400001)(76116006)(66946007)(8676002)(8936002)(64756008)(66556008)(66446008)(579004)(559001);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: VP2uvNI2Vi5pFRgG0UKjUIX26lh6THbgOItmlaZgAlTpurbxBPg0XWkyp7httLI7ri21soGsgaCXy1TFZ31jAyWJ0y2fbsb6hOGlDOl/chgW+Vggg/XJCbQvMpqIdGnTIzB1otw+ORU+NLr4JA85b7+8H0kWRi3pr4r09skCdeLS1EGRSnnQv1neHn7Zapv5xB0p9Rc1mrgl4AI5g1b0jZvgV8qtwWTtdf0nDvkIh0d2PoXgzsX6CExM9GI1REsU0s7zcmmVpeK4hwllM2fAi6DKl0+VPT8hBr7w2qWS+/eNIKobVADGA8DlUjpnpDn7mGS6HIpYbGIc/YOlBkpdXAKZ+qei4cq0t0yw1ghcA8uDK/Fq6XoqI87eg/HXORmIRdyabEtSRkKHnSomGeTZhPSS6RIbuik3+5Jzvd3dh0334U52uqlqD2j15t/YiSZatAMF1+SQ4mXEqPGD0mkepxToe2cmIVjtzkYWNxf901usgr2SlJjZbNv3WM1j4GC+j9SSaZxqtE4V44kANohmLLNMk8NY7lrx7QFrr9tbxvhXeIrBayy3Qd1sn4EdC4trrbHcjgpPn7czu4S0PLpgLpedluq3EBiG545ppTTKK4G9KwbkVMXqxaCG3GMLOfVf0CJywr+1cTxMRwPBYZViZZ1Qkk0WxfKLTSiQXA3YuXveRUPvie/ug1R7xA4TUFkCVBuSRfntllWmKlFDLekmujd3GVIYtRA4n2qhTyvGWdk06Toxrio8s5mkiMacG8xtYL599lGyMauDjaUsqhFt7xcj+vNtJuPQP7zb6xHl9fkkaHgpjV6JOPSGUVxdeUYfaY/RTrVrqpvkQCZvlSJiNT3URZvNTnzPhPsE6HXB939HJCJO9EMNx8W4YnCJYhir7qhH1XsBjq0h+NBOBWeJ7tPvdf/NMhk+h3/pHDpbJ226VuUex3KGr/n56eyASuAEunvGepaAOYsuxDLdWpauqh+aP55LG4FQ87eZYEotYADYiukFrDVu62KMTsBsc9r77EshphFuEy+U87nHDBxhjkJWQubbDlpCti/L5OXWGikc8c/lhCRnXXSk44skodl7ZmYUtche26eRoIpOsLM0UmiP0kUO5sGM5hqJfzrh2y/3pQAb5Ly0LzuN9kEsDM2u949B7T9qIJF1mjUZC1JiJuyTht1okLFTwR8KXzsJ3Z3IHCAyb9t6XWSQO16Tm+pqRjI5rKae0BbfRNYKt7BSrU+cTJe0L7KvYjmAbnhDcOb+AdIr2CnOdqiJfqMrEGpVX5hBpPscilO7hxVG5JzCHlCZDJR6/Re1qUL5cBM3SvmkrKeOPowahHjvrmjedoWSN9a32/RYX3iu1Yk7J6oequ7nZDAPX08kpjdgr4Ue/gcmNzwQfaPGUBO9qQC2Fp1V8IwuqbJR3LwoAQ/0SRYG0Ol+b/sM1W/Z37YUvVGOgemzwmrQvZ/oazkJxZ457ZabqZ0OX/4DVfSTUhYNWWsDQS8Z1iYY4OJOBHnUNgSGxpBHVlmhJnDiLQiuJgwXdwa1liIYeAA52dT2u7udmOTmq/tIwCxAfghtbKaqVttDpATkltxyCJ6DKQPHYoQYJrIC Content-ID: <2118936A27D66648B667D6D212945885@namprd15.prod.outlook.com> MIME-Version: 1.0 X-OriginatorOrg: fb.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: SJ0PR15MB4552.namprd15.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 03cddf9b-4942-4ea8-57ee-08da70a2ba89 X-MS-Exchange-CrossTenant-originalarrivaltime: 28 Jul 2022 14:09:04.2441 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 8ae927fe-1255-47a7-a2af-5f3a069daaa2 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: Cs6M/irsHavNSuKcjZ/lngF7rJrHn8m1/uVPZ0FyqE3aX0JOVfHRBgYGxN51S+RW X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR15MB4256 X-Proofpoint-GUID: lEf015fXqgCGuSEtYHojfkWyWp_XTlUG X-Proofpoint-ORIG-GUID: lEf015fXqgCGuSEtYHojfkWyWp_XTlUG X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.883,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-07-28_05,2022-07-28_02,2022-06-22_01 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org The cpio handling routines can be useful outside of just initialising the initramfs. Pull the functions into lib/ and all of the static state into a context structure in preparation for enabling the use of this functionality outside of __init code. Signed-off-by: Jonathan McDowell --- v2: - Fix printf format string in populate_initrd_image (kernel test robot, i386 build) - Include in cpio.h (kernel test robot, uml build) --- include/linux/cpio.h | 79 +++++++ init/initramfs.c | 518 ++++--------------------------------------- lib/Makefile | 2 +- lib/cpio.c | 454 +++++++++++++++++++++++++++++++++++++ 4 files changed, 579 insertions(+), 474 deletions(-) create mode 100644 include/linux/cpio.h create mode 100644 lib/cpio.c diff --git a/include/linux/cpio.h b/include/linux/cpio.h new file mode 100644 index 000000000000..2f9fd735331e --- /dev/null +++ b/include/linux/cpio.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_CPIO_H +#define _LINUX_CPIO_H + +#include +#include +#include +#include + +/* Must be a power of 2 */ +#define CPIO_LINK_HASH_SIZE 32 + +#define N_ALIGN(len) ((((len) + 1) & ~3) + 2) + +enum cpio_state { + CPIO_START, + CPIO_COLLECT, + CPIO_GOTHEADER, + CPIO_SKIPIT, + CPIO_GOTNAME, + CPIO_COPYFILE, + CPIO_GOTSYMLINK, + CPIO_RESET +}; + +struct cpio_dir_entry { + struct list_head list; + time64_t mtime; + char name[]; +}; + +struct cpio_link_hash { + int ino, minor, major; + umode_t mode; + struct cpio_link_hash *next; + char name[N_ALIGN(PATH_MAX)]; +}; + +struct cpio_context { + enum cpio_state state, next_state; + char *header_buf, *symlink_buf, *name_buf; + loff_t this_header, next_header; + char *victim; + unsigned long byte_count; + bool csum_present; + u32 io_csum; + char *errmsg; + + char *collected; + long remains; + char *collect; + + struct file *wfile; + loff_t wfile_pos; + + /* Header fields */ + unsigned long ino, major, minor, nlink; + umode_t mode; + unsigned long body_len, name_len; + uid_t uid; + gid_t gid; + unsigned int rdev; + u32 hdr_csum; + time64_t mtime; + + /* Link hash */ + struct cpio_link_hash *link_hash[CPIO_LINK_HASH_SIZE]; + + struct list_head dir_list; +}; + +int __init cpio_start(struct cpio_context *ctx); +void __init cpio_finish(struct cpio_context *ctx); +long __init cpio_write_buffer(struct cpio_context *ctx, char *buf, + unsigned long len); +long __init cpio_process_buffer(struct cpio_context *ctx, void *bufv, + unsigned long len); + +#endif /* _LINUX_CPIO_H */ diff --git a/init/initramfs.c b/init/initramfs.c index 18229cfe8906..00c101d04f4b 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include #include -#include #include #include #include @@ -14,43 +13,9 @@ #include #include #include -#include #include #include - -static __initdata bool csum_present; -static __initdata u32 io_csum; - -static ssize_t __init xwrite(struct file *file, const unsigned char *p, - size_t count, loff_t *pos) -{ - ssize_t out = 0; - - /* sys_write only can write MAX_RW_COUNT aka 2G-4K bytes at most */ - while (count) { - ssize_t rv = kernel_write(file, p, count, pos); - - if (rv < 0) { - if (rv == -EINTR || rv == -EAGAIN) - continue; - return out ? out : rv; - } else if (rv == 0) - break; - - if (csum_present) { - ssize_t i; - - for (i = 0; i < rv; i++) - io_csum += p[i]; - } - - p += rv; - out += rv; - count -= rv; - } - - return out; -} +#include static __initdata char *message; static void __init error(char *x) @@ -69,423 +34,17 @@ static void panic_show_mem(const char *fmt, ...) va_end(args); } -/* link hash */ - -#define N_ALIGN(len) ((((len) + 1) & ~3) + 2) - -static __initdata struct hash { - int ino, minor, major; - umode_t mode; - struct hash *next; - char name[N_ALIGN(PATH_MAX)]; -} *head[32]; - -static inline int hash(int major, int minor, int ino) -{ - unsigned long tmp = ino + minor + (major << 3); - tmp += tmp >> 5; - return tmp & 31; -} - -static char __init *find_link(int major, int minor, int ino, - umode_t mode, char *name) -{ - struct hash **p, *q; - for (p = head + hash(major, minor, ino); *p; p = &(*p)->next) { - if ((*p)->ino != ino) - continue; - if ((*p)->minor != minor) - continue; - if ((*p)->major != major) - continue; - if (((*p)->mode ^ mode) & S_IFMT) - continue; - return (*p)->name; - } - q = kmalloc(sizeof(struct hash), GFP_KERNEL); - if (!q) - panic_show_mem("can't allocate link hash entry"); - q->major = major; - q->minor = minor; - q->ino = ino; - q->mode = mode; - strcpy(q->name, name); - q->next = NULL; - *p = q; - return NULL; -} - -static void __init free_hash(void) -{ - struct hash **p, *q; - for (p = head; p < head + 32; p++) { - while (*p) { - q = *p; - *p = q->next; - kfree(q); - } - } -} - -#ifdef CONFIG_INITRAMFS_PRESERVE_MTIME -static void __init do_utime(char *filename, time64_t mtime) -{ - struct timespec64 t[2] = { { .tv_sec = mtime }, { .tv_sec = mtime } }; - init_utimes(filename, t); -} - -static void __init do_utime_path(const struct path *path, time64_t mtime) -{ - struct timespec64 t[2] = { { .tv_sec = mtime }, { .tv_sec = mtime } }; - vfs_utimes(path, t); -} - -static __initdata LIST_HEAD(dir_list); -struct dir_entry { - struct list_head list; - time64_t mtime; - char name[]; -}; - -static void __init dir_add(const char *name, time64_t mtime) -{ - size_t nlen = strlen(name) + 1; - struct dir_entry *de; - - de = kmalloc(sizeof(struct dir_entry) + nlen, GFP_KERNEL); - if (!de) - panic_show_mem("can't allocate dir_entry buffer"); - INIT_LIST_HEAD(&de->list); - strscpy(de->name, name, nlen); - de->mtime = mtime; - list_add(&de->list, &dir_list); -} - -static void __init dir_utime(void) -{ - struct dir_entry *de, *tmp; - list_for_each_entry_safe(de, tmp, &dir_list, list) { - list_del(&de->list); - do_utime(de->name, de->mtime); - kfree(de); - } -} -#else -static void __init do_utime(char *filename, time64_t mtime) {} -static void __init do_utime_path(const struct path *path, time64_t mtime) {} -static void __init dir_add(const char *name, time64_t mtime) {} -static void __init dir_utime(void) {} -#endif - -static __initdata time64_t mtime; - -/* cpio header parsing */ - -static __initdata unsigned long ino, major, minor, nlink; -static __initdata umode_t mode; -static __initdata unsigned long body_len, name_len; -static __initdata uid_t uid; -static __initdata gid_t gid; -static __initdata unsigned rdev; -static __initdata u32 hdr_csum; - -static void __init parse_header(char *s) -{ - unsigned long parsed[13]; - char buf[9]; - int i; - - buf[8] = '\0'; - for (i = 0, s += 6; i < 13; i++, s += 8) { - memcpy(buf, s, 8); - parsed[i] = simple_strtoul(buf, NULL, 16); - } - ino = parsed[0]; - mode = parsed[1]; - uid = parsed[2]; - gid = parsed[3]; - nlink = parsed[4]; - mtime = parsed[5]; /* breaks in y2106 */ - body_len = parsed[6]; - major = parsed[7]; - minor = parsed[8]; - rdev = new_encode_dev(MKDEV(parsed[9], parsed[10])); - name_len = parsed[11]; - hdr_csum = parsed[12]; -} - -/* FSM */ - -static __initdata enum state { - Start, - Collect, - GotHeader, - SkipIt, - GotName, - CopyFile, - GotSymlink, - Reset -} state, next_state; - -static __initdata char *victim; -static unsigned long byte_count __initdata; -static __initdata loff_t this_header, next_header; - -static inline void __init eat(unsigned n) -{ - victim += n; - this_header += n; - byte_count -= n; -} - -static __initdata char *collected; -static long remains __initdata; -static __initdata char *collect; - -static void __init read_into(char *buf, unsigned size, enum state next) -{ - if (byte_count >= size) { - collected = victim; - eat(size); - state = next; - } else { - collect = collected = buf; - remains = size; - next_state = next; - state = Collect; - } -} - -static __initdata char *header_buf, *symlink_buf, *name_buf; - -static int __init do_start(void) -{ - read_into(header_buf, 110, GotHeader); - return 0; -} - -static int __init do_collect(void) -{ - unsigned long n = remains; - if (byte_count < n) - n = byte_count; - memcpy(collect, victim, n); - eat(n); - collect += n; - if ((remains -= n) != 0) - return 1; - state = next_state; - return 0; -} - -static int __init do_header(void) -{ - if (!memcmp(collected, "070701", 6)) { - csum_present = false; - } else if (!memcmp(collected, "070702", 6)) { - csum_present = true; - } else { - if (memcmp(collected, "070707", 6) == 0) - error("incorrect cpio method used: use -H newc option"); - else - error("no cpio magic"); - return 1; - } - parse_header(collected); - next_header = this_header + N_ALIGN(name_len) + body_len; - next_header = (next_header + 3) & ~3; - state = SkipIt; - if (name_len <= 0 || name_len > PATH_MAX) - return 0; - if (S_ISLNK(mode)) { - if (body_len > PATH_MAX) - return 0; - collect = collected = symlink_buf; - remains = N_ALIGN(name_len) + body_len; - next_state = GotSymlink; - state = Collect; - return 0; - } - if (S_ISREG(mode) || !body_len) - read_into(name_buf, N_ALIGN(name_len), GotName); - return 0; -} - -static int __init do_skip(void) -{ - if (this_header + byte_count < next_header) { - eat(byte_count); - return 1; - } else { - eat(next_header - this_header); - state = next_state; - return 0; - } -} - -static int __init do_reset(void) -{ - while (byte_count && *victim == '\0') - eat(1); - if (byte_count && (this_header & 3)) - error("broken padding"); - return 1; -} - -static void __init clean_path(char *path, umode_t fmode) -{ - struct kstat st; - - if (!init_stat(path, &st, AT_SYMLINK_NOFOLLOW) && - (st.mode ^ fmode) & S_IFMT) { - if (S_ISDIR(st.mode)) - init_rmdir(path); - else - init_unlink(path); - } -} - -static int __init maybe_link(void) -{ - if (nlink >= 2) { - char *old = find_link(major, minor, ino, mode, collected); - if (old) { - clean_path(collected, 0); - return (init_link(old, collected) < 0) ? -1 : 1; - } - } - return 0; -} - -static __initdata struct file *wfile; -static __initdata loff_t wfile_pos; - -static int __init do_name(void) -{ - state = SkipIt; - next_state = Reset; - if (strcmp(collected, "TRAILER!!!") == 0) { - free_hash(); - return 0; - } - clean_path(collected, mode); - if (S_ISREG(mode)) { - int ml = maybe_link(); - if (ml >= 0) { - int openflags = O_WRONLY|O_CREAT; - if (ml != 1) - openflags |= O_TRUNC; - wfile = filp_open(collected, openflags, mode); - if (IS_ERR(wfile)) - return 0; - wfile_pos = 0; - io_csum = 0; - - vfs_fchown(wfile, uid, gid); - vfs_fchmod(wfile, mode); - if (body_len) - vfs_truncate(&wfile->f_path, body_len); - state = CopyFile; - } - } else if (S_ISDIR(mode)) { - init_mkdir(collected, mode); - init_chown(collected, uid, gid, 0); - init_chmod(collected, mode); - dir_add(collected, mtime); - } else if (S_ISBLK(mode) || S_ISCHR(mode) || - S_ISFIFO(mode) || S_ISSOCK(mode)) { - if (maybe_link() == 0) { - init_mknod(collected, mode, rdev); - init_chown(collected, uid, gid, 0); - init_chmod(collected, mode); - do_utime(collected, mtime); - } - } - return 0; -} +static unsigned long my_inptr; /* index of next byte to be processed in inbuf */ -static int __init do_copy(void) -{ - if (byte_count >= body_len) { - if (xwrite(wfile, victim, body_len, &wfile_pos) != body_len) - error("write error"); - - do_utime_path(&wfile->f_path, mtime); - fput(wfile); - if (csum_present && io_csum != hdr_csum) - error("bad data checksum"); - eat(body_len); - state = SkipIt; - return 0; - } else { - if (xwrite(wfile, victim, byte_count, &wfile_pos) != byte_count) - error("write error"); - body_len -= byte_count; - eat(byte_count); - return 1; - } -} +#include -static int __init do_symlink(void) -{ - collected[N_ALIGN(name_len) + body_len] = '\0'; - clean_path(collected, 0); - init_symlink(collected + N_ALIGN(name_len), collected); - init_chown(collected, uid, gid, AT_SYMLINK_NOFOLLOW); - do_utime(collected, mtime); - state = SkipIt; - next_state = Reset; - return 0; -} +static struct cpio_context ctx __initdata; -static __initdata int (*actions[])(void) = { - [Start] = do_start, - [Collect] = do_collect, - [GotHeader] = do_header, - [SkipIt] = do_skip, - [GotName] = do_name, - [CopyFile] = do_copy, - [GotSymlink] = do_symlink, - [Reset] = do_reset, -}; - -static long __init write_buffer(char *buf, unsigned long len) +static long __init process_buffer(void *bufv, unsigned long len) { - byte_count = len; - victim = buf; - - while (!actions[state]()) - ; - return len - byte_count; + return cpio_process_buffer(&ctx, bufv, len); } -static long __init flush_buffer(void *bufv, unsigned long len) -{ - char *buf = (char *) bufv; - long written; - long origLen = len; - if (message) - return -1; - while ((written = write_buffer(buf, len)) < len && !message) { - char c = buf[written]; - if (c == '0') { - buf += written; - len -= written; - state = Start; - } else if (c == 0) { - buf += written; - len -= written; - state = Reset; - } else - error("junk within compressed archive"); - } - return origLen; -} - -static unsigned long my_inptr; /* index of next byte to be processed in inbuf */ - -#include - static char * __init unpack_to_rootfs(char *buf, unsigned long len) { long written; @@ -493,36 +52,34 @@ static char * __init unpack_to_rootfs(char *buf, unsigned long len) const char *compress_name; static __initdata char msg_buf[64]; - header_buf = kmalloc(110, GFP_KERNEL); - symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL); - name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL); - - if (!header_buf || !symlink_buf || !name_buf) + if (cpio_start(&ctx)) panic_show_mem("can't allocate buffers"); - state = Start; - this_header = 0; message = NULL; while (!message && len) { - loff_t saved_offset = this_header; - if (*buf == '0' && !(this_header & 3)) { - state = Start; - written = write_buffer(buf, len); + loff_t saved_offset = ctx.this_header; + + if (*buf == '0' && !(ctx.this_header & 3)) { + ctx.state = CPIO_START; + written = cpio_write_buffer(&ctx, buf, len); buf += written; len -= written; + if (ctx.errmsg) + message = ctx.errmsg; continue; } if (!*buf) { buf++; len--; - this_header++; + ctx.this_header++; continue; } - this_header = 0; + ctx.this_header = 0; decompress = decompress_method(buf, len, &compress_name); pr_debug("Detected %s compressed data\n", compress_name); if (decompress) { - int res = decompress(buf, len, NULL, flush_buffer, NULL, + int res = decompress(buf, len, NULL, + process_buffer, NULL, &my_inptr, error); if (res) error("decompressor failed"); @@ -535,16 +92,13 @@ static char * __init unpack_to_rootfs(char *buf, unsigned long len) } } else error("invalid magic at start of compressed archive"); - if (state != Reset) + if (ctx.state != CPIO_RESET) error("junk at the end of compressed archive"); - this_header = saved_offset + my_inptr; + ctx.this_header = saved_offset + my_inptr; buf += my_inptr; len -= my_inptr; } - dir_utime(); - kfree(name_buf); - kfree(symlink_buf); - kfree(header_buf); + cpio_finish(&ctx); return message; } @@ -672,9 +226,11 @@ static inline bool kexec_free_initrd(void) #ifdef CONFIG_BLK_DEV_RAM static void __init populate_initrd_image(char *err) { - ssize_t written; struct file *file; + unsigned char *p; + ssize_t written; loff_t pos = 0; + size_t count; unpack_to_rootfs(__initramfs_start, __initramfs_size); @@ -684,11 +240,27 @@ static void __init populate_initrd_image(char *err) if (IS_ERR(file)) return; - written = xwrite(file, (char *)initrd_start, initrd_end - initrd_start, - &pos); - if (written != initrd_end - initrd_start) - pr_err("/initrd.image: incomplete write (%zd != %ld)\n", - written, initrd_end - initrd_start); + count = initrd_end - initrd_start; + p = (char *)initrd_start; + while (count) { + written = kernel_write(file, p, count, &pos); + + if (written < 0) { + if (written == -EINTR || written == -EAGAIN) + continue; + break; + } else if (written == 0) { + break; + } + + p += written; + count -= written; + } + + if (count != 0) + pr_err("/initrd.image: incomplete write (%ld != %ld)\n", + (initrd_end - initrd_start) - count, + initrd_end - initrd_start); fput(file); } #endif /* CONFIG_BLK_DEV_RAM */ diff --git a/lib/Makefile b/lib/Makefile index f99bf61f8bbc..8db946deb71c 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -34,7 +34,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \ is_single_threaded.o plist.o decompress.o kobject_uevent.o \ earlycpio.o seq_buf.o siphash.o dec_and_lock.o \ nmi_backtrace.o nodemask.o win_minmax.o memcat_p.o \ - buildid.o + buildid.o cpio.o lib-$(CONFIG_PRINTK) += dump_stack.o lib-$(CONFIG_SMP) += cpumask.o diff --git a/lib/cpio.c b/lib/cpio.c new file mode 100644 index 000000000000..c71bebd4cc98 --- /dev/null +++ b/lib/cpio.c @@ -0,0 +1,454 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include +#include + +static ssize_t __init xwrite(struct cpio_context *ctx, struct file *file, + const unsigned char *p, size_t count, loff_t *pos) +{ + ssize_t out = 0; + + /* sys_write only can write MAX_RW_COUNT aka 2G-4K bytes at most */ + while (count) { + ssize_t rv = kernel_write(file, p, count, pos); + + if (rv < 0) { + if (rv == -EINTR || rv == -EAGAIN) + continue; + return out ? out : rv; + } else if (rv == 0) { + break; + } + + if (ctx->csum_present) { + ssize_t i; + + for (i = 0; i < rv; i++) + ctx->io_csum += p[i]; + } + + p += rv; + out += rv; + count -= rv; + } + + return out; +} + +/* link hash */ + +static inline int hash(int major, int minor, int ino) +{ + unsigned long tmp = ino + minor + (major << 3); + + tmp += tmp >> 5; + return tmp & (CPIO_LINK_HASH_SIZE - 1); +} + +static char __init *find_link(struct cpio_context *ctx, int major, int minor, + int ino, umode_t mode, char *name) +{ + struct cpio_link_hash **p, *q; + + for (p = ctx->link_hash + hash(major, minor, ino); *p; p = &(*p)->next) { + if ((*p)->ino != ino) + continue; + if ((*p)->minor != minor) + continue; + if ((*p)->major != major) + continue; + if (((*p)->mode ^ mode) & S_IFMT) + continue; + return (*p)->name; + } + q = kmalloc(sizeof(*q), GFP_KERNEL); + if (!q) + return ERR_PTR(-ENOMEM); + q->major = major; + q->minor = minor; + q->ino = ino; + q->mode = mode; + strcpy(q->name, name); + q->next = NULL; + *p = q; + return NULL; +} + +static void __init free_hash(struct cpio_context *ctx) +{ + struct cpio_link_hash **p, *q; + + for (p = ctx->link_hash; p < ctx->link_hash + CPIO_LINK_HASH_SIZE; p++) { + while (*p) { + q = *p; + *p = q->next; + kfree(q); + } + } +} + +#ifdef CONFIG_INITRAMFS_PRESERVE_MTIME +static void __init do_utime(char *filename, time64_t mtime) +{ + struct timespec64 t[2] = { { .tv_sec = mtime }, { .tv_sec = mtime } }; + + init_utimes(filename, t); +} + +static void __init do_utime_path(const struct path *path, time64_t mtime) +{ + struct timespec64 t[2] = { { .tv_sec = mtime }, { .tv_sec = mtime } }; + + vfs_utimes(path, t); +} + +static int __init dir_add(struct cpio_context *ctx, const char *name, time64_t mtime) +{ + size_t nlen = strlen(name) + 1; + struct cpio_dir_entry *de; + + de = kmalloc(sizeof(*de) + nlen, GFP_KERNEL); + if (!de) + return -ENOMEM; + INIT_LIST_HEAD(&de->list); + strscpy(de->name, name, nlen); + de->mtime = mtime; + list_add(&de->list, &ctx->dir_list); + + return 0; +} + +static void __init dir_utime(struct cpio_context *ctx) +{ + struct cpio_dir_entry *de, *tmp; + + list_for_each_entry_safe(de, tmp, &ctx->dir_list, list) { + list_del(&de->list); + do_utime(de->name, de->mtime); + kfree(de); + } +} +#else +static void __init do_utime(char *filename, time64_t mtime) {} +static void __init do_utime_path(const struct path *path, time64_t mtime) {} +static int __init dir_add(struct cpio_context *ctx, const char *name, time64_t mtime) { return 0; } +static void __init dir_utime(struct cpio_context *ctx) {} +#endif + +/* cpio header parsing */ + +static void __init parse_header(struct cpio_context *ctx, char *s) +{ + unsigned long parsed[13]; + char buf[9]; + int i; + + buf[8] = '\0'; + for (i = 0, s += 6; i < 13; i++, s += 8) { + memcpy(buf, s, 8); + parsed[i] = simple_strtoul(buf, NULL, 16); + } + ctx->ino = parsed[0]; + ctx->mode = parsed[1]; + ctx->uid = parsed[2]; + ctx->gid = parsed[3]; + ctx->nlink = parsed[4]; + ctx->mtime = parsed[5]; /* breaks in y2106 */ + ctx->body_len = parsed[6]; + ctx->major = parsed[7]; + ctx->minor = parsed[8]; + ctx->rdev = new_encode_dev(MKDEV(parsed[9], parsed[10])); + ctx->name_len = parsed[11]; + ctx->hdr_csum = parsed[12]; +} + +/* FSM */ + +static inline void __init eat(struct cpio_context *ctx, unsigned int n) +{ + ctx->victim += n; + ctx->this_header += n; + ctx->byte_count -= n; +} + +static void __init read_into(struct cpio_context *ctx, char *buf, + unsigned int size, enum cpio_state next) +{ + if (ctx->byte_count >= size) { + ctx->collected = ctx->victim; + eat(ctx, size); + ctx->state = next; + } else { + ctx->collect = buf; + ctx->collected = buf; + ctx->remains = size; + ctx->next_state = next; + ctx->state = CPIO_COLLECT; + } +} + +static int __init do_start(struct cpio_context *ctx) +{ + read_into(ctx, ctx->header_buf, 110, CPIO_GOTHEADER); + return 0; +} + +static int __init do_collect(struct cpio_context *ctx) +{ + unsigned long n = ctx->remains; + + if (ctx->byte_count < n) + n = ctx->byte_count; + memcpy(ctx->collect, ctx->victim, n); + eat(ctx, n); + ctx->collect += n; + ctx->remains -= n; + + if (ctx->remains != 0) + return 1; + + ctx->state = ctx->next_state; + return 0; +} + +static int __init do_header(struct cpio_context *ctx) +{ + if (!memcmp(ctx->collected, "070701", 6)) { + ctx->csum_present = false; + } else if (!memcmp(ctx->collected, "070702", 6)) { + ctx->csum_present = true; + } else { + if (memcmp(ctx->collected, "070707", 6) == 0) + ctx->errmsg = "incorrect cpio method used: use -H newc option"; + else + ctx->errmsg = "no cpio magic"; + return 1; + } + parse_header(ctx, ctx->collected); + ctx->next_header = ctx->this_header + N_ALIGN(ctx->name_len) + ctx->body_len; + ctx->next_header = (ctx->next_header + 3) & ~3; + ctx->state = CPIO_SKIPIT; + if (ctx->name_len <= 0 || ctx->name_len > PATH_MAX) + return 0; + if (S_ISLNK(ctx->mode)) { + if (ctx->body_len > PATH_MAX) + return 0; + ctx->collect = ctx->symlink_buf; + ctx->collected = ctx->symlink_buf; + ctx->remains = N_ALIGN(ctx->name_len) + ctx->body_len; + ctx->next_state = CPIO_GOTSYMLINK; + ctx->state = CPIO_COLLECT; + return 0; + } + if (S_ISREG(ctx->mode) || !ctx->body_len) + read_into(ctx, ctx->name_buf, N_ALIGN(ctx->name_len), CPIO_GOTNAME); + return 0; +} + +static int __init do_skip(struct cpio_context *ctx) +{ + if (ctx->this_header + ctx->byte_count < ctx->next_header) { + eat(ctx, ctx->byte_count); + return 1; + } + + eat(ctx, ctx->next_header - ctx->this_header); + ctx->state = ctx->next_state; + return 0; +} + +static int __init do_reset(struct cpio_context *ctx) +{ + while (ctx->byte_count && *ctx->victim == '\0') + eat(ctx, 1); + if (ctx->byte_count && (ctx->this_header & 3)) + ctx->errmsg = "broken padding"; + return 1; +} + +static void __init clean_path(char *path, umode_t fmode) +{ + struct kstat st; + + if (!init_stat(path, &st, AT_SYMLINK_NOFOLLOW) && + (st.mode ^ fmode) & S_IFMT) { + if (S_ISDIR(st.mode)) + init_rmdir(path); + else + init_unlink(path); + } +} + +static int __init maybe_link(struct cpio_context *ctx) +{ + if (ctx->nlink >= 2) { + char *old = find_link(ctx, ctx->major, ctx->minor, ctx->ino, + ctx->mode, ctx->collected); + if (old) { + clean_path(ctx->collected, 0); + return (init_link(old, ctx->collected) < 0) ? -1 : 1; + } + } + return 0; +} + +static int __init do_name(struct cpio_context *ctx) +{ + ctx->state = CPIO_SKIPIT; + ctx->next_state = CPIO_RESET; + if (strcmp(ctx->collected, "TRAILER!!!") == 0) { + free_hash(ctx); + return 0; + } + clean_path(ctx->collected, ctx->mode); + if (S_ISREG(ctx->mode)) { + int ml = maybe_link(ctx); + + if (ml >= 0) { + int openflags = O_WRONLY | O_CREAT; + + if (ml != 1) + openflags |= O_TRUNC; + ctx->wfile = filp_open(ctx->collected, openflags, ctx->mode); + if (IS_ERR(ctx->wfile)) + return 0; + ctx->wfile_pos = 0; + ctx->io_csum = 0; + + vfs_fchown(ctx->wfile, ctx->uid, ctx->gid); + vfs_fchmod(ctx->wfile, ctx->mode); + if (ctx->body_len) + vfs_truncate(&ctx->wfile->f_path, ctx->body_len); + ctx->state = CPIO_COPYFILE; + } + } else if (S_ISDIR(ctx->mode)) { + init_mkdir(ctx->collected, ctx->mode); + init_chown(ctx->collected, ctx->uid, ctx->gid, 0); + init_chmod(ctx->collected, ctx->mode); + dir_add(ctx, ctx->collected, ctx->mtime); + } else if (S_ISBLK(ctx->mode) || S_ISCHR(ctx->mode) || + S_ISFIFO(ctx->mode) || S_ISSOCK(ctx->mode)) { + if (maybe_link(ctx) == 0) { + init_mknod(ctx->collected, ctx->mode, ctx->rdev); + init_chown(ctx->collected, ctx->uid, ctx->gid, 0); + init_chmod(ctx->collected, ctx->mode); + do_utime(ctx->collected, ctx->mtime); + } + } + return 0; +} + +static int __init do_copy(struct cpio_context *ctx) +{ + if (ctx->byte_count >= ctx->body_len) { + if (xwrite(ctx, ctx->wfile, ctx->victim, ctx->body_len, + &ctx->wfile_pos) != ctx->body_len) + ctx->errmsg = "write error"; + + do_utime_path(&ctx->wfile->f_path, ctx->mtime); + fput(ctx->wfile); + if (ctx->csum_present && ctx->io_csum != ctx->hdr_csum) + ctx->errmsg = "bad data checksum"; + eat(ctx, ctx->body_len); + ctx->state = CPIO_SKIPIT; + return 0; + } + + if (xwrite(ctx, ctx->wfile, ctx->victim, ctx->byte_count, + &ctx->wfile_pos) != ctx->byte_count) + ctx->errmsg = "write error"; + ctx->body_len -= ctx->byte_count; + eat(ctx, ctx->byte_count); + return 1; +} + +static int __init do_symlink(struct cpio_context *ctx) +{ + ctx->collected[N_ALIGN(ctx->name_len) + ctx->body_len] = '\0'; + clean_path(ctx->collected, 0); + init_symlink(ctx->collected + N_ALIGN(ctx->name_len), ctx->collected); + init_chown(ctx->collected, ctx->uid, ctx->gid, AT_SYMLINK_NOFOLLOW); + do_utime(ctx->collected, ctx->mtime); + ctx->state = CPIO_SKIPIT; + ctx->next_state = CPIO_RESET; + return 0; +} + +static __initdata int (*actions[])(struct cpio_context *) = { + [CPIO_START] = do_start, + [CPIO_COLLECT] = do_collect, + [CPIO_GOTHEADER] = do_header, + [CPIO_SKIPIT] = do_skip, + [CPIO_GOTNAME] = do_name, + [CPIO_COPYFILE] = do_copy, + [CPIO_GOTSYMLINK] = do_symlink, + [CPIO_RESET] = do_reset, +}; + +long __init cpio_write_buffer(struct cpio_context *ctx, char *buf, + unsigned long len) +{ + ctx->byte_count = len; + ctx->victim = buf; + + while (!actions[ctx->state](ctx)) + ; + return len - ctx->byte_count; +} + +long __init cpio_process_buffer(struct cpio_context *ctx, void *bufv, + unsigned long len) +{ + char *buf = (char *)bufv; + long written; + long left = len; + + if (ctx->errmsg) + return -1; + + while ((written = cpio_write_buffer(ctx, buf, left)) < left && !ctx->errmsg) { + char c = buf[written]; + + if (c == '0') { + buf += written; + left -= written; + ctx->state = CPIO_START; + } else if (c == 0) { + buf += written; + left -= written; + ctx->state = CPIO_RESET; + } else { + ctx->errmsg = "junk within compressed archive"; + } + } + + return len; +} + +int __init cpio_start(struct cpio_context *ctx) +{ + ctx->header_buf = kmalloc(110, GFP_KERNEL); + ctx->symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL); + ctx->name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL); + + if (!ctx->header_buf || !ctx->symlink_buf || !ctx->name_buf) + return -ENOMEM; + + ctx->state = CPIO_START; + ctx->this_header = 0; + INIT_LIST_HEAD(&ctx->dir_list); + + return 0; +} + +void __init cpio_finish(struct cpio_context *ctx) +{ + dir_utime(ctx); + kfree(ctx->name_buf); + kfree(ctx->symlink_buf); + kfree(ctx->header_buf); +} From patchwork Thu Jul 28 14:09:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan McDowell X-Patchwork-Id: 12931335 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 98AB0C19F2D for ; Thu, 28 Jul 2022 14:09:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230150AbiG1OJZ (ORCPT ); Thu, 28 Jul 2022 10:09:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38088 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230049AbiG1OJS (ORCPT ); Thu, 28 Jul 2022 10:09:18 -0400 Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 73C11222AD; Thu, 28 Jul 2022 07:09:17 -0700 (PDT) Received: from pps.filterd (m0044012.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 26SDKdrT005372; Thu, 28 Jul 2022 07:09:17 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=from : to : cc : subject : date : message-id : references : in-reply-to : content-type : content-id : mime-version; s=facebook; bh=4CZ1hZn2cbkt7i9J+NMQpIdxxO0FwrubGh36izgjG4E=; b=XJPDQmukAr8gN9WyMQicItDFKbbIVPeGC/kAzFD/QzViq76QnU4MenTC/AhUkSu6GigH iWzKr3RhaKPZ9lePqCv/OibMPv8ze8r9EGn0Lksrso0ojfzALDLDULLSg2Wg8P6Wd6Ya OaW564wsl68XmhpV+ed74EX4N+eqazyMZDs= Received: from nam12-bn8-obe.outbound.protection.outlook.com (mail-bn8nam12lp2170.outbound.protection.outlook.com [104.47.55.170]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3hks0ps38f-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 28 Jul 2022 07:09:16 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=gqOPwDAXyJf9aqv4JqCNpB1cAKA/3i0xtcEcbdR+EunEB0kuB9Fna61VxlUTAntPT6fOqP6RAYTJvni18rKR4U/bbEjsZv8zJ/GLzdpYmhrKLDYiQ6Gvk8Ni8Ftaa9zdwVnLfqVY0m2K43i1IFLD/C4yYREDztNe9xYGnjrvDPAtwqdC88J/8mVtWAJ4BV7JZeXYMQSGf8ih8vhbyU0+IGfIafQGZJ0Dq4co+0RH//FKiluAf5QMmMmd/XywuFhEF6qHVE5AOZTjK8pwBY6cU5TeHA0/oSQSllRPgT+dJN/U7zoDIKmnK8xuOV0deU/eIle/Xez1LRc9KR17juv6pg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=4CZ1hZn2cbkt7i9J+NMQpIdxxO0FwrubGh36izgjG4E=; b=YAestAJ84w59bPkO7O46rWepRkb1Vv6lHxzg8GvdaN+vnX9Go9cpiniwsHsaYzD2eDkhJJ3xJr6zfcERwnQkgx2BZaBRCIg5zaHerPydOLRLEBcVtyJcSaIKA/waoJaxx5OsWa8s8L+S7cuYqxcSeu62juYDNJ3aTn1OHzYhH+iK8IOnpKTqsePqxySuCijtL5oyPqYXX1dpxHxaYgAPlRqOen1JnGx00+L3COdU0jw6cdVikhqdJgYbk+R6jtwH0Z3A/pdCdihiqg5UNkdzrPo7Pf+mTftZFnQ4RyTZIOeuS7DCk5crFqxaRtJBgEbb6jEaxye+FC00Oedw8Dyn/Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=fb.com; dmarc=pass action=none header.from=fb.com; dkim=pass header.d=fb.com; arc=none Received: from SJ0PR15MB4552.namprd15.prod.outlook.com (2603:10b6:a03:379::12) by MN2PR15MB4256.namprd15.prod.outlook.com (2603:10b6:208:fe::25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5458.25; Thu, 28 Jul 2022 14:09:12 +0000 Received: from SJ0PR15MB4552.namprd15.prod.outlook.com ([fe80::81f9:c21c:c5bf:e174]) by SJ0PR15MB4552.namprd15.prod.outlook.com ([fe80::81f9:c21c:c5bf:e174%8]) with mapi id 15.20.5458.025; Thu, 28 Jul 2022 14:09:12 +0000 From: Jonathan McDowell To: "linux-kernel@vger.kernel.org" , "linux-fsdevel@vger.kernel.org" , "linux-integrity@vger.kernel.org" , "linux-security-module@vger.kernel.org" CC: Alexander Viro , Mimi Zohar , Dmitry Kasatkin , James Morris , "Serge E. Hallyn" , Matthew Garrett , Dmitrii Potoskuev Subject: [RFC PATCH v2 2/7] lib/cpio: Improve error handling Thread-Topic: [RFC PATCH v2 2/7] lib/cpio: Improve error handling Thread-Index: AQHYooucwp+PEgLZlU+UDY/xIbZ3dA== Date: Thu, 28 Jul 2022 14:09:12 +0000 Message-ID: References: In-Reply-To: Accept-Language: en-GB, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 1781041f-13c8-42ae-7160-08da70a2bf41 x-ms-traffictypediagnostic: MN2PR15MB4256:EE_ x-fb-source: Internal x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: nDBlBD0ZAeQkzMTvVW2VIIs21A/TNqigbzdu2RQW++bWB1Qzk6GQvyp701FYpnK5oRQr99rPQO/JqPsTJy/bb2zhEwuZd/hzXOSS47GJgA3mIHCXID80Acgo7BjPr8NVfPrOmOC1VcG7ZE1pFkjs6OzvfadDI2NPE4fxS+K4qX46PEj5P6NWAOBgcjYbKJrCCk1+64EVkjwo7t/Gl+lA6PY3OWpjKeTrfOjbf+EChhqwZ2+0XeAS8jMwExWiZatWSwn9zbE0DgM3A7n+3uPONlFYuC7Bpd1M/zYMQmxDREW0vrAZX+g8vCbtDYl83gynEvyBaO5QdDFj1R3A9vMjgnWQYmUhdfCL1AknC0wHfikqbHmHTOQwyHmwJi36l6Kg7giUIWIfVEZ1mtQGpf6X+5CuquEU8NY/C0Fmj2/UpOPTCs1vS6aYvY5cFQK76qMzXSUA4lfPV9G2ZdBw+pLzNO+PnBkkAsRwcVe9SBUVKZ+FjZedL+BJERxaSNKswdif+4EVrJgsmf8bVv5bgN+muk9CywyzPgciqBWeDxLn9doTROlt2iWRhS9NT/HO6YoodWG2Dh+2WGBFGJxjw3LkKoHNwPMkHb67CXVU7hGCcxUSvY8342NKdH9byGj45tElL8BWsA8bRmm7hwoyOW1bllTua+eFMfBLu0FfcYHPQhqjxl81qeCfTT3xp7+cQgdoMeWvSwYpA5PGRAhh15edlT1znAPXAv59x6cfu17q9nTezl11EYhJSKECFoBUUEAzyQ5BI9+xCdM4GKkuil9t9vAbkx3zJDqQN64wD4FWNRf+Ko+XjeT7Lrfig0rDY6lt x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SJ0PR15MB4552.namprd15.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230016)(4636009)(346002)(376002)(366004)(136003)(39860400002)(396003)(7416002)(2616005)(2906002)(478600001)(122000001)(41300700001)(6506007)(86362001)(316002)(36756003)(186003)(5660300002)(38070700005)(38100700002)(66476007)(4326008)(83380400001)(6486002)(6512007)(91956017)(110136005)(54906003)(26005)(71200400001)(76116006)(66946007)(8676002)(8936002)(64756008)(66556008)(66446008);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: RKhrI78mQM3liZfyitw56Kwcc08hUDhHoIOQhDHD3lSqyLp9S5iBFHzXylBazexj5Ai8YYjDcBBks24PQg4S0ti5QVFGjj923xGBFvzvrsq/2et058CJ+411tqvPXUp1QWrMEUQp86T/kWdMxLMQ7uKieFB2zbWyGikXE6jcbdkcsj280YEUq+jTbsImbqxeEyXsk0uumPjYYyy/C/dY2WsJQZlQtImhFbjVTXWX00mqMeDZ+kP9ml+gJeBl+/KkUh8o07pOp/Th/7yt+ftMQV0ubwI1GEWJvaMgrY+AXAE+aml6HXivpZrBhG2Wa2VVVadGLueEGSwf5Z3Y4mew9zKONkt50eFtN6m4bh3W/+ZRTRT+eEtIWz39EqQl8Ekh+XUdlH5VqC8ojWl2dm1gDFiEyxdqftI543VoTWXgaemjzi5wGzPmuGqLcHTT7V4BXU6jkwxhDggV7IiSktGuKM0P016neg1Xx3qBUIq/o7CEqMrEE7wj9Lk824EXOsa06uvCuSQ7ckrubhsn+ocRXkGH2DtklpaUGrPZLaIWVsvaKofUY7otKCo5Iq7GkQaALBIWakLI09RQdBWck13ZEywk+6s1qTdLLznKgpgpLXYQOsc0GcXNGzpc1FKWWAJ0X1uQqtr3+j1Mgjw6gJFNUKulewmN7NHmtpx3VmlZF5MAYpTH2r5zdFHADJrtTWTwSeS/qsW/5VBndPED4WmWgwNNZnkmckOnEoWsC2ROWWzDr4+PwkVF4jdGxq/zgYPZEB84NDY+fHVIH8mTy9Z67XWIKpFh1uwfP5++aI5F5AFkouXTyfSQgfvhX7i5m7ry4x0iGnP+YyyADOYbhvE8RHdxINkf84/4wkskj5siru38J8q4mrSsqrgz/2j5BHMQQgsuW2j9IinqY21Vy/nJFCTxNKm/vZ6t3R6++dTLWngRSW+GHU3RxFRns+N2kSK4NM9dX+FUiBxAJcDm3c541ddC9cSWYQH29nYL9upKhakxLVSo+GTsOqUNYh1d+b8PZOYKd+E0diXtlLEUa5Xgl9mkKAQSDEz5qCbVjPYblzFiDCV52Lcn8rDSdaPBTeU88TNG3ikGTV4pZa2SPhLcSyKEIzdW07VVEXQwDm+LpSqBtHVKMnbkFpriSetMqg/INMn+8FD0dO3aqiOo7fV1oMk5w6FA4vH6AvRbpOaMpmE3UQugUcz+Ki2BCcgif6yNFRFTYe6bsqRCenmKc2PPLmhucB1XbgzVQsahGmIzUAxMgcEubtqOwgK/Qa0MApcrN8gHApTlqkVH7p4/JiH6M+SW7iP+e2vBDAsYecRnZbMWJAkwaC3gdNO8UTzq1EnXqfIz226nywu9hJmj7+jGedpPNo6ibtnFZpRZyAPv9co3X51NHZNa1xv+cAMkXkI+9JEdCQDSCWbpB7NixQzXopVtPS+WO9eSHW2qOE3UuWfJONljVZb05T4Jgq9QX/w/zp2KrunYwah1V4aILQrov+EFudpi8T+5VVAq9AvUiTG5z+lWczCFHIKQ0QfTqJKk5BOrXCgys6wQUzdQBwLOoMm7WbiasTs+egNJQC6n7zxBRedOCyrEuq/c0nLRVJoS Content-ID: <57B1A3003B6BC645847C0278A259714B@namprd15.prod.outlook.com> MIME-Version: 1.0 X-OriginatorOrg: fb.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: SJ0PR15MB4552.namprd15.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1781041f-13c8-42ae-7160-08da70a2bf41 X-MS-Exchange-CrossTenant-originalarrivaltime: 28 Jul 2022 14:09:12.1784 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 8ae927fe-1255-47a7-a2af-5f3a069daaa2 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: G1dM+25bc+EbZ4EfZUTcFMujTVBLzV+TblRx/krICe4gS/ht43MvCGlwwBUrhF68 X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR15MB4256 X-Proofpoint-GUID: ghVbqN44zCxuA6Sli_WTQJnW_C2DVTxi X-Proofpoint-ORIG-GUID: ghVbqN44zCxuA6Sli_WTQJnW_C2DVTxi X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.883,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-07-28_05,2022-07-28_02,2022-06-22_01 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org As preparation for making the cpio parsing routines more generally available improve the error handling such that we pass back a suitable errno rather than a string message, and correctly exit execution when such an error is raised. Signed-off-by: Jonathan McDowell --- include/linux/cpio.h | 1 - init/initramfs.c | 10 ++++++-- lib/cpio.c | 56 +++++++++++++++++++++++++++----------------- 3 files changed, 43 insertions(+), 24 deletions(-) diff --git a/include/linux/cpio.h b/include/linux/cpio.h index 2f9fd735331e..69a15fffa5c6 100644 --- a/include/linux/cpio.h +++ b/include/linux/cpio.h @@ -44,7 +44,6 @@ struct cpio_context { unsigned long byte_count; bool csum_present; u32 io_csum; - char *errmsg; char *collected; long remains; diff --git a/init/initramfs.c b/init/initramfs.c index 00c101d04f4b..79c3a3f42cdb 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -62,10 +62,16 @@ static char * __init unpack_to_rootfs(char *buf, unsigned long len) if (*buf == '0' && !(ctx.this_header & 3)) { ctx.state = CPIO_START; written = cpio_write_buffer(&ctx, buf, len); + + if (written < 0) { + pr_err("Failed to process archive: %ld\n", + written); + error("failed to process archive"); + break; + } + buf += written; len -= written; - if (ctx.errmsg) - message = ctx.errmsg; continue; } if (!*buf) { diff --git a/lib/cpio.c b/lib/cpio.c index c71bebd4cc98..5d150939704f 100644 --- a/lib/cpio.c +++ b/lib/cpio.c @@ -221,12 +221,10 @@ static int __init do_header(struct cpio_context *ctx) ctx->csum_present = false; } else if (!memcmp(ctx->collected, "070702", 6)) { ctx->csum_present = true; + } else if (memcmp(ctx->collected, "070707", 6) == 0) { + return -EPROTONOSUPPORT; } else { - if (memcmp(ctx->collected, "070707", 6) == 0) - ctx->errmsg = "incorrect cpio method used: use -H newc option"; - else - ctx->errmsg = "no cpio magic"; - return 1; + return -EINVAL; } parse_header(ctx, ctx->collected); ctx->next_header = ctx->this_header + N_ALIGN(ctx->name_len) + ctx->body_len; @@ -266,7 +264,8 @@ static int __init do_reset(struct cpio_context *ctx) while (ctx->byte_count && *ctx->victim == '\0') eat(ctx, 1); if (ctx->byte_count && (ctx->this_header & 3)) - ctx->errmsg = "broken padding"; + return -EFAULT; + return 1; } @@ -344,23 +343,29 @@ static int __init do_name(struct cpio_context *ctx) static int __init do_copy(struct cpio_context *ctx) { + int ret; + if (ctx->byte_count >= ctx->body_len) { - if (xwrite(ctx, ctx->wfile, ctx->victim, ctx->body_len, - &ctx->wfile_pos) != ctx->body_len) - ctx->errmsg = "write error"; + ret = xwrite(ctx, ctx->wfile, ctx->victim, ctx->body_len, + &ctx->wfile_pos); + if (ret != ctx->body_len) + return (ret < 0) ? ret : -EIO; do_utime_path(&ctx->wfile->f_path, ctx->mtime); fput(ctx->wfile); if (ctx->csum_present && ctx->io_csum != ctx->hdr_csum) - ctx->errmsg = "bad data checksum"; + return -EBADMSG; + eat(ctx, ctx->body_len); ctx->state = CPIO_SKIPIT; return 0; } - if (xwrite(ctx, ctx->wfile, ctx->victim, ctx->byte_count, - &ctx->wfile_pos) != ctx->byte_count) - ctx->errmsg = "write error"; + ret = xwrite(ctx, ctx->wfile, ctx->victim, ctx->byte_count, + &ctx->wfile_pos); + if (ret != ctx->byte_count) + return (ret < 0) ? ret : -EIO; + ctx->body_len -= ctx->byte_count; eat(ctx, ctx->byte_count); return 1; @@ -392,12 +397,19 @@ static __initdata int (*actions[])(struct cpio_context *) = { long __init cpio_write_buffer(struct cpio_context *ctx, char *buf, unsigned long len) { + int ret; + ctx->byte_count = len; ctx->victim = buf; - while (!actions[ctx->state](ctx)) - ; - return len - ctx->byte_count; + ret = 0; + while (ret == 0) + ret = actions[ctx->state](ctx); + + if (ret < 0) + return ret; + else + return len - ctx->byte_count; } long __init cpio_process_buffer(struct cpio_context *ctx, void *bufv, @@ -407,11 +419,13 @@ long __init cpio_process_buffer(struct cpio_context *ctx, void *bufv, long written; long left = len; - if (ctx->errmsg) - return -1; + while ((written = cpio_write_buffer(ctx, buf, left)) < left) { + char c; + + if (written < 0) + return written; - while ((written = cpio_write_buffer(ctx, buf, left)) < left && !ctx->errmsg) { - char c = buf[written]; + c = buf[written]; if (c == '0') { buf += written; @@ -422,7 +436,7 @@ long __init cpio_process_buffer(struct cpio_context *ctx, void *bufv, left -= written; ctx->state = CPIO_RESET; } else { - ctx->errmsg = "junk within compressed archive"; + return -EINVAL; } } From patchwork Thu Jul 28 14:09:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan McDowell X-Patchwork-Id: 12931336 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DE340C04A68 for ; Thu, 28 Jul 2022 14:10:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230473AbiG1OJ7 (ORCPT ); Thu, 28 Jul 2022 10:09:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38308 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230293AbiG1OJa (ORCPT ); Thu, 28 Jul 2022 10:09:30 -0400 Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A66F95F13C; Thu, 28 Jul 2022 07:09:27 -0700 (PDT) Received: from pps.filterd (m0044012.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 26SD9eEh012416; Thu, 28 Jul 2022 07:09:27 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=from : to : cc : subject : date : message-id : references : in-reply-to : content-type : content-id : mime-version; s=facebook; bh=LEJpDPX/NKMZyfnFH7rB9Ov/WvBAflqmzyE4kZeGnbA=; b=h7w3bpUIdhpC1MrI8L4amecfwzwwL7bzkgvMz86M1ChmRBjvef5+o10z1SNGxwAgO2ZZ KdrV/P0xy7p1y4/YnR7BRGjKp40Tfaf5IYJmiYrMH2ZI9vD4ydfAkthEZKXVKnQHI7Gs 4Xzjni0iPWqEU2U9fwmFDQtxVPSrdNYi4Uc= Received: from nam12-bn8-obe.outbound.protection.outlook.com (mail-bn8nam12lp2168.outbound.protection.outlook.com [104.47.55.168]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3hks0ps39h-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 28 Jul 2022 07:09:27 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=UMh15I2ARfcVSvtIzWFK+6Bo1FyG9NACDA377KpCrqIX4pcj+SYhCOP86p9ZqaBAU0cU9Lw3jF1VhpdxJuaHQMBLdOXUs+SHF2Ljf/jDBHokE10XVdPVewnX5+7QZm6aQzAvgwcKWcWgRNnzUWSlziIUCpNILsC8WlKd4IFshc8tVv9mZymcyhY9il9kykp4E70hkreBQypq+XhE74QUHeklELjyBVCdG6A2mbGFwq8oqVJEEUQzGzYbW02kjp0vB5uAZ+2Rdr5kuBE4UtvGeXMgjvZyrKykuxgnYfrWZhb+zUilNJ9F9MwkrI04DFUhPvJaadx3vlA7Bz7boD2V9g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=LEJpDPX/NKMZyfnFH7rB9Ov/WvBAflqmzyE4kZeGnbA=; b=PXJHcFKEwg/kl4i55bPMb8rJxbRIb72CV/Op0rpJpVjWXaZk/Gg+0PXcdX/v/mFCtKzuZmm6oNTF8GnonVsGYwDzYw0hFwMQZLAoDAYxr2oIISKKxxYYA5SpMDTcbsN73ZZ4z8YUN1Uqhe1aUZJ4715qlVMHAoUqtCkKGfch8Md/nozSvhtzWchLtiAR7ndRiUU72+UstJxLqr6+YvnksRaYetmkxhaehYD4NA3Zz9mWv0ehCSptZaHrRbA8uuHPcITEZiwc0LmEqSk1yXZ1+V1vB7IlXjhBs2gorHCQK3xxfFoaLHZWdSN/f3ech/cEuIyEHX9eCgWh8c2ne8n76Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=fb.com; dmarc=pass action=none header.from=fb.com; dkim=pass header.d=fb.com; arc=none Received: from SJ0PR15MB4552.namprd15.prod.outlook.com (2603:10b6:a03:379::12) by MN2PR15MB4256.namprd15.prod.outlook.com (2603:10b6:208:fe::25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5458.25; Thu, 28 Jul 2022 14:09:22 +0000 Received: from SJ0PR15MB4552.namprd15.prod.outlook.com ([fe80::81f9:c21c:c5bf:e174]) by SJ0PR15MB4552.namprd15.prod.outlook.com ([fe80::81f9:c21c:c5bf:e174%8]) with mapi id 15.20.5458.025; Thu, 28 Jul 2022 14:09:22 +0000 From: Jonathan McDowell To: "linux-kernel@vger.kernel.org" , "linux-fsdevel@vger.kernel.org" , "linux-integrity@vger.kernel.org" , "linux-security-module@vger.kernel.org" CC: Alexander Viro , Mimi Zohar , Dmitry Kasatkin , James Morris , "Serge E. Hallyn" , Matthew Garrett , Dmitrii Potoskuev Subject: [RFC PATCH v2 3/7] lib/cpio: use non __init filesystem related functions Thread-Topic: [RFC PATCH v2 3/7] lib/cpio: use non __init filesystem related functions Thread-Index: AQHYoouisaJ4GxUn7UeGeqD/Ofxiug== Date: Thu, 28 Jul 2022 14:09:22 +0000 Message-ID: <7ad4218faaf60b632329c86b819b4615b6c6f121.1659003817.git.noodles@fb.com> References: In-Reply-To: Accept-Language: en-GB, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 1c73fb1d-f512-4ccb-6375-08da70a2c52e x-ms-traffictypediagnostic: MN2PR15MB4256:EE_ x-fb-source: Internal x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: T3jc76xrcFrCxrpsEG0XtdIaHJH8c6e9RZfxhIHeWNLUMDftZcKWzIa8SSiaM1XZw3mdXNR991bEr7o0bbsNBkq8we862dxwRF3i6HXqz/2sTcsdWN8IkgSM0JjYtTN70DilCDcDOQR6jehskkaW+EQHrJTcYQhesGR18zhlM04Q5vTbU+DSFk4v+GOluJsjUh0b3L8ZSswUOvbYEYQLwHeBHcd+enpNeOBHSzwWo0/ZXKuZSH3d33tzZFcjHGpjwc6G9GhJQMbTZLKU9ksd/bpyEW3YTTzUIvZTOIakpl2rDhROcEdWTyV4nYEQE7SDh32lOnlD5a17vg3MxhrG41NSiAklentOSok56yWdEQ0YPVf6SnpSQT8Uus1KZCTHyo5itemQr53rNEIxJ1zYkJ57Nj+PAflaQWGaGdbsUNSzlaXN/WAZmsWt3eLMScQ0BqxKa7TDd/OqxXlahzjMyH1MXf4e5H/JSKtIjDQOHoJ9gb2NrH8pELL9r8Y225w8wSGD2ZamUbM2YniNdD8t7Fua6oisdSv1fJhPH1lKAr+cY1NqWkVsJYHx0AvLLGVpw2AWBJBz2T1uzDi+w3ykd74cLHMf/vYhba5t3P2GOPqehuCoimrmapjRcUs+yNMw/LLUDZTZnfbXa+7TP9gM8M8eSzumRBvp02lYyl7yPwmGOzskp3hkedk+fp+c8aESmKFCdPj20udzl5cPa3Rx0warnrSdcvGvDnTjhh/3iof6bkIr8BB6034MGaXTXhC1/Xdn+s4xccChUZLaABrvfI2yOuSSw/QyZj6UJh+p1G6BJ3GYxgGtqd6URbJ4gMVY x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SJ0PR15MB4552.namprd15.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230016)(4636009)(346002)(376002)(366004)(136003)(39860400002)(396003)(7416002)(2616005)(2906002)(478600001)(122000001)(41300700001)(6506007)(86362001)(316002)(36756003)(186003)(30864003)(5660300002)(38070700005)(38100700002)(66476007)(4326008)(83380400001)(6486002)(6512007)(91956017)(110136005)(54906003)(26005)(71200400001)(76116006)(66946007)(8676002)(8936002)(64756008)(66556008)(66446008);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: sphL66o7Ulu245zqpYbei+GG7Bx7D3VHiwl0FBvKs4qDM5P0epiPMTNVjnag+1ObL9iYF+Vc4u5ql3ehH0sTHXYk29cA+YGOxv3kDsUz/qJ2wjN5w9w9j9041S98b7qOWqctolbdiSrrRKmUATQwLUUKpnh1hQ5B6kRdNypXADYJIXP0b9fHrjcBbY+QvidxF8ODaPqj4U5ve//4hoLzg1hEpu9FTOuvBegIexpbCuvD6hrj9aUZsrJcxDc9MZFwRUhWZqrCq8DTevrvqyqppGc1z0tkvdqPajZ2Efl4pExvicQnzX4zP9hxE9XsdmzlVG1MSoX3KFv09qzlCIu9sz4h8eBUwjB6L/DZQK5w+f2m3rm4Cd8FdRxEdzDzzo4MLRHQcn7PWWYKuSljc1AmuVTk+xxQByErAjf87QeuaHEoiXafoRNcY5KrdIymFjPyBtOdxru7VOaC5haZpExfcC1DdyALE0pp/Do8YMDcr8XidIJotKpa6ISP1ZekCnkUFn7SvkeaZd/1WqaGmmMr1y9deN00OHoKLCY4auK+hleEDvfxnlD/V1P/fN5wOjiugS9Qb2pjfMtjb/p5CAZF2voMGK0vvP1PqHaO9y5/e4WnfTgC7uA+eY+1JwDv1FIYp2GPEg4Zb5SxkRdcTine7r+/0VMXXrrYTnWqsX9smYK25S/v6F6zx3BxkUtlBv9uEaY44saPLJCrgk/MU1QwuEXpBE6W6ps5nwtZnoFhBWDt9Dwvhvz41pkHCeHMgrEj7jWFN5jCnThkS9IWgsOtW8tmmyKwjpwsVFYLFhAF2HLqub/THnyI+MgEo1QL/o19XVKUhpdRrndegp68DzM5IR8WqnXvOFtJngx7bVJ75llhCImP3E7DhVGwF5u2sLsrOzYOP7zer5uNJcTTEQdk3lgwsMcWJqW1BbtIEd//pJKFx9xTqHWfIVRunOHauGsr21CbEIiNs4wiRXCykdE/F+cDevZHJGsR99WhlIKv06MYk/my5ntOt60WesZAkK4HG8Io875az41S83/vXB0WCgJlecCMSGaKpNjjkrpdnKmw1MQbtqQGfdl0/bc30iUd+B5z3R4Zr/bvsGv4EdN8P7CHle/UO7EFOlvHYn7mJrsXFxHAvY3JcOHPLQjNeKz/JiFmKJEiXEkNaP0c0fHDO8vDqlGiT2YcJMQ0znS5+z3fLHcmngOCryPmSW2FTh/Fdo02bbrC/7Y6KsfVbgon3A96162PWcRD4y80nq9eZVYnUAAGMPTucBtIik6/kvQKimZM+mKbbsFN9piPup4aB+XP7qCUxG885Il2Edyov9RJj9XPngfGJcDQMGYlxvz34C9v0jTwXUoLXpNIlX0yGc23rVKca0B1Qn4y8bDe1+zOdd4L/s41kbjhZ3PwAw6ShUCMzGrIKdA8fmN8rV25uk663dOrv6z5UpGVh0cie6FppRwqK9Ha2ALmU070TAtan9D8ikklacfEVvhg+e/2JZQNyhbBGDdx0jtJ4yWU+OrZQQTOsV6qR5S2Fv/4vbYIfnf8FIV6u0zMVn5GAR8zU4oLzWVDoMtd8PmnnuC3Ys2hzfjO88slAkxAj9cI4KVZ Content-ID: <031C80F7C7EC8447BD5DE89D4840F3A7@namprd15.prod.outlook.com> MIME-Version: 1.0 X-OriginatorOrg: fb.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: SJ0PR15MB4552.namprd15.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1c73fb1d-f512-4ccb-6375-08da70a2c52e X-MS-Exchange-CrossTenant-originalarrivaltime: 28 Jul 2022 14:09:22.1198 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 8ae927fe-1255-47a7-a2af-5f3a069daaa2 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: CwrmjewM7Fe9Q8QvPMOPnzuzKzc8yfs4Fb6+NCd9mPWgkvZd8ocamporaEHNm2Py X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR15MB4256 X-Proofpoint-GUID: r4DCnt7PYt8RzXR1ejLAma---IDrzdq9 X-Proofpoint-ORIG-GUID: r4DCnt7PYt8RzXR1ejLAma---IDrzdq9 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.883,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-07-28_05,2022-07-28_02,2022-06-22_01 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org In preparation for making the cpio functions generally available rather than just at init make sure we're using versions of the filesystem related functions that aren't in the __init section. Remove functions only used by us from fs/init.c while folding into the cpio code directly. Signed-off-by: Jonathan McDowell --- v2: - Fold in directory EEXIST checking from patch 4 - Add EEXIST checking for device nodes (kernel test reboot boot test) --- fs/init.c | 101 --------------------- fs/internal.h | 4 - include/linux/fs.h | 4 + include/linux/init_syscalls.h | 6 -- lib/cpio.c | 162 +++++++++++++++++++++++++++++----- 5 files changed, 145 insertions(+), 132 deletions(-) diff --git a/fs/init.c b/fs/init.c index 5c36adaa9b44..a946ad672dee 100644 --- a/fs/init.c +++ b/fs/init.c @@ -79,37 +79,6 @@ int __init init_chroot(const char *filename) return error; } -int __init init_chown(const char *filename, uid_t user, gid_t group, int flags) -{ - int lookup_flags = (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW; - struct path path; - int error; - - error = kern_path(filename, lookup_flags, &path); - if (error) - return error; - error = mnt_want_write(path.mnt); - if (!error) { - error = chown_common(&path, user, group); - mnt_drop_write(path.mnt); - } - path_put(&path); - return error; -} - -int __init init_chmod(const char *filename, umode_t mode) -{ - struct path path; - int error; - - error = kern_path(filename, LOOKUP_FOLLOW, &path); - if (error) - return error; - error = chmod_common(&path, mode); - path_put(&path); - return error; -} - int __init init_eaccess(const char *filename) { struct path path; @@ -163,58 +132,6 @@ int __init init_mknod(const char *filename, umode_t mode, unsigned int dev) return error; } -int __init init_link(const char *oldname, const char *newname) -{ - struct dentry *new_dentry; - struct path old_path, new_path; - struct user_namespace *mnt_userns; - int error; - - error = kern_path(oldname, 0, &old_path); - if (error) - return error; - - new_dentry = kern_path_create(AT_FDCWD, newname, &new_path, 0); - error = PTR_ERR(new_dentry); - if (IS_ERR(new_dentry)) - goto out; - - error = -EXDEV; - if (old_path.mnt != new_path.mnt) - goto out_dput; - mnt_userns = mnt_user_ns(new_path.mnt); - error = may_linkat(mnt_userns, &old_path); - if (unlikely(error)) - goto out_dput; - error = security_path_link(old_path.dentry, &new_path, new_dentry); - if (error) - goto out_dput; - error = vfs_link(old_path.dentry, mnt_userns, new_path.dentry->d_inode, - new_dentry, NULL); -out_dput: - done_path_create(&new_path, new_dentry); -out: - path_put(&old_path); - return error; -} - -int __init init_symlink(const char *oldname, const char *newname) -{ - struct dentry *dentry; - struct path path; - int error; - - dentry = kern_path_create(AT_FDCWD, newname, &path, 0); - if (IS_ERR(dentry)) - return PTR_ERR(dentry); - error = security_path_symlink(&path, dentry, oldname); - if (!error) - error = vfs_symlink(mnt_user_ns(path.mnt), path.dentry->d_inode, - dentry, oldname); - done_path_create(&path, dentry); - return error; -} - int __init init_unlink(const char *pathname) { return do_unlinkat(AT_FDCWD, getname_kernel(pathname)); @@ -239,24 +156,6 @@ int __init init_mkdir(const char *pathname, umode_t mode) return error; } -int __init init_rmdir(const char *pathname) -{ - return do_rmdir(AT_FDCWD, getname_kernel(pathname)); -} - -int __init init_utimes(char *filename, struct timespec64 *ts) -{ - struct path path; - int error; - - error = kern_path(filename, 0, &path); - if (error) - return error; - error = vfs_utimes(&path, ts); - path_put(&path); - return error; -} - int __init init_dup(struct file *file) { int fd; diff --git a/fs/internal.h b/fs/internal.h index 87e96b9024ce..c57d5f0aa731 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -60,9 +60,6 @@ extern int filename_lookup(int dfd, struct filename *name, unsigned flags, struct path *path, struct path *root); extern int vfs_path_lookup(struct dentry *, struct vfsmount *, const char *, unsigned int, struct path *); -int do_rmdir(int dfd, struct filename *name); -int do_unlinkat(int dfd, struct filename *name); -int may_linkat(struct user_namespace *mnt_userns, struct path *link); int do_renameat2(int olddfd, struct filename *oldname, int newdfd, struct filename *newname, unsigned int flags); int do_mkdirat(int dfd, struct filename *name, umode_t mode); @@ -132,7 +129,6 @@ long do_sys_ftruncate(unsigned int fd, loff_t length, int small); int chmod_common(const struct path *path, umode_t mode); int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group, int flag); -int chown_common(const struct path *path, uid_t user, gid_t group); extern int vfs_open(const struct path *, struct file *); /* diff --git a/include/linux/fs.h b/include/linux/fs.h index 9ad5e3520fae..1cb51a54799b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2636,11 +2636,15 @@ static inline struct file *file_clone_open(struct file *file) return dentry_open(&file->f_path, file->f_flags, file->f_cred); } extern int filp_close(struct file *, fl_owner_t id); +extern int chown_common(const struct path *path, uid_t user, gid_t group); +extern int do_rmdir(int dfd, struct filename *name); +extern int do_unlinkat(int dfd, struct filename *name); extern struct filename *getname_flags(const char __user *, int, int *); extern struct filename *getname_uflags(const char __user *, int); extern struct filename *getname(const char __user *); extern struct filename *getname_kernel(const char *); +extern int may_linkat(struct user_namespace *mnt_userns, struct path *link); extern void putname(struct filename *name); extern int finish_open(struct file *file, struct dentry *dentry, diff --git a/include/linux/init_syscalls.h b/include/linux/init_syscalls.h index 92045d18cbfc..196030cd958d 100644 --- a/include/linux/init_syscalls.h +++ b/include/linux/init_syscalls.h @@ -5,15 +5,9 @@ int __init init_mount(const char *dev_name, const char *dir_name, int __init init_umount(const char *name, int flags); int __init init_chdir(const char *filename); int __init init_chroot(const char *filename); -int __init init_chown(const char *filename, uid_t user, gid_t group, int flags); -int __init init_chmod(const char *filename, umode_t mode); int __init init_eaccess(const char *filename); int __init init_stat(const char *filename, struct kstat *stat, int flags); int __init init_mknod(const char *filename, umode_t mode, unsigned int dev); -int __init init_link(const char *oldname, const char *newname); -int __init init_symlink(const char *oldname, const char *newname); int __init init_unlink(const char *pathname); int __init init_mkdir(const char *pathname, umode_t mode); -int __init init_rmdir(const char *pathname); -int __init init_utimes(char *filename, struct timespec64 *ts); int __init init_dup(struct file *file); diff --git a/lib/cpio.c b/lib/cpio.c index 5d150939704f..9a0120c638db 100644 --- a/lib/cpio.c +++ b/lib/cpio.c @@ -3,8 +3,9 @@ #include #include #include -#include #include +#include +#include #include static ssize_t __init xwrite(struct cpio_context *ctx, struct file *file, @@ -92,18 +93,25 @@ static void __init free_hash(struct cpio_context *ctx) } #ifdef CONFIG_INITRAMFS_PRESERVE_MTIME -static void __init do_utime(char *filename, time64_t mtime) +static void __init do_utime_path(const struct path *path, time64_t mtime) { struct timespec64 t[2] = { { .tv_sec = mtime }, { .tv_sec = mtime } }; - init_utimes(filename, t); + vfs_utimes(path, t); } -static void __init do_utime_path(const struct path *path, time64_t mtime) +static int __init do_utime(char *filename, time64_t mtime) { - struct timespec64 t[2] = { { .tv_sec = mtime }, { .tv_sec = mtime } }; + struct path path; + int error; - vfs_utimes(path, t); + error = kern_path(filename, 0, &path); + if (error) + return error; + do_utime_path(&path, mtime); + path_put(&path); + + return error; } static int __init dir_add(struct cpio_context *ctx, const char *name, time64_t mtime) @@ -133,12 +141,31 @@ static void __init dir_utime(struct cpio_context *ctx) } } #else -static void __init do_utime(char *filename, time64_t mtime) {} +static int __init do_utime(char *filename, time64_t mtime) { return 0; } static void __init do_utime_path(const struct path *path, time64_t mtime) {} static int __init dir_add(struct cpio_context *ctx, const char *name, time64_t mtime) { return 0; } static void __init dir_utime(struct cpio_context *ctx) {} #endif +static int __init cpio_chown(const char *filename, uid_t user, gid_t group, + int flags) +{ + int lookup_flags = (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW; + struct path path; + int error; + + error = kern_path(filename, lookup_flags, &path); + if (error) + return error; + error = mnt_want_write(path.mnt); + if (!error) { + error = chown_common(&path, user, group); + mnt_drop_write(path.mnt); + } + path_put(&path); + return error; +} + /* cpio header parsing */ static void __init parse_header(struct cpio_context *ctx, char *s) @@ -269,27 +296,67 @@ static int __init do_reset(struct cpio_context *ctx) return 1; } -static void __init clean_path(char *path, umode_t fmode) +static void __init clean_path(char *pathname, umode_t fmode) { + struct path path; struct kstat st; + int error; - if (!init_stat(path, &st, AT_SYMLINK_NOFOLLOW) && - (st.mode ^ fmode) & S_IFMT) { + error = kern_path(pathname, 0, &path); + if (error) + return; + error = vfs_getattr(&path, &st, STATX_BASIC_STATS, AT_NO_AUTOMOUNT); + path_put(&path); + if (error) + return; + + if ((st.mode ^ fmode) & S_IFMT) { if (S_ISDIR(st.mode)) - init_rmdir(path); + do_rmdir(AT_FDCWD, getname_kernel(pathname)); else - init_unlink(path); + do_unlinkat(AT_FDCWD, getname_kernel(pathname)); } } static int __init maybe_link(struct cpio_context *ctx) { + struct dentry *new_dentry; + struct path old_path, new_path; + struct user_namespace *mnt_userns; + int error; + if (ctx->nlink >= 2) { char *old = find_link(ctx, ctx->major, ctx->minor, ctx->ino, ctx->mode, ctx->collected); if (old) { clean_path(ctx->collected, 0); - return (init_link(old, ctx->collected) < 0) ? -1 : 1; + + error = kern_path(old, 0, &old_path); + if (error) + return error; + + new_dentry = kern_path_create(AT_FDCWD, ctx->collected, &new_path, 0); + error = PTR_ERR(new_dentry); + if (IS_ERR(new_dentry)) + goto out; + + error = -EXDEV; + if (old_path.mnt != new_path.mnt) + goto out_dput; + mnt_userns = mnt_user_ns(new_path.mnt); + error = may_linkat(mnt_userns, &old_path); + if (unlikely(error)) + goto out_dput; + error = security_path_link(old_path.dentry, &new_path, new_dentry); + if (error) + goto out_dput; + error = vfs_link(old_path.dentry, mnt_userns, new_path.dentry->d_inode, + new_dentry, NULL); +out_dput: + done_path_create(&new_path, new_dentry); +out: + path_put(&old_path); + return (error < 0) ? error : 1; } } return 0; @@ -297,6 +364,10 @@ static int __init maybe_link(struct cpio_context *ctx) static int __init do_name(struct cpio_context *ctx) { + struct dentry *dentry; + struct path path; + int error; + ctx->state = CPIO_SKIPIT; ctx->next_state = CPIO_RESET; if (strcmp(ctx->collected, "TRAILER!!!") == 0) { @@ -325,16 +396,48 @@ static int __init do_name(struct cpio_context *ctx) ctx->state = CPIO_COPYFILE; } } else if (S_ISDIR(ctx->mode)) { - init_mkdir(ctx->collected, ctx->mode); - init_chown(ctx->collected, ctx->uid, ctx->gid, 0); - init_chmod(ctx->collected, ctx->mode); + dentry = kern_path_create(AT_FDCWD, ctx->collected, &path, LOOKUP_DIRECTORY); + + if (!IS_ERR(dentry)) { + error = security_path_mkdir(&path, dentry, ctx->mode); + if (!error) + error = vfs_mkdir(mnt_user_ns(path.mnt), + path.dentry->d_inode, + dentry, ctx->mode); + done_path_create(&path, dentry); + } else { + error = PTR_ERR(dentry); + } + + if (error && error != -EEXIST) + return error; + + cpio_chown(ctx->collected, ctx->uid, ctx->gid, 0); dir_add(ctx, ctx->collected, ctx->mtime); } else if (S_ISBLK(ctx->mode) || S_ISCHR(ctx->mode) || S_ISFIFO(ctx->mode) || S_ISSOCK(ctx->mode)) { if (maybe_link(ctx) == 0) { - init_mknod(ctx->collected, ctx->mode, ctx->rdev); - init_chown(ctx->collected, ctx->uid, ctx->gid, 0); - init_chmod(ctx->collected, ctx->mode); + if (S_ISFIFO(ctx->mode) || S_ISSOCK(ctx->mode)) + ctx->rdev = 0; + + dentry = kern_path_create(AT_FDCWD, ctx->collected, &path, 0); + if (!IS_ERR(dentry)) { + error = security_path_mknod(&path, dentry, ctx->mode, + ctx->rdev); + if (!error) + error = vfs_mknod(mnt_user_ns(path.mnt), + path.dentry->d_inode, + dentry, ctx->mode, + new_decode_dev(ctx->rdev)); + done_path_create(&path, dentry); + } else { + error = PTR_ERR(dentry); + } + + if (error && error != -EEXIST) + return error; + + cpio_chown(ctx->collected, ctx->uid, ctx->gid, 0); do_utime(ctx->collected, ctx->mtime); } } @@ -373,10 +476,27 @@ static int __init do_copy(struct cpio_context *ctx) static int __init do_symlink(struct cpio_context *ctx) { + struct dentry *dentry; + struct path path; + int error; + ctx->collected[N_ALIGN(ctx->name_len) + ctx->body_len] = '\0'; clean_path(ctx->collected, 0); - init_symlink(ctx->collected + N_ALIGN(ctx->name_len), ctx->collected); - init_chown(ctx->collected, ctx->uid, ctx->gid, AT_SYMLINK_NOFOLLOW); + + dentry = kern_path_create(AT_FDCWD, ctx->collected, &path, 0); + if (IS_ERR(dentry)) + return PTR_ERR(dentry); + error = security_path_symlink(&path, dentry, + ctx->collected + N_ALIGN(ctx->name_len)); + if (!error) + error = vfs_symlink(mnt_user_ns(path.mnt), path.dentry->d_inode, + dentry, + ctx->collected + N_ALIGN(ctx->name_len)); + done_path_create(&path, dentry); + if (error) + return error; + + cpio_chown(ctx->collected, ctx->uid, ctx->gid, AT_SYMLINK_NOFOLLOW); do_utime(ctx->collected, ctx->mtime); ctx->state = CPIO_SKIPIT; ctx->next_state = CPIO_RESET; From patchwork Thu Jul 28 14:09:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan McDowell X-Patchwork-Id: 12931337 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 948A8C19F2C for ; Thu, 28 Jul 2022 14:10:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230376AbiG1OKF (ORCPT ); Thu, 28 Jul 2022 10:10:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38200 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230213AbiG1OJ4 (ORCPT ); Thu, 28 Jul 2022 10:09:56 -0400 Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CC8A165650; Thu, 28 Jul 2022 07:09:34 -0700 (PDT) Received: from pps.filterd (m0044012.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 26SAlHgU000921; Thu, 28 Jul 2022 07:09:34 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=from : to : cc : subject : date : message-id : references : in-reply-to : content-type : content-id : mime-version; s=facebook; bh=d7rtdrLnuw6c0rXZn1h6CU3mT+PfQNaZdzxmBwpNA2s=; b=G6BOyJ4GTpRsqK5CPXcHJfIz8CW0lF2RzFlGqQ0lGztPb8iDk91sv5Lsy8wTwiFiVIOW FjRv2bMrDG84wRXWpJecsLgEet+KUF7/whRMZZ+Kgl2Y0w6wno6pE/6TNTs9OTlJ3Esd YjU93Fluy9pPIVTzEeVPovlejwYWh067OJg= Received: from nam11-bn8-obe.outbound.protection.outlook.com (mail-bn8nam11lp2168.outbound.protection.outlook.com [104.47.58.168]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3hks0ps3aa-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 28 Jul 2022 07:09:34 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=cUtUzeBYjIgb3DGZLfzxI+9M9PlRGOmk4mUyfFcEuD/KvLSokoWTw/Ju0pYSOfIS3NXL1X71XMrXvZd859naULj73WAKTMpqJatiMKUNyjnt+tcu6w//oxHm8V6s33Tv2MFUxG/LlNzSZ1zb1capcsqzjCcYkWWL8VROu3rIPkcSfCDGwZzLRJIxiL9bWt1jqgCrZ6PujIlG130qJ29dF8b8allVhlNeHaSEA7zSon8XcMcfPSI6qk1KGAd/AkbMF2NlW9l6aKwY2Ktc6lfqWdFvAVLiLsK5zGf+njNl4cC2HQDkbzPAocWudXnurSo5ssKEbo6yDCHQO7KTPKinxQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=d7rtdrLnuw6c0rXZn1h6CU3mT+PfQNaZdzxmBwpNA2s=; b=P4NTGT4hY2v19UQJlbo/bB32ArQOWGXLCShdX2b2X9oT8R6mqMRLIL8g9GuRY9L6n1D8gCLfD79JDBR/Rp4Et+fK7hxJ6CGClRtWHqqpo0jlRMB81j1Z8iM7MWqsWtF58FndQ/BPzGOGd5Yc404KtrMNdOv7At3DNCKZgOJ523dl4FMMsRyvzPPFmvgVdSbFWMhCUrGu+npYeMb5JucAouhvZaHM9gdlicarkEtuxYBUWZURyIKQLlEk/Y70gxHYZgviNMDLyCbus6PUsY6wC3megiTYuR/bi0sfhv4j2K6cIUr8ofYmWpifYtvTcJ7GC/OVzpugHLmqWYHMK01Qdw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=fb.com; dmarc=pass action=none header.from=fb.com; dkim=pass header.d=fb.com; arc=none Received: from SJ0PR15MB4552.namprd15.prod.outlook.com (2603:10b6:a03:379::12) by MN2PR15MB3247.namprd15.prod.outlook.com (2603:10b6:208:3a::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5458.25; Thu, 28 Jul 2022 14:09:30 +0000 Received: from SJ0PR15MB4552.namprd15.prod.outlook.com ([fe80::81f9:c21c:c5bf:e174]) by SJ0PR15MB4552.namprd15.prod.outlook.com ([fe80::81f9:c21c:c5bf:e174%8]) with mapi id 15.20.5458.025; Thu, 28 Jul 2022 14:09:30 +0000 From: Jonathan McDowell To: "linux-kernel@vger.kernel.org" , "linux-fsdevel@vger.kernel.org" , "linux-integrity@vger.kernel.org" , "linux-security-module@vger.kernel.org" CC: Alexander Viro , Mimi Zohar , Dmitry Kasatkin , James Morris , "Serge E. Hallyn" , Matthew Garrett , Dmitrii Potoskuev Subject: [RFC PATCH v2 4/7] lib/cpio: Allow use outside of initramfs creation Thread-Topic: [RFC PATCH v2 4/7] lib/cpio: Allow use outside of initramfs creation Thread-Index: AQHYoounBlqU8+fP1UiT63PdDmCcnA== Date: Thu, 28 Jul 2022 14:09:30 +0000 Message-ID: <187b606266722c4df9ecfb1b5d5892a17c45575a.1659003817.git.noodles@fb.com> References: In-Reply-To: Accept-Language: en-GB, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 32f97a5b-0e5a-4adb-19e0-08da70a2c9f6 x-ms-traffictypediagnostic: MN2PR15MB3247:EE_ x-fb-source: Internal x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: dTi5Eg/5xFEB8bqorSWwCv9ona0Pp4LdOhSvL28OetzvfT6xbB+nSaKK7CULtmLIMescbbUYdyW7au4MVEVCHgAADrT52YQkbPGjltWzFUb79EsnU/W8/qcVVrVKnvBH/gBz2322kNUFC9uXA8JhA+pAaLe87xhKA0xwPRZaGXsFYOztGyxfCYTxTVb4jYlCMS9/Za9KZv9qt8jE8d8ec5OblCKi5T6ecGuVzlythzYdbrTExD8KvI7c6PFGS2x08WzIHgC1XaVIRdv/oqTw8b1flcgc2Z8i/Kms+t41UVgJ7tmZqAH1mhYRlQG8C76JB0JAiKbKzW/tNKHF7D1QQL64ew98gSa2JVcmO0JUiplwuLF9beLUVDBmk468qB/nfI9AZ3YxVR3FIBuQv8BRIdNYlX1Q6T9pS9VqJA5VCYmdyZr4tka9uX05a8lXzl3DT3AKlDJIPMvhraAYmtVcmi46X12ozeU2Wq74XZUUYRMwryCjrDi3hNGLOBSrX57VXbWy7/tTuk3D2+TKB7iKXEq9EGaasb0bqvmZZuD2O4IvoBgm8TQjL+Z70cMUGp1BTKOLKQZQjwLtOgfeV02jkZodgQyECIiJ4N972Ap00Kd3iu2hbXKuk0I2gnMx1VPJENATW8OKb29LZhLxNI4LTVgldcWBxw8Hi8aZiqeSj4xONlMVQc6uTpPKW3qAVYypmIvJjGD3YS0q9+Yxp7d63jEv5HxWC0qIyPx8PD+w4kr5b8UDFdfV5yPK7nGwYp/sZNq0IVtDWcZWv81v7NhSALM7YzQ0fAZrnAeNCFTbr+wVt1+ZdQzqIDqln2Z/+DLF x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SJ0PR15MB4552.namprd15.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230016)(4636009)(346002)(39860400002)(136003)(366004)(376002)(396003)(6506007)(54906003)(7416002)(122000001)(186003)(83380400001)(478600001)(71200400001)(38100700002)(6486002)(41300700001)(6512007)(91956017)(66556008)(66446008)(8676002)(26005)(2616005)(66946007)(5660300002)(4326008)(110136005)(38070700005)(36756003)(76116006)(66476007)(64756008)(316002)(2906002)(8936002)(86362001);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: zpf3C3k6cCEExaqIcMFrYTuFQwzntVFzV9ffI3phm2mB9Un1ARlQOw0vHm98IafyP80B6T5cd5l3FC8y2h65X8KIEhsvvzBkOHBlz7mAq3LV+vIJaMNWGxXuJz5Kl3hNKJrF61Psumg+UchDqM+dqh1lNm3uMHGJuz1SyXLmhuLI5b/9+B2fuW2xaGsDlAhYFYXwofxpwKLlRJblWMgwUYKjuiqxm/IZ8PeiNWcAbHJaEnTcew/aCaYbhSf63QMfeEq6vrg4kdgNZkbOFtPyESw9S3pSnJ3DLxmQE9kYB1GuhSgJQO9xgyGBivdxIW3e1xjBMibTQeiUdE9oRvSawICf8jfcPW94+sxnDdTyRamfzLqnMUImtZqpMXgWzlNhOxHMZ98ySrym6CkGjhhadjlcbxX5onABDX9Dpe3uDcg09CyJ5afCv9pjKqLEWwfNfl9DqCWjGaoYTBLYvOz3fHwbySTsVjAPvJyXlHj04gcQn3HXA6/eMqUL+afkbM1BTzFeC664f75XfD05IaXIoqRIXDQEWs8/l4r7gHvYnd41Dh2/70BXQJqfCnM3tc7LRhI2dIYyGQHjJ7YD+Uk9DbSsYhF8FaydXie26LGQJhPhKj+kDs9IsEOY03TMg940pBi9H8VtIqdMW4iF35lIs6h8zzn2GpWOxufsGb0Wm7LcBsoBQmI3cYDlObQlLB10G66diP27XCJ9NwU87UlmqqCX/wOxvikzBd2e6AWDzkqYEoxidfkqhno2MNeTps5sp7De0eJVc+A0PwbqOY56LqP0FBeHX2AQKUX967S5fgwfgYyq0WApoVa5rs3QTjaHhmsmeGZ35kuaOa53blntdZ/HAioml30ifjrjBUyr7kkeolFsh/NlQvEpNxb2z9IieJ+KATbnb2Dj/cXTH191dI6DFoZrndN44Yk/BN/Ooj4/3ppHuhWlqadGUjYTjZQUEV/lHsN2dGAUl98SYAS96E8nuJXdq53QiUh1hZ7OW9gZCPgvsK+j4EcFn1W8noTfTjzuFBTFsf2D9zuHa/ptUOZKFA34SLcWrnMXErCxipBE+ZWBLnv5ogicd5H8JD8EX9IMqNyMcw4SglvUfFsLEhmZeEenvQxlY434f9qtwKA/oV2fcQcdqQFFoo2VCARwFLXdaPU3zvJcoRp7BsELerEWx1XooNVVigOKe+iv1BNgPLvDnHBGHQKnqhA3ch5FSomEX0TNe4hFgc0u8rYXVrX/vlrZz1HF0o+Q9X9FiwHg24Us/kByat4pMzB2ljYNS+6uSyfR16n+cBoo3oznU7Uq/h0SbxUltLJCPgGBdlfVgAKQZar4oBCzxKc+pmBB4nzTdoCA8eW7qR6GXDN2r6jRyHSzkBIRlUR96rDHlb8bP57JuWS0reQ1F6tPz2CegYviEB67/vM1VqtcnX+UgdkhjC+aJxajPSx4Qtw7sfxaexFBUb94JkoYvgzCLH1yz9Qyg5CIUvuzHaeIBo+USRwlUI0hgZFUb/2V3QJrjKqBKVRFgTtYTf1dSawUnnZa22JZsb5/mH0dMcn9c+TrHkWCaoCnTGZ5WFZKG1Um8QN4KPsR6CxqMhlwOw8o9Y1H Content-ID: <3BFB9A1D09458642AE85F797DAE62C36@namprd15.prod.outlook.com> MIME-Version: 1.0 X-OriginatorOrg: fb.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: SJ0PR15MB4552.namprd15.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 32f97a5b-0e5a-4adb-19e0-08da70a2c9f6 X-MS-Exchange-CrossTenant-originalarrivaltime: 28 Jul 2022 14:09:30.1552 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 8ae927fe-1255-47a7-a2af-5f3a069daaa2 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: dsJPiHym66/Th+kSi9Jo9MEFU5tvh9/37b3WKg4BjXf7FDWYWrBiY2jmK2u8GuhS X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR15MB3247 X-Proofpoint-GUID: LloWI6nYaOJ3zhE4dFnD5aAbec7yqwEm X-Proofpoint-ORIG-GUID: LloWI6nYaOJ3zhE4dFnD5aAbec7yqwEm X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.883,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-07-28_05,2022-07-28_02,2022-06-22_01 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org Now we no longer depend on anything that lives in __init add a Kconfig option to allow the cpio code to be used by other code within the kernel. If not selected the code will continue to be placed within the __init section and discarded after boot. Signed-off-by: Jonathan McDowell --- v2: - Move directory EEXIST checking to patch 3 --- include/linux/cpio.h | 20 ++++++++++++--- lib/Kconfig | 3 +++ lib/cpio.c | 60 ++++++++++++++++++++++---------------------- 3 files changed, 49 insertions(+), 34 deletions(-) diff --git a/include/linux/cpio.h b/include/linux/cpio.h index 69a15fffa5c6..7e9888e6a1ad 100644 --- a/include/linux/cpio.h +++ b/include/linux/cpio.h @@ -12,6 +12,18 @@ #define N_ALIGN(len) ((((len) + 1) & ~3) + 2) +/* + * If nothing explicitly wants us then we can live in the __init section as + * only the initramfs code will call us. + */ +#ifdef CONFIG_CPIO +#define __cpio +#define __cpiodata +#else +#define __cpio __init +#define __cpiodata __initdata +#endif + enum cpio_state { CPIO_START, CPIO_COLLECT, @@ -68,11 +80,11 @@ struct cpio_context { struct list_head dir_list; }; -int __init cpio_start(struct cpio_context *ctx); -void __init cpio_finish(struct cpio_context *ctx); -long __init cpio_write_buffer(struct cpio_context *ctx, char *buf, +int __cpio cpio_start(struct cpio_context *ctx); +void __cpio cpio_finish(struct cpio_context *ctx); +long __cpio cpio_write_buffer(struct cpio_context *ctx, char *buf, unsigned long len); -long __init cpio_process_buffer(struct cpio_context *ctx, void *bufv, +long __cpio cpio_process_buffer(struct cpio_context *ctx, void *bufv, unsigned long len); #endif /* _LINUX_CPIO_H */ diff --git a/lib/Kconfig b/lib/Kconfig index eaaad4d85bf2..fad66ee4caed 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -743,3 +743,6 @@ config ASN1_ENCODER config POLYNOMIAL tristate + +config CPIO + bool diff --git a/lib/cpio.c b/lib/cpio.c index 9a0120c638db..03967e063c76 100644 --- a/lib/cpio.c +++ b/lib/cpio.c @@ -8,7 +8,7 @@ #include #include -static ssize_t __init xwrite(struct cpio_context *ctx, struct file *file, +static ssize_t __cpio xwrite(struct cpio_context *ctx, struct file *file, const unsigned char *p, size_t count, loff_t *pos) { ssize_t out = 0; @@ -50,7 +50,7 @@ static inline int hash(int major, int minor, int ino) return tmp & (CPIO_LINK_HASH_SIZE - 1); } -static char __init *find_link(struct cpio_context *ctx, int major, int minor, +static char __cpio *find_link(struct cpio_context *ctx, int major, int minor, int ino, umode_t mode, char *name) { struct cpio_link_hash **p, *q; @@ -79,7 +79,7 @@ static char __init *find_link(struct cpio_context *ctx, int major, int minor, return NULL; } -static void __init free_hash(struct cpio_context *ctx) +static void __cpio free_hash(struct cpio_context *ctx) { struct cpio_link_hash **p, *q; @@ -93,14 +93,14 @@ static void __init free_hash(struct cpio_context *ctx) } #ifdef CONFIG_INITRAMFS_PRESERVE_MTIME -static void __init do_utime_path(const struct path *path, time64_t mtime) +static void __cpio do_utime_path(const struct path *path, time64_t mtime) { struct timespec64 t[2] = { { .tv_sec = mtime }, { .tv_sec = mtime } }; vfs_utimes(path, t); } -static int __init do_utime(char *filename, time64_t mtime) +static int __cpio do_utime(char *filename, time64_t mtime) { struct path path; int error; @@ -114,7 +114,7 @@ static int __init do_utime(char *filename, time64_t mtime) return error; } -static int __init dir_add(struct cpio_context *ctx, const char *name, time64_t mtime) +static int __cpio dir_add(struct cpio_context *ctx, const char *name, time64_t mtime) { size_t nlen = strlen(name) + 1; struct cpio_dir_entry *de; @@ -130,7 +130,7 @@ static int __init dir_add(struct cpio_context *ctx, const char *name, time64_t m return 0; } -static void __init dir_utime(struct cpio_context *ctx) +static void __cpio dir_utime(struct cpio_context *ctx) { struct cpio_dir_entry *de, *tmp; @@ -141,13 +141,13 @@ static void __init dir_utime(struct cpio_context *ctx) } } #else -static int __init do_utime(char *filename, time64_t mtime) { return 0; } -static void __init do_utime_path(const struct path *path, time64_t mtime) {} -static int __init dir_add(struct cpio_context *ctx, const char *name, time64_t mtime) { return 0; } -static void __init dir_utime(struct cpio_context *ctx) {} +static int __cpio do_utime(char *filename, time64_t mtime) { return 0; } +static void __cpio do_utime_path(const struct path *path, time64_t mtime) {} +static int __cpio dir_add(struct cpio_context *ctx, const char *name, time64_t mtime) { return 0; } +static void __cpio dir_utime(struct cpio_context *ctx) {} #endif -static int __init cpio_chown(const char *filename, uid_t user, gid_t group, +static int __cpio cpio_chown(const char *filename, uid_t user, gid_t group, int flags) { int lookup_flags = (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW; @@ -168,7 +168,7 @@ static int __init cpio_chown(const char *filename, uid_t user, gid_t group, /* cpio header parsing */ -static void __init parse_header(struct cpio_context *ctx, char *s) +static void __cpio parse_header(struct cpio_context *ctx, char *s) { unsigned long parsed[13]; char buf[9]; @@ -195,14 +195,14 @@ static void __init parse_header(struct cpio_context *ctx, char *s) /* FSM */ -static inline void __init eat(struct cpio_context *ctx, unsigned int n) +static inline void __cpio eat(struct cpio_context *ctx, unsigned int n) { ctx->victim += n; ctx->this_header += n; ctx->byte_count -= n; } -static void __init read_into(struct cpio_context *ctx, char *buf, +static void __cpio read_into(struct cpio_context *ctx, char *buf, unsigned int size, enum cpio_state next) { if (ctx->byte_count >= size) { @@ -218,13 +218,13 @@ static void __init read_into(struct cpio_context *ctx, char *buf, } } -static int __init do_start(struct cpio_context *ctx) +static int __cpio do_start(struct cpio_context *ctx) { read_into(ctx, ctx->header_buf, 110, CPIO_GOTHEADER); return 0; } -static int __init do_collect(struct cpio_context *ctx) +static int __cpio do_collect(struct cpio_context *ctx) { unsigned long n = ctx->remains; @@ -242,7 +242,7 @@ static int __init do_collect(struct cpio_context *ctx) return 0; } -static int __init do_header(struct cpio_context *ctx) +static int __cpio do_header(struct cpio_context *ctx) { if (!memcmp(ctx->collected, "070701", 6)) { ctx->csum_present = false; @@ -274,7 +274,7 @@ static int __init do_header(struct cpio_context *ctx) return 0; } -static int __init do_skip(struct cpio_context *ctx) +static int __cpio do_skip(struct cpio_context *ctx) { if (ctx->this_header + ctx->byte_count < ctx->next_header) { eat(ctx, ctx->byte_count); @@ -286,7 +286,7 @@ static int __init do_skip(struct cpio_context *ctx) return 0; } -static int __init do_reset(struct cpio_context *ctx) +static int __cpio do_reset(struct cpio_context *ctx) { while (ctx->byte_count && *ctx->victim == '\0') eat(ctx, 1); @@ -296,7 +296,7 @@ static int __init do_reset(struct cpio_context *ctx) return 1; } -static void __init clean_path(char *pathname, umode_t fmode) +static void __cpio clean_path(char *pathname, umode_t fmode) { struct path path; struct kstat st; @@ -318,7 +318,7 @@ static void __init clean_path(char *pathname, umode_t fmode) } } -static int __init maybe_link(struct cpio_context *ctx) +static int __cpio maybe_link(struct cpio_context *ctx) { struct dentry *new_dentry; struct path old_path, new_path; @@ -362,7 +362,7 @@ static int __init maybe_link(struct cpio_context *ctx) return 0; } -static int __init do_name(struct cpio_context *ctx) +static int __cpio do_name(struct cpio_context *ctx) { struct dentry *dentry; struct path path; @@ -444,7 +444,7 @@ static int __init do_name(struct cpio_context *ctx) return 0; } -static int __init do_copy(struct cpio_context *ctx) +static int __cpio do_copy(struct cpio_context *ctx) { int ret; @@ -474,7 +474,7 @@ static int __init do_copy(struct cpio_context *ctx) return 1; } -static int __init do_symlink(struct cpio_context *ctx) +static int __cpio do_symlink(struct cpio_context *ctx) { struct dentry *dentry; struct path path; @@ -503,7 +503,7 @@ static int __init do_symlink(struct cpio_context *ctx) return 0; } -static __initdata int (*actions[])(struct cpio_context *) = { +static __cpiodata int (*actions[])(struct cpio_context *) = { [CPIO_START] = do_start, [CPIO_COLLECT] = do_collect, [CPIO_GOTHEADER] = do_header, @@ -514,7 +514,7 @@ static __initdata int (*actions[])(struct cpio_context *) = { [CPIO_RESET] = do_reset, }; -long __init cpio_write_buffer(struct cpio_context *ctx, char *buf, +long __cpio cpio_write_buffer(struct cpio_context *ctx, char *buf, unsigned long len) { int ret; @@ -532,7 +532,7 @@ long __init cpio_write_buffer(struct cpio_context *ctx, char *buf, return len - ctx->byte_count; } -long __init cpio_process_buffer(struct cpio_context *ctx, void *bufv, +long __cpio cpio_process_buffer(struct cpio_context *ctx, void *bufv, unsigned long len) { char *buf = (char *)bufv; @@ -563,7 +563,7 @@ long __init cpio_process_buffer(struct cpio_context *ctx, void *bufv, return len; } -int __init cpio_start(struct cpio_context *ctx) +int __cpio cpio_start(struct cpio_context *ctx) { ctx->header_buf = kmalloc(110, GFP_KERNEL); ctx->symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL); @@ -579,7 +579,7 @@ int __init cpio_start(struct cpio_context *ctx) return 0; } -void __init cpio_finish(struct cpio_context *ctx) +void __cpio cpio_finish(struct cpio_context *ctx) { dir_utime(ctx); kfree(ctx->name_buf); From patchwork Thu Jul 28 14:09:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan McDowell X-Patchwork-Id: 12931338 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 095F1C04A68 for ; Thu, 28 Jul 2022 14:10:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231339AbiG1OKY (ORCPT ); Thu, 28 Jul 2022 10:10:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38776 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230469AbiG1OJ7 (ORCPT ); Thu, 28 Jul 2022 10:09:59 -0400 Received: from mx0a-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DD3DD6610C; Thu, 28 Jul 2022 07:09:43 -0700 (PDT) Received: from pps.filterd (m0089730.ppops.net [127.0.0.1]) by m0089730.ppops.net (8.17.1.5/8.17.1.5) with ESMTP id 26SA3KON028760; Thu, 28 Jul 2022 07:09:43 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=from : to : cc : subject : date : message-id : references : in-reply-to : content-type : content-id : mime-version; s=facebook; bh=yLO2fDxoKF+qQQ6krmpZVBN+5J3Uy5TbMmCSOCWLvow=; b=hwT/eTKA82IiGme+Y5gPQWDQWP/4BPSwJv8SVNx1J4hX6ALMnop2JE6dfRQky5Wtt4QY O4163qb2dI6AjYp+eaN6lTQiEXZzFtPExW9rGQjNNFmd0+YzRwiQ4JPm/R/1D8tntVR0 /FKwYIzGZIr4CJOYPY5vZ/O5J93f6knlgA8= Received: from nam12-bn8-obe.outbound.protection.outlook.com (mail-bn8nam12lp2171.outbound.protection.outlook.com [104.47.55.171]) by m0089730.ppops.net (PPS) with ESMTPS id 3hkjkmtue4-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 28 Jul 2022 07:09:42 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=n2XnmxHpVXEyPY/vmOmGw/mB2kfgG52XqwOlWHRSoT7PKgBjl7FPOVp2NAeKsyGQliWHAaULA5GlutwLPmgg21Iv+aw2AZADQEg4sNtpRo8Du2dv7R7H7S06ngaDP82keVXB/Y//nn105M+19vsBS9UID8rDhH7+9CcGOpxz8RqFkLYB74QkWBe7gZJvbN+PryxAXUnlhB4MoKr6EbGf6vuz8d+/7hpXnhmFZuRac4zy5R31i9Wskg8sxs4zvM9pGcdRVeUFvD/0zpnIihKsbOQzwgpnBEvo5XvNBTNNWAf2Hr0mee4UczK2RkCRJN8+Unvsbycv+qwMM9BT1i9NwA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=yLO2fDxoKF+qQQ6krmpZVBN+5J3Uy5TbMmCSOCWLvow=; b=L56f0XqSTYDuAAdCeWNbquH84ZnpEnT2vqR3Ra+wr4s43u7C/dUnVrqJlqZyuUPR86hSEGwySdam0+8NGctat64LDoJ4Uut6r3OJZhyCH0bXxBCdJIl3bcayss+jmsSSjlacSYRRmEmGVR7KxZEUZurGahafVNB3VXU56qrY+8nY/Uu/4lHa0BBuXvLBxIPOEtd/QDPZBTSIpNaCXgSOLFeIFz8TZYnzyB/e8IdXq9WXhIqj+9fLqpl4ba0IUToUkSD7ekU8aQn0ro5kZA9PIRwBTQiczBuuTTsspSh2vScjMxAf30UeuFRinn1wjvB7kJEnRyUslUal1LNeVCscQg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=fb.com; dmarc=pass action=none header.from=fb.com; dkim=pass header.d=fb.com; arc=none Received: from SJ0PR15MB4552.namprd15.prod.outlook.com (2603:10b6:a03:379::12) by MN2PR15MB4256.namprd15.prod.outlook.com (2603:10b6:208:fe::25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5458.25; Thu, 28 Jul 2022 14:09:38 +0000 Received: from SJ0PR15MB4552.namprd15.prod.outlook.com ([fe80::81f9:c21c:c5bf:e174]) by SJ0PR15MB4552.namprd15.prod.outlook.com ([fe80::81f9:c21c:c5bf:e174%8]) with mapi id 15.20.5458.025; Thu, 28 Jul 2022 14:09:38 +0000 From: Jonathan McDowell To: "linux-kernel@vger.kernel.org" , "linux-fsdevel@vger.kernel.org" , "linux-integrity@vger.kernel.org" , "linux-security-module@vger.kernel.org" CC: Alexander Viro , Mimi Zohar , Dmitry Kasatkin , James Morris , "Serge E. Hallyn" , Matthew Garrett , Dmitrii Potoskuev Subject: [RFC PATCH v2 5/7] lib/cpio: Add a parse-only option that doesn't extract any files Thread-Topic: [RFC PATCH v2 5/7] lib/cpio: Add a parse-only option that doesn't extract any files Thread-Index: AQHYoous319EjwaYY0eBZQOcYf/Drw== Date: Thu, 28 Jul 2022 14:09:38 +0000 Message-ID: References: In-Reply-To: Accept-Language: en-GB, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 59139d2f-1a5e-4541-d202-08da70a2cec4 x-ms-traffictypediagnostic: MN2PR15MB4256:EE_ x-fb-source: Internal x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: AiOPLuUkEZ8eUa7Hg5wtgGo5gyxMeSwH3cY9iP1gTIhFRdGQ4bVzVbmXeihXoC4shri+/lSQvCdhZ5WUrhDI2M8HJM/KsHJz33GQEeGWWeHKRPEp76qibBVp5+G3JgxKugRpfb3iAVId2Sj1xyhflV9u7n7DEExXc/6BFqqUEvBGt0llvNEL7oJgb7CmUCsjmq+sXTALUFX1YsXsrPBWeJbhJPebtsf/9fB0zF4biNnwURkU4AYvmKmVjMdZv3LVn+8BVXWSU4CVuarNCa0aySZuRGrHAy1kKn0cee3yG9puDhzU/rXnbFfIq8MhHTmIdUgGlRG34+Kem8rGS/B4b23dNHOq59ScfF0GPGkSPVivuMxMfqij/toAZKppeo7s26jcC0W0+IEs2OPIkDXZwX+a37aofQwxACk7yvymhN5BQ29/QdUgGtTXBk8LFZoZw7tc0b94eTqB/laG131C4LDmKltBWx/TOPRLdlq+zrA83U0wNLEkNNHOwIZJL2S5cGTcVlIk9RDn2upOlalisPdMZtVFifpdv4Z8OKAkzkP0G2uJ5LDMFOhDmKXzv+eWjeBW6BVtCnUdxsEJyqfBoPcB08woXgwMu5/Yj0p9QniJXwzZyadk2ALLzuJ11HlZJtlPz886OASzLIXFiSrPt36PRR+gFOMqJ0nuh6W7nLwATFmuCntewmNMQk69HDozcuqxeDxUFqR07O7mtfOISAXLOWOyC6z/XP5hBdZp1vW6kzul6Rx26kzyCHkjbz3zFym3dY+IjAlsBRFmhhEBrOeax9GkXzm8EQhmdarcQvs= x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SJ0PR15MB4552.namprd15.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230016)(4636009)(346002)(376002)(366004)(136003)(39860400002)(396003)(7416002)(2616005)(2906002)(478600001)(122000001)(41300700001)(6506007)(86362001)(316002)(36756003)(186003)(5660300002)(38070700005)(38100700002)(66476007)(4326008)(83380400001)(6486002)(6512007)(91956017)(110136005)(54906003)(26005)(71200400001)(76116006)(66946007)(8676002)(8936002)(64756008)(66556008)(66446008);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: Bx3KFSqiMpPS5t9QLclG1mxtEhs/Iv2Cuj9kPtiLoYpI1SQokSO4iao7cn+1Ilx08WzfBk6723vjmz0e8xmr1+1dRsN0CqZ5Qtv8M9XETcRuZM1l6QtFWKVWc8IVo6huYnc1ksDJYOv7AVisDYezr0tqbdt4b/lMhnRZwrm3WVB7aYD/P+gLv1PfGYbvf1WPGzd9vRJTR4iUgWDHRiXVI5VfPlt+F3FCIiWzR72Cx1RHFlDSWhqdwi/pKXk9Zv9pL7dhH4sgY+ZoTwohT/B4tMk1zeXTfZJr0JrBIeX+2Z/FWf5IFc0g0/tJ8I77iCj1MAgKrA2BHWLA0fdf8shTxgHFeGfM6ANy0GJJP2Ob0hgdc96LNORqTU/W/kRXbpEITvi96WsCPJq9G8JIhnwZv9fyuSV5xRhM3uY0AYTZtaJmgNnUtO0QKYAvppGusqZ8/oPiiJZqOgcGk69RSdqZSac9bKua1EsFqOq4I3ZTFApRcKE7il+ckYyzDTgp9a9kBF/8zdvicWfGyp8UpowmmeGsaNgcPr/Q3lccHOjxXrlD9FJ1Wn4Qvg+0Qz0Y84k14Eb1Co6fk3Ynq5vQR5wXkPIgH9VlBSEMC2Cyv1r++5Zc/sDFzbmgmS0wV7fut+xjpCij1IR1USVqpYhb9iT+enyVa/wPh8iZtYLKp6wIx3Df83XeSOZ4Jtrvu30brjQzrLvAG3G7GSf/wtqqZYPls6lh5a9xoRYXgKttSAWaPfehIv0ONEn2dP+2peuE9Vvrv0uAYNglgH+XZrfVaRX0FyvZej6PndaAZ7uWz6HoSw3cC3ZFoN7Jbzokv7Gjys5gRN7yetnQQBwA1dwSCY7YhdLA6RYNBvqeV1kKGCdh22tgwMC91f9ZBznDdTSf/6xqbANb9Tr8UlCeZLMbDSogsoE/AvDL7WAhv0dlOvQQ4fdnHuGy/pDLHLUk202Aux3/apXGjNy/u2G6m6IunTsBpT8+loWK033ES0hPpl7QEjGQmR2YEND1RfbUXL/nunA1etfVSR4gUVHhO0CnAcxkVUUPTWF4f2Q0lrf8r1XeCd9JuuBtgsD2R1A3QXx19GHeN0Toh5f3WxF5LNz5+ILb5a/7re1gDsVNWm8dy1etj0y14m1Ne0GpKVT2PwDXNMCYpVdeijzAEf2Ztgz7dDY9i5EfTJ/PtT9+AOKqHJenumwhUQdsbTKdDf/W591OSOO2JE9TVNVGIN5TTTvh6og+SO3wZGSlHBqLs3Q9B/LWCF4KIpgKf+Kr5IU/GAO3u9j0IewHQyIageG+K6v445RM86FzwJ21gdXHaywpWGnRVnqmF3clSDZTicaYI7/dqq4tlEgNzpjOD3ezItGS8c7UzciKUu433So2a+erDz4ylrrzZLpwWbv6/ZFAQM65TjEMzR8f6dwpUD5+aLeJYvdwRjSVzxaEGenWYgkRXzGyHx8Grwahe/s+3UTy9J3cnPS1zEiGyOItdlkOVb+LeGdjn/wdVinA3U04iXvOX8uVyGO2oRQQp4gHEjHKf2hJX12UKaKVnbYyaCFWWa/b+B2fGMHOG5umCyc8+gPHA1ERW15TFJUUEOnhnoBQc07Fj/zo Content-ID: <940BB3465600F6468A643DC4314EA569@namprd15.prod.outlook.com> MIME-Version: 1.0 X-OriginatorOrg: fb.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: SJ0PR15MB4552.namprd15.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 59139d2f-1a5e-4541-d202-08da70a2cec4 X-MS-Exchange-CrossTenant-originalarrivaltime: 28 Jul 2022 14:09:38.2208 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 8ae927fe-1255-47a7-a2af-5f3a069daaa2 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: CfVg9SrrKs87y2y4bFpQBZLzjdSGN4r6/zPIRObr7vh2g1O+ZtgjVAA9NHm+yzHG X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR15MB4256 X-Proofpoint-GUID: RkXfWCIFQVgFVZ9NQfsBnce4eCOzl3AF X-Proofpoint-ORIG-GUID: RkXfWCIFQVgFVZ9NQfsBnce4eCOzl3AF X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.883,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-07-28_05,2022-07-28_02,2022-06-22_01 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org In order to allow a CPIO archive to be parsed without actually extracting anything add a parse_only flag. Signed-off-by: Jonathan McDowell --- include/linux/cpio.h | 2 ++ lib/cpio.c | 35 ++++++++++++++++++++++++++++------- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/include/linux/cpio.h b/include/linux/cpio.h index 7e9888e6a1ad..5b897d1d3143 100644 --- a/include/linux/cpio.h +++ b/include/linux/cpio.h @@ -78,6 +78,8 @@ struct cpio_context { struct cpio_link_hash *link_hash[CPIO_LINK_HASH_SIZE]; struct list_head dir_list; + + bool parse_only; }; int __cpio cpio_start(struct cpio_context *ctx); diff --git a/lib/cpio.c b/lib/cpio.c index 03967e063c76..37e2e2071c8d 100644 --- a/lib/cpio.c +++ b/lib/cpio.c @@ -15,7 +15,12 @@ static ssize_t __cpio xwrite(struct cpio_context *ctx, struct file *file, /* sys_write only can write MAX_RW_COUNT aka 2G-4K bytes at most */ while (count) { - ssize_t rv = kernel_write(file, p, count, pos); + ssize_t rv; + + if (ctx->parse_only) + rv = count; + else + rv = kernel_write(file, p, count, pos); if (rv < 0) { if (rv == -EINTR || rv == -EAGAIN) @@ -136,7 +141,8 @@ static void __cpio dir_utime(struct cpio_context *ctx) list_for_each_entry_safe(de, tmp, &ctx->dir_list, list) { list_del(&de->list); - do_utime(de->name, de->mtime); + if (!ctx->parse_only) + do_utime(de->name, de->mtime); kfree(de); } } @@ -374,6 +380,13 @@ static int __cpio do_name(struct cpio_context *ctx) free_hash(ctx); return 0; } + + if (ctx->parse_only) { + if (S_ISREG(ctx->mode)) + ctx->state = CPIO_COPYFILE; + return 0; + } + clean_path(ctx->collected, ctx->mode); if (S_ISREG(ctx->mode)) { int ml = maybe_link(ctx); @@ -454,8 +467,10 @@ static int __cpio do_copy(struct cpio_context *ctx) if (ret != ctx->body_len) return (ret < 0) ? ret : -EIO; - do_utime_path(&ctx->wfile->f_path, ctx->mtime); - fput(ctx->wfile); + if (!ctx->parse_only) { + do_utime_path(&ctx->wfile->f_path, ctx->mtime); + fput(ctx->wfile); + } if (ctx->csum_present && ctx->io_csum != ctx->hdr_csum) return -EBADMSG; @@ -480,6 +495,12 @@ static int __cpio do_symlink(struct cpio_context *ctx) struct path path; int error; + ctx->state = CPIO_SKIPIT; + ctx->next_state = CPIO_RESET; + + if (ctx->parse_only) + return 0; + ctx->collected[N_ALIGN(ctx->name_len) + ctx->body_len] = '\0'; clean_path(ctx->collected, 0); @@ -498,8 +519,7 @@ static int __cpio do_symlink(struct cpio_context *ctx) cpio_chown(ctx->collected, ctx->uid, ctx->gid, AT_SYMLINK_NOFOLLOW); do_utime(ctx->collected, ctx->mtime); - ctx->state = CPIO_SKIPIT; - ctx->next_state = CPIO_RESET; + return 0; } @@ -581,7 +601,8 @@ int __cpio cpio_start(struct cpio_context *ctx) void __cpio cpio_finish(struct cpio_context *ctx) { - dir_utime(ctx); + if (!ctx->parse_only) + dir_utime(ctx); kfree(ctx->name_buf); kfree(ctx->symlink_buf); kfree(ctx->header_buf); From patchwork Thu Jul 28 14:09:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan McDowell X-Patchwork-Id: 12931339 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3305BC19F29 for ; Thu, 28 Jul 2022 14:10:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231445AbiG1OKp (ORCPT ); Thu, 28 Jul 2022 10:10:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38800 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231164AbiG1OKB (ORCPT ); Thu, 28 Jul 2022 10:10:01 -0400 Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 99AE561D6F; Thu, 28 Jul 2022 07:09:52 -0700 (PDT) Received: from pps.filterd (m0109334.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 26SA3AaR028446; Thu, 28 Jul 2022 07:09:52 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=from : to : cc : subject : date : message-id : references : in-reply-to : content-type : content-id : mime-version; s=facebook; bh=aJE8ipRAhMVj75DqzMcPmsdE5KkTJgnRvLnquYiA1Jo=; b=cKboazccL4t6T1w2F80QnBhPC+sd86UpSPxIFVvD83G7J/BURNHvnPbhsrya2oePSv5C gR18Ldx0Mg7oQWiyVwUSPWfWx6sPGUaiRxCFEWuuBGS7Cl12yByizmbGa/xb2BrtN7jI tWiuzzFpm73Ujd5y5qvRaRa7ojbTwEwhT8g= Received: from nam11-bn8-obe.outbound.protection.outlook.com (mail-bn8nam11lp2168.outbound.protection.outlook.com [104.47.58.168]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3hkfsk3kgw-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 28 Jul 2022 07:09:52 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=HnFjiHn/P7HaDRxx5uktrkBh2GyPgnisKcnh0aBCAbfACiFSDzAh2Gp/6st6NbiaqDws7F6e8jMZoCqu+eV0Le9B8XBYxmDNKT14nEu69FbimgNW55RpfLgGjf+IGE++xl3swBL5UhNmTGRe58frlTONR3Z2gX8HSiW7OPR+sSSlk4LoPYMOaqDnmiZB8uzBe4gXUmgK7it0xyoBhbu6PSHLMM0TNUtOscCG4VnNpnYLuBI1a4rzsEv4kcjFtcwuUZwZRn/V+hMP0LWwfCM3dxWVnOStlDIzr7HwXnYzGoc6eE2d2lc/f5bFLXqLKW0ZD8/Gxu2VL9kn6PgVJiHYzA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=aJE8ipRAhMVj75DqzMcPmsdE5KkTJgnRvLnquYiA1Jo=; b=dLN9e+JdLM7y2tLwL4ksJrax2DmdQrf3qU1ICK6zTB8E/LeXLFuPPb5RYu36BQlZkZCLtHNodbtH2pld1+zgXcFtjNVpq+51nzVsN/t1MjjqYt0NtdEW8pPoJrpStqSWlUYe6iVmaCusCm7WUtGg3s3Z1LBhQ4f29GtMa1loVZPESJUnLk43Ac+5gKplTKE0NYyAcjFornKdhvbTrJTuoWMFAO9WWnImCu0bQto8mYsJIaBRs+jW9TY0Stlr0l8Ie6ZteV9YBgcFTb9607Syi18Lj7fJf7tnc9kpnDQqJjMf1+u9/0Kga3RL/ifnp40bcqDlGRo5lkg8BYem5wg4+A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=fb.com; dmarc=pass action=none header.from=fb.com; dkim=pass header.d=fb.com; arc=none Received: from SJ0PR15MB4552.namprd15.prod.outlook.com (2603:10b6:a03:379::12) by MN2PR15MB3247.namprd15.prod.outlook.com (2603:10b6:208:3a::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5458.25; Thu, 28 Jul 2022 14:09:49 +0000 Received: from SJ0PR15MB4552.namprd15.prod.outlook.com ([fe80::81f9:c21c:c5bf:e174]) by SJ0PR15MB4552.namprd15.prod.outlook.com ([fe80::81f9:c21c:c5bf:e174%8]) with mapi id 15.20.5458.025; Thu, 28 Jul 2022 14:09:49 +0000 From: Jonathan McDowell To: "linux-kernel@vger.kernel.org" , "linux-fsdevel@vger.kernel.org" , "linux-integrity@vger.kernel.org" , "linux-security-module@vger.kernel.org" CC: Alexander Viro , Mimi Zohar , Dmitry Kasatkin , James Morris , "Serge E. Hallyn" , Matthew Garrett , Dmitrii Potoskuev Subject: [RFC PATCH v2 6/7] HACK: Allow the use of generic decompress with gzip outside __init Thread-Topic: [RFC PATCH v2 6/7] HACK: Allow the use of generic decompress with gzip outside __init Thread-Index: AQHYoouyabqQkkqDF062tKBAwVyHtQ== Date: Thu, 28 Jul 2022 14:09:49 +0000 Message-ID: <53e15800b5e1382bfa3ce4440908726fd808ac39.1659003817.git.noodles@fb.com> References: In-Reply-To: Accept-Language: en-GB, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 679a21a2-fc36-40f2-bd1e-08da70a2d55b x-ms-traffictypediagnostic: MN2PR15MB3247:EE_ x-fb-source: Internal x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: C+enTzvh/eMGAtDcYwA/kFu9KD0/agHty/Ibqm2mqHMwH2l5Ht9Xa/Uro1jJLRFRYhG8iWZCDkn754NA526wZVMtffbMx4nrPcj6PU85I8GlmuVX1NiFyGN+Wne7vlDxRg4ae8AyK78/uHa+lZ6QbqQqUaFgmoJec2baauERwnh5Hm/H1aGut7Nv7RvPuz+E7IrEsd2uJXsvNeWRkT/9djDYDmWoj+Dpr8GvS9rPrAvHpth/cOjc7LgZ83yu1bNZ8KLj2PDMcrautqdTLtwZ+Ima2myK+0dtJ/VV8KEF3ZJFWYARIjdN2jdbRPnCOVldsUnrjQ1AjsDuZjNG3tinyBbwJk7RWHwpo4NE8NBGWFp3w36dX5s08p1ESx9laUtyW5QEuCFDNp3SGZaw6EvI9tdhrWu/eQc5KIfPwxZVoGTwr+bVqIemqextYQO53S2bLPDyFlDJQmEE0/zy3W8xzNXAevcPCG3Ez93kA4Ag9OuKujQYhRHOZtyRVhzmF1QTm8x9AQ6zwWJPa6pWYwjI3q0aiZeX5IIxyAE17Gi1vA+Oy8lT/2sAedlyp+tEOR1Ew8mKlndwDjIkyd/yc3bdAbRVQF68TxbVSmxWoP1M5yr1jBDZkwIfq8XsMLkdgq0ZVFWweV2x2nkvK2NIr5fkPFkO+93E3ZkSPSWtoO2LvIakA1kmYPUo3vOa7CS6Qgo4tLBBz2W3nF+PeEtXfvtd65NMpfGZVIzINICwx8Dci0pONlQkqbzPbJEiZbexeotHn4aDf15Hfsi9IdCNqlG6PyzPwFCEY0Orgrhzf1ogq5y5yF+T2EmGVo69KrjlDnzwWI/NNWk3kR47dQDWxZL+dQ== x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SJ0PR15MB4552.namprd15.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230016)(4636009)(346002)(39860400002)(136003)(366004)(376002)(396003)(6506007)(54906003)(7416002)(122000001)(186003)(83380400001)(478600001)(71200400001)(38100700002)(6486002)(41300700001)(6512007)(91956017)(66556008)(66446008)(8676002)(26005)(2616005)(66946007)(5660300002)(4326008)(110136005)(38070700005)(36756003)(76116006)(66476007)(64756008)(316002)(2906002)(8936002)(86362001)(41533002);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: 40oyHV3VcYMFSwNGgzUpLebg+qM0ANB7vrThtbrBMlMnpZXh7R8U8ySmDN1kLLIfCgrldQLRIRJXlWkNGUSgQjqbsC6RG22+m1mWVIkMlmnezsnfmIi1bEd3p2s6KrX4HH/r7qOQWIntURPc1Qp2989eZCFDxJnTl6U1UXubM3XExrMpEs2HzSdr23rmbf8uaI2CMZA6OHSQK6ZRV2MWO1ViTOj/ukl/f8SbgIMYzTCuL8GzltA3cRh5XfEz1lBvZ7KbQAveB979XzQCNj3uBiFXzhL039WixT/StK+Rb5J1A878XKPz7xYy+9o9DxAAIUMP8p1N9yNb/wWoN/eI1+T3dzFD8kif4+9yl1TFrHpCGinQ/MnCDcYED1BQIy63AyCCY8paoXrcssvfVM4NMTcYtwX/8aA25PguBaG/rETEpKvu7OuSVBMgjB1WyRm1sh86ecpQFyql1gr/OzuvvwxxEAGqeHeL2zwk1bw/+dvwmuiiTIr8KXjmjsxIlzEhSmyMbled4hCrpv0zrztM8Iyu5AVsgmF+wN+s0PK9sOsUelfLhiKzL8poXuaNEj30l5VQT2FzNAEj0DiyDzQ4ast9W12ZgGeBCx5+xyyO1L8WCwDBjoec2Ebsea8VlpfbuEFKw9h6xPJKU0sgcHXeo/70hzVsuOOy2EB8X3siFfZEd0lzrwBdRVHIMC5zhOh7+VRLAFZB0VQuNX3E/duPZxz6f63gDlZhxJO2oMVnlvP8Ru0tls0G47clEnGZ5sx7Ad1oT4LcTWh5FgABhexsxRfTuCdcmEqUF1aCMUKjAl0ZKvor/rD22wZlyVOHIRW0O5+B917xTk9PTeF5OV2aR1ZzxB4pQmJ5UVxpLKRb1NIuQ6TKvqcl7RQ8efTFo7p1D17t5IqkcUoGk8zAALMONBM5YDpmeT1PBmV3p9WMgj2cBCi4LqiakcsXk2St/coDO2R4i1h4mjWyQnNl18e4xSHvJvYNWM3QcfeOZDyHOo54tfOBk3BOHX/QXvY40e7yHIjm5yQZCFP5VBb9NWbOchjawyiyTUTYyPObZU3lNZM8B3q4u71kkLp0Ds8CLCaaxjj6m9SAst9etuDDKhjb5XuXIm/2DKk0zqrODe6k/vtOcVL5jJYLCNyEToWKP621pUSa0r+ISaSud4kqaFTRdeKq5gfKTObbf9N9VSSwKl132Dp8DqrhhS5QjeWvMHsFYYdL2Zf+wUjubq9YzcQlV3owXnG+9Qo/uhJZZ6GcnZcJ41BmK4SrNgk1X+XFOKX9pMxV7G32OdQD/niLCX16NxUeylX5k2pBI/Fk5R+YCQtb8iWaM1qey1fVKTADsVd914t1t0IoUAhynw9rvRDLZHdE4+oF31ZQs7GVbsJGZ5WTrLqGr8GY8sKKo3qjKN015/jas60MKNyhWSAY0fRrFFfDBbO2FdEpr29oy233Rvkf+Aw54I+0cxDOoD0ahTNU/c9p6GltRNefvOiF/SKwYpbrwJL+9rCfTOHZg+Sp200v9d0RraqHnbGzFyZGV3sPhXWF6IpQ4K+pn/+Evav1Nrkb79flnI8LU1BR3VyuNpOEjgzmqRjEZxkjX5BsZFEk Content-ID: <477B2E5FBCD8064AA1D6F3FAD22F50C9@namprd15.prod.outlook.com> MIME-Version: 1.0 X-OriginatorOrg: fb.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: SJ0PR15MB4552.namprd15.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 679a21a2-fc36-40f2-bd1e-08da70a2d55b X-MS-Exchange-CrossTenant-originalarrivaltime: 28 Jul 2022 14:09:49.2293 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 8ae927fe-1255-47a7-a2af-5f3a069daaa2 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: l0cHsjhYCZ8auUr0o2oWV1iv9OEBsNnsqHZP5ECeP4X/FytRJ5duPvFs1a2yus4D X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR15MB3247 X-Proofpoint-GUID: wU1VxvurWmDl3lEGE7JNRuZNo4GXY5SP X-Proofpoint-ORIG-GUID: wU1VxvurWmDl3lEGE7JNRuZNo4GXY5SP X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.883,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-07-28_05,2022-07-28_02,2022-06-22_01 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org The generic decompression support is only available in the __init section. Hack this out for now with gzip for testing. Longer term this needs rethought in a similar fashion to the cpio support. Signed-off-by: Jonathan McDowell --- lib/decompress.c | 4 ++-- lib/decompress_inflate.c | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/decompress.c b/lib/decompress.c index ab3fc90ffc64..89a5709e454a 100644 --- a/lib/decompress.c +++ b/lib/decompress.c @@ -48,7 +48,7 @@ struct compress_format { decompress_fn decompressor; }; -static const struct compress_format compressed_formats[] __initconst = { +static const struct compress_format compressed_formats[] = { { {0x1f, 0x8b}, "gzip", gunzip }, { {0x1f, 0x9e}, "gzip", gunzip }, { {0x42, 0x5a}, "bzip2", bunzip2 }, @@ -60,7 +60,7 @@ static const struct compress_format compressed_formats[] __initconst = { { {0, 0}, NULL, NULL } }; -decompress_fn __init decompress_method(const unsigned char *inbuf, long len, +decompress_fn decompress_method(const unsigned char *inbuf, long len, const char **name) { const struct compress_format *cf; diff --git a/lib/decompress_inflate.c b/lib/decompress_inflate.c index 6130c42b8e59..b245d6e5f8a6 100644 --- a/lib/decompress_inflate.c +++ b/lib/decompress_inflate.c @@ -33,6 +33,10 @@ #define GZIP_IOBUF_SIZE (16*1024) +/* HACK */ +#undef INIT +#define INIT + static long INIT nofill(void *buffer, unsigned long len) { return -1; From patchwork Thu Jul 28 14:09:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan McDowell X-Patchwork-Id: 12931340 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8743DC19F29 for ; Thu, 28 Jul 2022 14:10:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230213AbiG1OKu (ORCPT ); Thu, 28 Jul 2022 10:10:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38760 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230122AbiG1OKT (ORCPT ); Thu, 28 Jul 2022 10:10:19 -0400 Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5BA75396; Thu, 28 Jul 2022 07:10:07 -0700 (PDT) Received: from pps.filterd (m0044012.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 26SCZoSu016207; Thu, 28 Jul 2022 07:10:06 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=from : to : cc : subject : date : message-id : references : in-reply-to : content-type : content-id : mime-version; s=facebook; bh=FCpx8j/U32BBLGRtAe6lQ0wlfVvB7DZ9frN+YQJUFoQ=; b=FWZmHhkEL/oMMmIje78KBYXqTX4JhBodre34DYq8wE41vCe75hvANfA3e0lIxDg2CIaa Fal533u7agdpEwULoEzt+BajOSY//sCFIBW2gB/9sZycqevvFEIl/mjEW7M2TQZBCTT/ kWvwIbVkzv6FYTbbJ1EX0h/PjbrhsvaZSKY= Received: from nam12-bn8-obe.outbound.protection.outlook.com (mail-bn8nam12lp2169.outbound.protection.outlook.com [104.47.55.169]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3hks0ps3dw-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 28 Jul 2022 07:10:06 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=APPx+VvMIaysKZlTMZT5nYLQgkz4i8lPt4L84Kt0W3URrC2Xo6mbwqOGLvnMHUaZZ8s0OjFIVaej8c2u3UJB6uE7ArRWrTlBk4BgAid7BuM9T+W4Rw5rLEofwds8tfK7Uslm158eY3sK9ViMVrMoTgkPkEAtIVofUOJoY67aUyi5dyvMkdVQsxBv9FmBbRohU5JWHhTQFVBKcafuNgyaGElmdkP57hzGN8PeqgnL1jimWAnfulswFoXD6spE7NtJcRKtgNsym5dRLmyCzz+S71xGTRb9vf/stSkygBkHAj+3c3ULUxg6aBSzPHj5ulr1f3/LtSh/Y0XUeE27Z9gVjA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=FCpx8j/U32BBLGRtAe6lQ0wlfVvB7DZ9frN+YQJUFoQ=; b=X3z4KdtKASdwA1K9OZZ6GSrYNv1mY1vfW+9oco8Yp2yMF7F4s0FL1MP8/IbaxNUL0qfbc89LZeBC5h+cp8GGBAx2v3BgMVg5e5yZhJwa2XZ5oMNCSxvhrpWglBthtstSi7aV9hNQEdtfYg9Zn7PCjnu+NjnXN40rdn+BFTO73l9JzeCFaPN//x4XbnyOG/v4Rhi1T0AurCrcv0zv2bxwoGIR25DPBahc8DSBac2If9A0uGEDlnfE4Uam96p4OFP2ILYTWuMUJb3B9NXAyivJa/t0UrvuEopG5qtYb53OQH/E0o20+7qKGijPfsICo9clVKdBvJ7mxfRTgG/D4xJYBA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=fb.com; dmarc=pass action=none header.from=fb.com; dkim=pass header.d=fb.com; arc=none Received: from SJ0PR15MB4552.namprd15.prod.outlook.com (2603:10b6:a03:379::12) by MN2PR15MB4256.namprd15.prod.outlook.com (2603:10b6:208:fe::25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5458.25; Thu, 28 Jul 2022 14:09:56 +0000 Received: from SJ0PR15MB4552.namprd15.prod.outlook.com ([fe80::81f9:c21c:c5bf:e174]) by SJ0PR15MB4552.namprd15.prod.outlook.com ([fe80::81f9:c21c:c5bf:e174%8]) with mapi id 15.20.5458.025; Thu, 28 Jul 2022 14:09:56 +0000 From: Jonathan McDowell To: "linux-kernel@vger.kernel.org" , "linux-fsdevel@vger.kernel.org" , "linux-integrity@vger.kernel.org" , "linux-security-module@vger.kernel.org" CC: Alexander Viro , Mimi Zohar , Dmitry Kasatkin , James Morris , "Serge E. Hallyn" , Matthew Garrett , Dmitrii Potoskuev Subject: [RFC PATCH v2 7/7] ima: Support measurement of kexec initramfs components Thread-Topic: [RFC PATCH v2 7/7] ima: Support measurement of kexec initramfs components Thread-Index: AQHYoou35xw0uKkOyEWRQ9fW+iCzLA== Date: Thu, 28 Jul 2022 14:09:56 +0000 Message-ID: <034c6e491e871e5902ca4d0af884adb07b37a39d.1659003817.git.noodles@fb.com> References: In-Reply-To: Accept-Language: en-GB, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 73fe3d37-e215-40de-63f4-08da70a2d9e7 x-ms-traffictypediagnostic: MN2PR15MB4256:EE_ x-fb-source: Internal x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: iM4Jbz3zwv1hmERU+MOQ6vPtcVMntUApmHOaeXkT7cC1ShaDrJaSO0mN19yPQrmYoz/46RmsfATxG+Etpzt7LxGF9dFMn1AuLmNLFbwBZaZxWp9XB23s6EvFEPZQZKt/ftu9cJwFsfINDoyAD1uEilEb9SUzIZUiKw6k3SFaFZx4APdtqtc6+gBkUgmr/QeJOt2naAYrSgmB/XgUIWATt3DXqYYT1MMdnGCJkUOSxUBwLbyU+TyJ3hEj2J964p/6Ux+psn4b9AsTF1osOsNOA38AdfLavOtmBJMgJJ58BYAZY0/K8BYvqzG8y6fx798lFuv2SPspU8uCtk2PYDcdxm/9Ft+1lKcggjWW+Xxag2SEBfibRoQASRPnEDnMeTLwgTvTdERgGMZZq4J9Vm73fbxRBNTFU8WZQ8ASfWsciHDEMRP8DCYG1c+x2wSlMC4dbLxxK8btiLDM1elWiyM2bli0Owa8hTFn3Kn6KH90njDet8JgnEfrkIRPXnV9hwz0aT+U0It3suIbTcEdung4gynh8a/BsJByvY9QrMHT+n3lmg/HtxdJGEMkQ6ygPhmPEgQrxxEyQePOriCoCnWIGju/YWDwaQC8XGBXOtxBZbTXoCe4lVqrc+xUaTRG0BrnRGiEpbPGgJ8gNnVsk0lgdNAxAkBJ8K9Hdz1rwH6m03emLL8Z05fjXwCb6oGkxJ6qAMpuv9qenQWmHVM6onQc+Ma5Hj5IfjONgoYISpSBO7RIHHdYueSIsUUdo+ksDkCnpLarHrwnpFR9QAdF45TDG6RN4Pi1zlEwOXrayd9zimzNbVl2Kc403/tuv41ARUWP x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SJ0PR15MB4552.namprd15.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230016)(4636009)(346002)(376002)(366004)(136003)(39860400002)(396003)(7416002)(2616005)(2906002)(478600001)(122000001)(41300700001)(6506007)(86362001)(316002)(36756003)(186003)(5660300002)(38070700005)(38100700002)(66476007)(4326008)(83380400001)(6486002)(6512007)(91956017)(110136005)(54906003)(26005)(71200400001)(76116006)(66946007)(8676002)(8936002)(64756008)(66556008)(66446008);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: ljOMfeIr6/I7qXBJmrll6TskcDGlVWQTHInuboZS2CeGRHXHOVH42B1/7BBldFuES3FEowA32HEblgsug3GahwzdiyTINoEBJ5Jl/IsCTExSxFz1emdoqTALiNNDzIoeUTlG1OZF2Woi/ZX6FoyNIEYnSc3UnMoxagwoTJDP1Vet5050nwgkBnlef6HgjqR2PEytndzoH1ydnxt3sXG1BfKfgoBz4ZXexokQXcCjhVQl9Jnhzn+cuLie/CMqtGbJa7swDnXybHCD+elsoEnACkwfk4Vjpyc5xVi621VvZWM3Xi0AxjUchiz1r5/fYgnM5nqDKJD0KZvRxNWGDgFahna5bR6q4ktt8XB5WiaU/W3aYR49jPKwUrPsTC5ELUa90JQ0f76nCVOAz8cKLxFNUE2bdRLTaTaAjq8i5af/uGl5sHOeihMSlxZMAXDtI93ua9PGSW7sY3LYpRxUf7f5jUoM8ecPfkM6+c54u+Zz9dYxRbUdxmxdmqwTKzmr3cHflpWVko2AXJ/TSqmstoRIiDw801f6+uip2bq3QhlIvmx5G7s9M3au/FSln14M5QlxnNSFy5ZZmsOwJbLNz24qOhmTv2qbO0EWN6sIf0ynj9HhHiCjTL/z6/BeFxi+lyplEd+H/T8YAI+ena1P03I9Mrzn4pt9hY/k0xmUEawM8tuns1BSsujFy3ZhEfVdDXhuJygJJ3QtD3URuKZtu/Lyj/ovgL5jMBsS6HVU8Q7czFtOZTUYJEWpkB5B2NRa9vF5sHmm+yLW5X9usqQfIpqn3+QmY8waROmUd4IiPZR/ImWaqdiWx4PMIIQ9EpUJjblItdX+tiAOUeLfpuZ8JfO5XgjJ8ZXNEHvS1hChYIUCwRNuZodA/BQ5yGmf7Pgk3RrEokBMvWzabpf3WOCFY+fn+ZlcoZkMivEROvjyzQyjI+zhgH93NViRFATw0d8y1WISaX5rwuNcSqNPObVpi+9pnBby0fdnLv/+zW6OoF5GaCMIy40QgTgv645U2VZi0DWlFu25FR4eciUGQ5wC1spEbbDQCAfJx6oYn7UJjbWXZadB4zYj9MSSC92/q5WVzY0vC4iK+UQD8KZUfNfsmz60ICqnVMN7kuOlH87UHNRL1xgejUn/4VXemSM20I781ZkjjVXP4Q7XBoljvXjW7lxauItChX2WYy4CaVkYrL/PfjDNuyuKaRVsf6JxNT0S2OsYf7FVdYAlbAPTAiTlcRQGAsFPHQAC3I1pT7xJSCc6h4maHFB7Y+OIApMa6N3VguX5iZKFv1hDzxEqrbpZ3IUJU4NXsHpcaTEiRvUhUk+F2W5NxSzrVatFjoXvP1t/JiRWjEm6zpYTodHjSyIT2p7Z9Se9zMFkL3Uot+lX/zDENIwKnpCvfvaVE00Xd3lL9iXa/B2EiYNV6ATuj8WysJ/F3mO5JghOXgmLNZC+L7ZRRO/VFHW7yezuDmEZex87xqx5ug+IbumEBfLWZiToWlpzRWmMaPiyc69FaB1czbanuLp0Wek7bN91KHKsllM0TdnPfsTqC5vRPJU2qZRQ6IBWQQuJ71EOYY7W8RKJ1EypFwfDCRO9oWRhd98wW2XL7pYx Content-ID: <744B632D9353E045ACBFF77931B179B7@namprd15.prod.outlook.com> MIME-Version: 1.0 X-OriginatorOrg: fb.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: SJ0PR15MB4552.namprd15.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 73fe3d37-e215-40de-63f4-08da70a2d9e7 X-MS-Exchange-CrossTenant-originalarrivaltime: 28 Jul 2022 14:09:56.8867 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 8ae927fe-1255-47a7-a2af-5f3a069daaa2 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: v9RElZ3wfk1H4UTKqrL+3cTGyOV+EtJ7XfDXa9MavCmaThQph4wY/IdJKMgzQoeX X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR15MB4256 X-Proofpoint-GUID: Mqzn7b5VR2b22hOjRSevXS4YFpqrQW0s X-Proofpoint-ORIG-GUID: Mqzn7b5VR2b22hOjRSevXS4YFpqrQW0s X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.883,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-07-28_05,2022-07-28_02,2022-06-22_01 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org An initramfs can be made up of multiple components that are concatenated together e.g. an early uncompressed cpio archive containing early firmware followed by a gziped cpio archive containing the actual userspace initramfs. Add a Kconfig option to allow the IMA subsystem to measure these components separately rather than as a single blob, allowing for easier reasoning about system state when checking TPM PCR values or the IMA integrity log. Signed-off-by: Jonathan McDowell --- security/integrity/ima/Kconfig | 16 +++ security/integrity/ima/ima_main.c | 191 ++++++++++++++++++++++++++++-- 2 files changed, 199 insertions(+), 8 deletions(-) diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index 7249f16257c7..b75da44a32f2 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig @@ -41,6 +41,22 @@ config IMA_KEXEC Depending on the IMA policy, the measurement list can grow to be very large. +config IMA_MEASURE_INITRAMFS_COMPONENTS + bool "Enable measurement of individual kexec initramfs components" + depends on IMA + select CPIO + default n + help + initramfs images can be made up of multiple separate components, + e.g. an early uncompressed cpio archive containing early firmware + followed by a gziped cpio archive containing the actual userspace + initramfs. More complex systems might involve a firmware archive, + a userspace archive and then a kernel module archive, allowing for + only the piece that needs changed to vary between boots. + + This option tells IMA to measure each individual component of the + initramfs separately, rather than as a single blob. + config IMA_MEASURE_PCR_IDX int depends on IMA diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 040b03ddc1c7..be7f446df4f2 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include "ima.h" @@ -198,6 +200,169 @@ void ima_file_free(struct file *file) ima_check_last_writer(iint, inode, file); } +#ifdef CONFIG_IMA_MEASURE_INITRAMFS_COMPONENTS +static void initrd_error(char *x) +{ + pr_err("measure initrd: error from decompressor: %s\n", x); +} + +static long initrd_flush(void *buf, unsigned long size) +{ + return size; +} + +static int process_initrd_measurement(struct integrity_iint_cache *iint, + struct file *file, char *buf, + loff_t size, const char *pathname, + struct modsig *modsig, int pcr, + struct evm_ima_xattr_data *xattr_value, + int xattr_len, + struct ima_template_desc *template_desc) +{ + struct cpio_context cpio_ctx; + const char *compress_name; + enum hash_algo hash_algo; + decompress_fn decompress; + long consumed, written; + char *start, *cur; + char *component; + int buf_len; + bool in_cpio; + int rc = 0; + int part; + + /* + * We collect this once, over the whole buffer. + */ + if (modsig) + ima_collect_modsig(modsig, buf, size); + + hash_algo = ima_get_hash_algo(xattr_value, xattr_len); + + /* + * Pathname, compression name, 2 : separators, single digit part + * and a trailing NUL. + */ + buf_len = strlen(pathname) + 5 + 2 + 2; + component = kmalloc(buf_len, GFP_KERNEL); + if (!component) + return -ENOMEM; + + memset(&cpio_ctx, 0, sizeof(cpio_ctx)); + cpio_ctx.parse_only = true; + rc = cpio_start(&cpio_ctx); + if (rc) + goto out; + in_cpio = false; + start = buf; + cur = buf; + part = 0; + + while (rc == 0 && size) { + loff_t saved_offset = cpio_ctx.this_header; + + /* It's a CPIO archive, process it */ + if (*buf == '0' && !(cpio_ctx.this_header & 3)) { + in_cpio = true; + cpio_ctx.state = CPIO_START; + written = cpio_write_buffer(&cpio_ctx, buf, size); + + if (written < 0) { + pr_err("Failed to process archive: %ld\n", + written); + break; + } + + buf += written; + size -= written; + continue; + } + if (!*buf) { + buf++; + size--; + cpio_ctx.this_header++; + continue; + } + + if (in_cpio) { + iint->flags &= ~(IMA_COLLECTED); + iint->measured_pcrs &= ~(0x1 << pcr); + rc = ima_collect_measurement(iint, file, cur, + buf - cur, hash_algo, + NULL); + if (rc == -ENOMEM) + return rc; + + snprintf(component, buf_len, "%s:%s:%d", + pathname, "cpio", part); + + ima_store_measurement(iint, file, component, + xattr_value, xattr_len, NULL, pcr, + template_desc); + part++; + + in_cpio = false; + } + + decompress = decompress_method(buf, size, &compress_name); + if (decompress) { + rc = decompress(buf, size, NULL, initrd_flush, NULL, + &consumed, initrd_error); + if (rc) { + pr_err("Failed to decompress archive\n"); + break; + } + } else if (compress_name) { + pr_info("Compression method %s not configured.\n", compress_name); + break; + } + + iint->flags &= ~(IMA_COLLECTED); + iint->measured_pcrs &= ~(0x1 << pcr); + rc = ima_collect_measurement(iint, file, buf, + consumed, hash_algo, NULL); + if (rc == -ENOMEM) + goto out; + + snprintf(component, buf_len, "%s:%s:%d", pathname, + compress_name, part); + + ima_store_measurement(iint, file, component, + xattr_value, xattr_len, NULL, pcr, + template_desc); + part++; + + cpio_ctx.this_header = saved_offset + consumed; + buf += consumed; + size -= consumed; + cur = buf; + } + cpio_finish(&cpio_ctx); + + /* Measure anything that remains */ + if (size != 0) { + iint->flags &= ~(IMA_COLLECTED); + iint->measured_pcrs &= ~(0x1 << pcr); + rc = ima_collect_measurement(iint, file, buf, size, hash_algo, + NULL); + if (rc == -ENOMEM) + goto out; + + snprintf(component, buf_len, "%s:left:%d", + pathname, + part); + + ima_store_measurement(iint, file, component, + xattr_value, xattr_len, NULL, pcr, + template_desc); + } + +out: + kfree(component); + return rc; +} +#endif + static int process_measurement(struct file *file, const struct cred *cred, u32 secid, char *buf, loff_t size, int mask, enum ima_hooks func) @@ -334,17 +499,27 @@ static int process_measurement(struct file *file, const struct cred *cred, hash_algo = ima_get_hash_algo(xattr_value, xattr_len); - rc = ima_collect_measurement(iint, file, buf, size, hash_algo, modsig); - if (rc == -ENOMEM) - goto out_locked; - if (!pathbuf) /* ima_rdwr_violation possibly pre-fetched */ pathname = ima_d_path(&file->f_path, &pathbuf, filename); - if (action & IMA_MEASURE) - ima_store_measurement(iint, file, pathname, - xattr_value, xattr_len, modsig, pcr, - template_desc); + if (IS_ENABLED(CONFIG_IMA_MEASURE_INITRAMFS_COMPONENTS) && + (action & IMA_MEASURE) && func == KEXEC_INITRAMFS_CHECK) { + rc = process_initrd_measurement(iint, file, buf, size, + pathname, modsig, pcr, + xattr_value, xattr_len, + template_desc); + } else { + rc = ima_collect_measurement(iint, file, buf, size, hash_algo, + modsig); + if (rc == -ENOMEM) + goto out_locked; + + if (action & IMA_MEASURE) + ima_store_measurement(iint, file, pathname, + xattr_value, xattr_len, modsig, + pcr, template_desc); + } + if (rc == 0 && (action & IMA_APPRAISE_SUBMASK)) { rc = ima_check_blacklist(iint, modsig, pcr); if (rc != -EPERM) {