From patchwork Fri Jul 8 10:11:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan McDowell X-Patchwork-Id: 12910886 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 5E871C43334 for ; Fri, 8 Jul 2022 10:11:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237909AbiGHKLl (ORCPT ); Fri, 8 Jul 2022 06:11:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56264 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237866AbiGHKLk (ORCPT ); Fri, 8 Jul 2022 06:11:40 -0400 Received: from mx0a-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 97E6283F3D; Fri, 8 Jul 2022 03:11:38 -0700 (PDT) Received: from pps.filterd (m0001303.ppops.net [127.0.0.1]) by m0001303.ppops.net (8.17.1.5/8.17.1.5) with ESMTP id 267KPdlF003834; Fri, 8 Jul 2022 03:11:37 -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=CkiMO6lYmM9ZcbH4jMe7VqhibWZBjDLd8iYa71HkU/M=; b=ZLZxbkd68rZ/P9TGzjB/O/1tLjexbuDPOcsG45DOFFmJbCaIWdMe+l+XmvrhtXtooOtr Fox2CDjzzhmLUY1XS2jJQ7JwR4/GE1zbinmAV0VNTkwgrYW6CQVskIy5tFQjskdNFmHi C0WsQyT3wLl09mwOwNNJrSTrhTttt2yeYMA= Received: from nam10-mw2-obe.outbound.protection.outlook.com (mail-mw2nam10lp2106.outbound.protection.outlook.com [104.47.55.106]) by m0001303.ppops.net (PPS) with ESMTPS id 3h5yeqq1nw-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 Jul 2022 03:11:37 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=mE23rLjPQDNApcfkpz5Gw9aSbswMJ4c3g7MBS8HILFH2SQ3lq8mjEh4DiUGkCpNhxgFUkdVIJ0qwQ3i8DqvtCMCx03g5CjyVugheeAYj1eL6Xa9wQx6r+tnP6tOiGlUFM9rMR9tQkJAqTncBLVoDy/w5g10nYwrIrFgAzMsVRUuJ4Hn4dLADjzrDZIaZ+L8iw59mK/G3GrFsu6dQCuZeM6VdwBHGR9iwRT64aD2no11LFoWoZLARw2qENEYjXnIswohxYDyIV3taSX8PIWvB/C3JPE/dmKTcv/luYygyj9dlOVlEdBTWYweEi02jln+oxF6ubRIEbbz9S3d2RfwZyA== 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=CkiMO6lYmM9ZcbH4jMe7VqhibWZBjDLd8iYa71HkU/M=; b=nErX6+UKSa2kjUaKntl55LsGlzCgbjSRqqs+ASDAXPuZrVQ6esXuDHRAEWN0VwE+WV3j869eFRE0imsK3AXFIN+Zxb8z5pK3wSVGqOvXW1ilmlSwjT62Ad6jzouB/GJVSnWqDITTSQt9Fz+3Henb2eJl0H4oQPMfVcNdcK179zX7AnWsaCSpzmONP35yE1bydA8qPMQOtT+bYoLl+qTtfqHy49LIWUV384IeKP+nCGmU4kVF+Ka/8Seome5twuyfURb1ajd/5PXOuA2J4sG6JT3rwmIJ6UUEfJq+m5z1ghtI1P9PW8cDp96t3QAHO5npvcVDrRO1uop3j5ANoNwavg== 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 BYAPR15MB2501.namprd15.prod.outlook.com (2603:10b6:a02:88::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5417.20; Fri, 8 Jul 2022 10:11:33 +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.5417.017; Fri, 8 Jul 2022 10:11:33 +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" , "kexec@lists.infradead.org" CC: Alexander Viro , Mimi Zohar , Dmitry Kasatkin , James Morris , "Serge E. Hallyn" , Matthew Garrett , Dmitrii Potoskuev Subject: [RFC PATCH 1/7] initramfs: Move cpio handling routines into lib/ Thread-Topic: [RFC PATCH 1/7] initramfs: Move cpio handling routines into lib/ Thread-Index: AQHYkrMZ5DDpxnKkiUCBiG2/Nktz+g== Date: Fri, 8 Jul 2022 10:11:33 +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: 80e563d5-a932-4d61-bd98-08da60ca3c42 x-ms-traffictypediagnostic: BYAPR15MB2501: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: wFu+7RKcICfiRPClrcLo07E7E4e21vXl2UCneTswBpqh3eiW+1cEzPVIpueMJP//d2f+T3cMp/wQvxni3mwMfgQAajjsw0E6o0HdTeLAzn9JUgMKT8+3KirrE+blwhjlYDEiYXgnUqq8Yk0u6+YR67xE2fsXnUVrsUptn42E+Aqlf4nXXQW1uwtO7v7HH8OAYX6VmkrfaVdeea4qTnDmyA3eHQu66cKahuoIxpxEzmHOg5tSsG+IDXdfDCLurYmGQJRDNoGh4bijKItwMmkcV4x2jh6Vulx32HSHkyRwKJzSOt0AkaV+MlF5evQqbP77uaJYsqpP1CGhR74L4xMw/r5hFc2zzrgcDg7FvZ7/XiRZ2p2fJAozxUaiF3EtmS9YHnAem/f7bxd628iz5Hw+4/FP1v0lk71q8OfRl5HqRRO+rhAwO2VWNgFP0aQy9AMFeoRY23zff5kP+XFdgGG/4yYs7MPxMsJ9YM1EctxqGT5OAOt7ZTTGgtR0ms9j6Jam2NDFXrnlSI76fWTYnFibzLJ3oSatsWnGKyxbCvqzi943cq/LTorxtfRw+b82s4jyWNm14yjuJzmB7H2zHX2NQMfElSbiQPeADJgdaxfR7XCMt/+lTonaEpSC8HrHq+fgfggpdnROnU4Yu+32vh90JlNdLk4KEaeBYaBj7rRK2sNP2iztOjykI3OsdsI9s6a9BMRfXrstOwjt7PKVfwe7PD2Dh+HjRnyMnchISU1uZy87QuIjEF+psjwgIyS62jLyR2+X/0xVPafqve5MROarNHAHEMVfdpvnrKOPZK/zkCGqpsuPPf6qtgRGH8yM9fp0 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)(39860400002)(346002)(366004)(396003)(136003)(376002)(76116006)(91956017)(8676002)(4326008)(71200400001)(64756008)(66446008)(66476007)(66556008)(66946007)(38070700005)(6512007)(26005)(186003)(6486002)(478600001)(6506007)(41300700001)(86362001)(54906003)(122000001)(316002)(38100700002)(110136005)(2906002)(36756003)(30864003)(83380400001)(7416002)(8936002)(2616005)(5660300002)(579004)(559001);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: yXSO7/TzYblG1qHPDTb/WtN4HqqNzyMJ08LpxDeC3XeQEk8dmyAwS7qwftxiTAqTDCWF9Z2vDbCJbLnkXFiyWPF+mOGym/sI9kYPjueY+ctwaeYSXMZT0DlokGeZUatu5cMr0yMHiykamNIhmpXK/OPYP/yYXcq6KOP4l7WmnMly/Hh+1eggeD29gXZLoCZyjk5tj3+FCGlOCqw7bmXlYgrV9nL+o7VPe5ok9qNXcL/HwLoEt1A48i5AAdZeG5RgHYULFOwncEURJaAS2QdY6DRNfLxg4EJMiT6q/i2gICna1tbZHE4khPy+43ktWsC5noljmqXEW3OT9PEZ6F1bOJ8OHJ7GfO1JyA/9Q8nokgPbSZ8M9PEsamrcYUwg3a81Qv6sRyhSkQ3t5+ri3bYYzdnPmHewjGCGMGRSxZFzHv/ql+mLdq0nK2V+EnLhBc1dH/HNPtWH1GulO0MDtls8DrROmXOUZB/d6NMzjJKmCvZIj/lZ2RqxgnP5IGP2VUA3JDpHw1h6s3CPnRaVeqiiCrvchXmfaLSu6gcTr1N6NoVvPYkHgMXmEpJWJ7TzZXZCm8qa/UgQd8oiJiXPPpKMKnexSG3YHz033+qMzgKSMTdaUmasATIZuZZxvfNIpfmVVByc22heBe3GHl18WLHa85lNkQNXuH5Jhcpx7BuMZ8v5ewXjkTNKzw/DlQmFFLOu4beKfq6WH8N6wTZAtucUSQSewqwBkrSdX9+SFNYG6fKAtgjrdgeNQi9zml81g6N6F4HM2Ca8OFZBVYa+ZV6Q5b67K29bhaaZoaMFaEbVLyN6ZH3SDrJJMGf5c+cQ4cb2Tr8CrSSwa7rB7fh0BdlYSQsdxrGm5eXagrd9MSJK5dKG0JG8ruJQaB7ltok1f49fCMtytW7KlXx1Z10TH2/BPfhTY58SkM+/nP59Dqi8g+kidbu+4d76h4Xm8IOA1lALSlklnFcU65Z2bhaqJkJRlHHpABcJJ1g1uM9ouhAEG8Qs2C083fStYlNpui9nx7NSUKkbuQguq9pT1+kG6zno8sgq0bU9nHZYCFTTu0bnlMiLS5Yg1LH/2PSYwP6ImPYahFW9KJVdpIL5UjwLI/cwvMR2lCFinxHyKL39RJ0haoLCuEQb9VG58L1fb0x5R/fOBlCnqMBWzjQcAgQi0WYTs8rCJ80MXmCvr0apEXJuoxB+gPfyCD+6n/rFt4sbl/YdgmPCOVFlq+ogUb1SgYzc/2LdqDTe9tYW7WiNkx4go7LPYBGobfLCHcU4j6Zl0bHOMs6+rYQEuKB1DgN6qM3FB+vtHb1qY+BmHe9AKdJ4hv+jixfxgKLmXCXxJL5EXe3uuL7BWNEwW09qNhbOTPkKWZNPYPJV4bAwi9DBEh6nQShoc1zJc/xLNsemerot/P7PZATslVgsn40QIoAAHZdd4hLcQWkjF0vJfVPhsZHSocd9z/e+KvwcB4k6VQ4nMRIx7MTRMUy8OBlScTjUbRiBdvULH4e2Y5iHJZ8SqMARwGvyxVFUOBdokqlaniJGeWv9UfBGQDqOLk0LK/t3unsZlZlYhSMQfywEO9c31SHrGXDXFg67kPD5ERKaDjwEiM+Z Content-ID: <4EBFAEBBEBE2F14B83BB77699C847083@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: 80e563d5-a932-4d61-bd98-08da60ca3c42 X-MS-Exchange-CrossTenant-originalarrivaltime: 08 Jul 2022 10:11:33.6701 (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: 6UcvvNFxF7hUdNGddbVigjjv/mszWTYIXx5K3qCkA6Kus/M6J8/NW5VSJ9ufl9jG X-MS-Exchange-Transport-CrossTenantHeadersStamped: BYAPR15MB2501 X-Proofpoint-ORIG-GUID: 8BTq2uEt2vUFRTb38McBF6el6vSPNOdg X-Proofpoint-GUID: 8BTq2uEt2vUFRTb38McBF6el6vSPNOdg 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-08_08,2022-06-28_01,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 --- include/linux/cpio.h | 78 +++++++ init/initramfs.c | 516 ++++--------------------------------------- lib/Makefile | 2 +- lib/cpio.c | 454 +++++++++++++++++++++++++++++++++++++ 4 files changed, 577 insertions(+), 473 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..f90b53fda6b5 --- /dev/null +++ b/include/linux/cpio.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_CPIO_H +#define _LINUX_CPIO_H + +#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..5e3abc1e51cc 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) + 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 (%zd != %ld)\n", - written, initrd_end - initrd_start); + (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 Fri Jul 8 10:11:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan McDowell X-Patchwork-Id: 12910887 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 0494ACCA47B for ; Fri, 8 Jul 2022 10:12:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236895AbiGHKMB (ORCPT ); Fri, 8 Jul 2022 06:12:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56578 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237699AbiGHKL5 (ORCPT ); Fri, 8 Jul 2022 06:11:57 -0400 Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F1B3F84EE3; Fri, 8 Jul 2022 03:11:51 -0700 (PDT) Received: from pps.filterd (m0109333.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 267LPjkJ002415; Fri, 8 Jul 2022 03:11:51 -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=0Pk+vzj4ct73OJIJI6cMAS+p+Sx8Zw0CIzkLGVLVzMQ=; b=fIS8xDS3YDRYcREEgCbBzuvO1ZX1U4IifL83WM/5Rxqb0MKtThj9Nw3XldItxFaWZwFB ku4mgMCxuHWtlyV7R+qHgQKECjXJ6KbEMZ8IC+a7aYDEd1tP7RKMm51c3EKTpIw9JLMZ wu7yEX7/+EQf657s+C54MYcYkVEDAaDBncA= Received: from nam10-mw2-obe.outbound.protection.outlook.com (mail-mw2nam10lp2102.outbound.protection.outlook.com [104.47.55.102]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3h67d23c44-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 Jul 2022 03:11:51 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=I29/pVdrEj2qvMVnfM4SttFZXGJ40aKA4zzCJy4pZdRa8RXK2kwARnW8MiHRxlE8nCoFrglR4zTzztE+txO11EIi1nD0JlKBWxeEHPNeE37jUTs+EyMl3+zJL/dw+vE2FmhQVdo+8vHdeSif2lI8lKj6H6BpwB4OGpBMKaYlxSOzfVW5P9yf80RxXUhW+WreN5rEFOfG/8uJVvEDlTXOEp846ZcABjuSgpBJQYnDbXTALJRGY51mNhiFMB4S5KkYTfnS8ILCsgShSdHIOKiW8T8cBooOa1EgR04jHSil+BjB05MUtNpMTYlofyeg9lyFU0wihTh7vM8AtkX5/UmO8g== 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=0Pk+vzj4ct73OJIJI6cMAS+p+Sx8Zw0CIzkLGVLVzMQ=; b=CiBwGfDlCbkRIct1a/ze9ENMeoAwkbBnfQ1XC+Hi6TZ9Ig84fqKB907x6FIHhuj49C2yFr0m7tlB+1WwrXniigWpjeFFoWVj7WNWOup/Ce4HlsDiiHeS8MukN2vzSZBmcUePfULzoPacjU9sK59h1vVqC5MxHIGDsWnbmB+dpq8UtEHaHgI8THTSrgQ3VLcXL19s5WiFrOUBjPm971c0jKZhwHwPh6+4MpEi9q5rp4FGRg09yA4g2++r6RK+Dpd8IPL1y0F0w+R+K1FP6VBp2bs4GuoLC1hMBB1cXM2s2D4FbOHeX6+VtC+ChtDHFcFpHHUby9EAhBiMhp0C1Ia/Cw== 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 BYAPR15MB2501.namprd15.prod.outlook.com (2603:10b6:a02:88::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5417.20; Fri, 8 Jul 2022 10:11: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.5417.017; Fri, 8 Jul 2022 10:11: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" , "kexec@lists.infradead.org" CC: Alexander Viro , Mimi Zohar , Dmitry Kasatkin , James Morris , "Serge E. Hallyn" , Matthew Garrett , Dmitrii Potoskuev Subject: [RFC PATCH 2/7] lib/cpio: Improve error handling Thread-Topic: [RFC PATCH 2/7] lib/cpio: Improve error handling Thread-Index: AQHYkrMiKkKuLt+VP0WlOEWW++RFVA== Date: Fri, 8 Jul 2022 10:11:48 +0000 Message-ID: <442be8d5f2810aa8e04c3529c822438f948075b3.1657272362.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: 16a45b67-4481-4e7e-11a7-08da60ca457a x-ms-traffictypediagnostic: BYAPR15MB2501: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: KgSJRrz/eieflDCe8pKNUN+ZOGIrKiXDUGarNvTm1kV0+kTnFr7IyTzddF2UivViPbuyZPCtHDMZAZ+p65/W3WRrmqlMmnRFQaTrk12YpI0OmyWtjE/dnnyOpAaAOXsVX5GZZ6ujwoR4pqm3oINhFVIQ8jwmATviBZLGx/kzoU6ViAiqsYAok8h5oy/DvmTryDz7cGNFwBxoH6ZnsAJ5ClPCeqCin+va/nmVu8UZqh4H4dYtpMY/yJeUj2rjcwtz78XXbH4zwk5TO5RP1iVo/k539L0qQv7KoeW1QAofXjGtPXuw5zzZlKdkr0y7Rl1RxURkwlmSj+4ZtP8fdCNE49OuaPbPMat9qqfsfjziDd71jA66jKg7k3UQ1gO2E6R8Ad6sye+wZUjPxUxgUIG8cbSxyQISDgR/kF2LARJEfOVvTyPrDam7MjV2ABRTgCVlj05XNm7WnAG3zDJU8Dn2+fpzITj+kYl6VAm+eaTsliFDUhXYK1bxj0G5dTEuXfNxFwramjD2qM6S4GY0TTTxO50qQjbCyhOM6O3zTcpg2loo84boetKUb5cTSzmssXqZO+h7Xxx3xLdRrF+xROqQJqmdpal/coqEmDrpYjqRbDDm58N1jM2OzaUNyi0H6tVmgi6Q2xCj5Tafh5Noq+60n+iXxykTQjBf8Gpm2Jrpw9AMHLmiAIseuI8tlaS5204VutNruIr8dBH6q3n3nSwSyitbhe9f+oRSl4bIJzADDbQpXzxEjTKODR5s8G2NrI+juhGMoMJnFRPpT7WX03W+ReEYxqKVENfJqa2wXm85vD6LiJP5rE0TnQM8gHelgMrW 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)(39860400002)(346002)(366004)(396003)(136003)(376002)(76116006)(91956017)(8676002)(4326008)(71200400001)(64756008)(66446008)(66476007)(66556008)(66946007)(38070700005)(6512007)(26005)(186003)(6486002)(478600001)(6506007)(41300700001)(86362001)(54906003)(122000001)(316002)(38100700002)(110136005)(2906002)(36756003)(83380400001)(7416002)(8936002)(2616005)(5660300002);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: ZTuN2Stq/Je9crqH+T+WrxsnOufE/5jAAal3jKjb5N39r7ka5o57oUMy1vhIcxBRb5s+UihtVPDGjelaW8xhf6k9KUEpJ/szbq5Ry1f8Va8gdkYUTXMUtZ+E3i4Sp7APhJgOKW85KGZER666IWZbIuEhgQoZHoZRnygxesqYSdtEb8mDW3LkdxVX5b3uJy0nkR9NeeHKzH2YOu7KKYDG4uGDyVICrjFkZEkGACH906JZsYNQFHOksi5Zhqwwq3/r6i0rRTBDLzw9+YHTKX6rahjm9Tqs8ywiBlknxKOp7PcfvyQO9RBYmNV1BWbehClMaI96tsZ64+krDfdxmKJhHFzMynukVGZmDOMVqZ1A1ttnkDwbWo7dzrVvdqSzk1IjwX1rSvslxFr+scAVcor7/qrJyy+ALtXiVTvelUsHDgD2xR7pjHvHxtjHjD29Y/z3S068V6u1XWoMak5v7FFBlnqN21BdllBUI3LV2TLHKTKwsSZkywwKCV0TxsI4XrEsycyL3PzQkkDE+z0BpmrTBfr5vu04GnStWYlwdOm1vdAyryDfXoblxyHR6PHUVk93c0AqH9QzRFPjbNaWwH4PDmQTzfQQpyJ9vW44w6mBn04jlYF5TsY0TWquHmzDz7NGlA7kys3QrnTAGR37tqJgM8ck8EyvBdwRysWthymIaeNPH/fJDdN2V90gIH52OQ6pZXeYmoy35lm7K+98OJekziaklNfCuIhodn8hEs8nmaFfLrAL6UaM18WSIPvC3o5febTqZZGAmA9wjEMsy2ynoTRdCzzdTlNwjgcH3Ih8NjCoQuFZdX9cYDILF8hk6haWuEQEQ8EW+s4YWigcW61cV0tKltpSFapjGoIOkN3Pd9PsRVZ/SVZ31LIWMAwV2wSv3va2AQIWnn9WppQPF+NL+p1gwvcIl0Nosy5zwyg49zD/HIBionmSCo5u4OfVgiSxCwAtjCJKl/X+oE68U4c0XjClIwpxzL99mrdlHKtlFSYcy+zHKT8g3/sePy4ErPAtEnirRzcaM8WLoxSOHXOgc3v6bM5cyoBLSuQBxffeNL44niT/hOFle0j1h7yUpA/famWuU+bAd0hOqZgdAwztqpIf+YSDO03iApSe3pjjq/EIXUVic+6BcY2YqlWDvxKXe/na7pKEFwWuTWwhWMYCzXNrzyciXoFJ2Sqrd91a8/IvY5PV+67zQrHraAxe4iog40DSa3UB7DoWaDE8JhHQsJ5jWFxZE7u9rkExBAUX/LspC9XSfJeYZAvi10ck5OXpC4rSWBOf6kmfhPUC0cjjFWcbm8z/ymnjr66/OrXdzMsugeGSKK/vinT5j0z9z4Ffn3PttdaWSc2r6GWBiCujZqrpQ7htpvfpoe3Qz0myiJHiW5eQImztMpn1sxdpZ4upw8AtxWl4kpEM2CYGMOrzcyS3NIhT/gLI3xJZVxbsdEUGAHvf36RTiVm7CDuiIb7jIF0Nb8gvqUbxcIPqkJUuq5NDlrTH/0quRCCKP/BKMzfZPTkyX6B2yVyVy3wG8QXkzz1BGQBlmWFzzxTW9ygQwb6AML4Ezzr1dc1fzBLQwRX2OCsHGhaibqPvB0KBdA19 Content-ID: <039104E7CC26474F9664D044F8C6E13F@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: 16a45b67-4481-4e7e-11a7-08da60ca457a X-MS-Exchange-CrossTenant-originalarrivaltime: 08 Jul 2022 10:11:49.1478 (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: Cmyk056EyCcHxgNh4Rd5v9tSY0WIdLwM4p90cVS7ko2lIC+CN3K/UYXEE6uTelcE X-MS-Exchange-Transport-CrossTenantHeadersStamped: BYAPR15MB2501 X-Proofpoint-GUID: gPhbysbod2A-Vcqwo01-KKun4ezTj1ai X-Proofpoint-ORIG-GUID: gPhbysbod2A-Vcqwo01-KKun4ezTj1ai 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-08_08,2022-06-28_01,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 f90b53fda6b5..d8c1344a6cc3 100644 --- a/include/linux/cpio.h +++ b/include/linux/cpio.h @@ -43,7 +43,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 5e3abc1e51cc..3670fe0ac336 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 Fri Jul 8 10:12:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan McDowell X-Patchwork-Id: 12910888 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 E9422C433EF for ; Fri, 8 Jul 2022 10:12:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237443AbiGHKMR (ORCPT ); Fri, 8 Jul 2022 06:12:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56746 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237440AbiGHKMH (ORCPT ); Fri, 8 Jul 2022 06:12:07 -0400 Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2C38884EE2; Fri, 8 Jul 2022 03:12:05 -0700 (PDT) Received: from pps.filterd (m0044010.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 2686Haqc027362; Fri, 8 Jul 2022 03:12:05 -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=FJyUWQvWyANcWv9sOowKnPZ86U7f++4lXTeaKds4TRE=; b=lzFM07bpDGrhDShrC7VnYG1NbI+bfEcO0T0h9WiUBNktxUYJJy6CzHe3D2MS1mBgAPu7 ieAPDr6ikdx4Wczc8OL3RyzBFFkEBCeGXSMMt6xILDPfBXWA0SDYlid0Q9jB2KF490Ns filsr1e5g9xa1h2qTWcpTsjIWkA9iDB8Wqk= Received: from nam10-mw2-obe.outbound.protection.outlook.com (mail-mw2nam10lp2107.outbound.protection.outlook.com [104.47.55.107]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3h6f69gxnr-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 Jul 2022 03:12:04 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=SxSPrEUXXaalL1X7Eg4phHETJCauu5t+QMN1aJ8k3J7zkioMTxRmF/ScogisZ4iRR5TDFzh2H1XY3xujmNVUhVUESrRobiRkMDmr5dX0dTuUuAFlobONfO3CcLtmtjJOBwYa1HOcGcMPmcMmbD0GRTU0Bii6feW324YZMVvBIIqo5/l2WqJuTiTiq9JRqWFZpxME4UCFdbMq+uTQEJ7Ap5b6n+qpsOnQ+HJQjD95AhfMnysmZ2dFrnGVgnbJt+iNS32kb5/zs0JsCXGhsXR3Jh2Or3W4ZLg+58KcIrL8ZME9raCkB8zfYfBLpCgyB+B8ciIuFaRdkVRgLry2zKehIg== 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=FJyUWQvWyANcWv9sOowKnPZ86U7f++4lXTeaKds4TRE=; b=DnTVXKXTtYdvec+kwMV+y6PXfvqji85quDngCzkCuDeO5093l6P2ZnnqmK3X0xXULYSg1nB3cgBSt35nFySivG8hUbPGjfAKMWBak2cCSOtxh+3WsE8i5yzfRoSrEUWE+sw12szpjThrqkXJDj1zfcIuMxspADt2x/Gf8Gz83JognTvaYq/2QiInUha02WbZUQqB22CsrYIWW6wQiQ6M2AuHoZsQFCuxsQOv1CojmGxN12x6sM9h57fCASJv+CwzgsMHP2GqBU9zXXc4Z2gjp+rMS8P86le9g5OrmF1D/o9MERETBpxa4De70vygh9unB5Mb4wo4VfSWy/UP7irYAw== 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 BYAPR15MB2501.namprd15.prod.outlook.com (2603:10b6:a02:88::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5417.20; Fri, 8 Jul 2022 10:12:01 +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.5417.017; Fri, 8 Jul 2022 10:12:01 +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" , "kexec@lists.infradead.org" CC: Alexander Viro , Mimi Zohar , Dmitry Kasatkin , James Morris , "Serge E. Hallyn" , Matthew Garrett , Dmitrii Potoskuev Subject: [RFC PATCH 3/7] lib/cpio: use non __init filesystem related functions Thread-Topic: [RFC PATCH 3/7] lib/cpio: use non __init filesystem related functions Thread-Index: AQHYkrMqQCQoguTYLkWyk+Fnuut0VQ== Date: Fri, 8 Jul 2022 10:12:01 +0000 Message-ID: <4b9ed0a326cec3752792792a3de1ae6e5270ca78.1657272362.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: 6f9a9a23-6152-4824-1ee6-08da60ca4d04 x-ms-traffictypediagnostic: BYAPR15MB2501: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: X3kzqKXIIWoz1hMDPl3ZGeJO2vC2Vm+8WgqtU9inD0UCqT/6f62TGhteSZOtLEy29XESkvY2tU6LzTVDcd28A3uPYml7wqFuiZWOh++NmK0SerL1khMh4UGRJQHzmd0VnbQiSO3eNSWxNcpgCYiw1LboKtZrdLQl793Cp6yNmMKUV8TeTZDboGV6rjf3dzy8jmcisjRS9B9hThxzv1LQu2adJBmnrQWmjw2wPS6sMULcyaWf256Cp4YK18T8zLNnGfER9MIJrziIfx4EblOfmXHCa2bjqYZrsWl1U2b3Clo3G6z3T17FkvHm5WyBmsb/2JwrFnMKBhhM7ItT68cpoAXv6DNvS6RAsyqKOrEJGXRlaFS3CUjgm7TPYwfFFJ5hjyyGbknJXv4/TiTnNFra5BEMDUBtHqhv7Efx3brxLnljKRqNvVHgaRdloRfWLZTDWN8QM5Uok5l8s4VyWgolStoaIz+fhqTpBgC4df1ORs1uX0noXsUWdF/Q2/4wn7lDbeyRO4u1t5g62HORDW1BEVqYSvnLHQbrkxexsUPT7kYAO8LIdlRAuW3d3NEE6aOmIGGv8UCQutSjtPDyocFl44LhuG8WXjW59xIc12LK67CWRs71UTiHunEwKVps5UKTcv33W4iLgx93SZQo8KkOWBOlBiuU44k9Q6SgbCYgwSuDtO34WjXIswqWCbSl7zdJ0JNWXbDAs41+rZqs+ZsyLHbAqiw+TfpQdkbo3+J+NgOTX9fQPu+pLkFSxhv/RudFl1pq2QhuDTwtCWIbzicPGFi5I8NbRohETbGuFw9pnqo0CWEyU9cSwP8JzI9v2LNa 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)(39860400002)(346002)(366004)(396003)(136003)(376002)(76116006)(91956017)(8676002)(4326008)(71200400001)(64756008)(66446008)(66476007)(66556008)(66946007)(38070700005)(6512007)(26005)(186003)(6486002)(478600001)(6506007)(41300700001)(86362001)(54906003)(122000001)(316002)(38100700002)(110136005)(2906002)(36756003)(30864003)(83380400001)(7416002)(8936002)(2616005)(5660300002);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: M3r2xDnKLheRNUbs1h1HUmBCfB9XQbSrzVVrbSTnGCiZB7bR4l1t1IkonyfQyXQibyMDvZw5sQQANdXLEFdhKuIOisfdVOCU6AVI4fzaeCSorKtavniEjaoXKQGJTjakTFHXimVjaptZJwjenPOLpGJ+iQOgTxDUzlo2EY2T4jOhKZ5cUK/LIzaiWHtJmlRniEx/JPYK9MOfLoPEf9WrtyJQiIOLdNs8M9INzmMHDP5UErAmhJrrBomzf2mLEM/vx/pXwKJbITOzTUZ/L/Pe3ja5d+Xc+cecUwQDCSgcOxOXuVE+V0nv65eL2uCBT1xFYLitiPGyGYHiUMRfdWKIp/w7uu+It7mF8mG7n/FkZoTtJbX8jNZFLbTA5cI9Tp2TOpuWFWVhG0MiyZCjU9TFxaLc7PzqJ8+jj6I1256Yh38sOikq5deAdD5KomxEhYpGqO7nv9n3z8SxT3Qm8TbLvgANCtH5rejs5ikM/toccBLSGcqI+pW+a83sKCDDM5/bZhjk3wbpCMmbeigBCsuGkQwuPHA8cTZRkHG6d6C7yfnE5BlbPmOjAVMnvzmBx+/4yu8jGxA08sJZK6kfxQ/ZhAmW1zNFI0QULsNWRY/8jpZQQRpsQNqjzViwSdFkPD2WrCqaEuCjFJj5+5l2Ks8oTgFB7417NdWu/wLYf/pXY7PjMsBU/UIkTRVlkpyvtusPeanon4uAiuGT5oe8e1yeEAn10u3I08DSa2OL2wPFmTm2lLemwSdYdVf/QGz/T0UuIlzT5PsvL8kIUZ0G365Ywt8PpUeygeNp3eY1lfBXv+IPR588fdDLVeeZvMSPAqWibilFf+VRxNu80TyQYmEgL24z3o/1/78SAgL+OyUFDywymaa8b7l4npVaCl8seWs2UMYDAuYRNE1xbFZ0AOWGfaKrY99laaGMexzi1ZntgfNdaBkWn1sj0H1vm2KjUL4IeGrgv3jWPMbNOiEJoXuEV2vng/mSUgzEz6LobWor2a/dE94SzOISQy8UGKB5fvytt4CaD5yWA3cEl+ciKl6+rXfAFCuugmsMiARQWkM3n1m0SitNqeAIFp/knl0Dd4W75/9SQT46gpAAutgaSjJButQKlnICC3xpWFCRFBZ9VtQQFV5zar2D3itEqKR5Crg03N2HprECt9C6LW+yLiNRMXB0R5ClYj6ILuohLtRnr8J5NAryxqa2foq/CNkLD5AO5TL8fQhNh53N6qSVMz8EzkkfSGUqbb83as812pCRxvwtkiSzhu8Si16h/nCMCp3YPM73qezuPHl58eFAlk7RwB/MA0jv7pHmxqu6oNHk3OqFukWcpdk4l9DMrfc7a+LR+PBR9U1jpALHYL5b3IeKkgEPkAr68um669KCVtrae6b7GV5hHVxnIhBgJOgFGxpcFwiEZTH0rTqXJko3a3RMaEYtde76IJmx5sOnI1T8YZPG8PktSZO6DEZmLuJ/rqBcarfaSINl9QGbldll79ttmFh+kiYNTJQ96EjeLt0SjIT3bvJ7XuVpct8rA8lTQSTlg8esS7DjwT3l/ijIL+dxY1cdMp3sWQRg+zEKEgGGFEskxbu/Q4ejh0TOM3VO3EY3 Content-ID: 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: 6f9a9a23-6152-4824-1ee6-08da60ca4d04 X-MS-Exchange-CrossTenant-originalarrivaltime: 08 Jul 2022 10:12:01.7809 (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: BHxj8B77a+DimGY2kdQjd9KiHb3LkHjTkEVcuK3g3KNUs/FWAM9E9L11nhwHGBOW X-MS-Exchange-Transport-CrossTenantHeadersStamped: BYAPR15MB2501 X-Proofpoint-GUID: u7KijVxezWURKmdYnL36j37xjxOeBwfT X-Proofpoint-ORIG-GUID: u7KijVxezWURKmdYnL36j37xjxOeBwfT 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-08_08,2022-06-28_01,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 --- fs/init.c | 101 ---------------------- fs/internal.h | 4 - include/linux/fs.h | 4 + include/linux/init_syscalls.h | 6 -- lib/cpio.c | 156 +++++++++++++++++++++++++++++----- 5 files changed, 139 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..6ae443a1c103 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,42 @@ 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)) + return PTR_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); + if (error) + 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)) + return PTR_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); + + if (error) + return error; + + cpio_chown(ctx->collected, ctx->uid, ctx->gid, 0); do_utime(ctx->collected, ctx->mtime); } } @@ -373,10 +470,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 Fri Jul 8 10:12:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan McDowell X-Patchwork-Id: 12910889 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 C2957CCA480 for ; Fri, 8 Jul 2022 10:12:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237934AbiGHKMV (ORCPT ); Fri, 8 Jul 2022 06:12:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56584 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237826AbiGHKMP (ORCPT ); Fri, 8 Jul 2022 06:12:15 -0400 Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7533784EF2; Fri, 8 Jul 2022 03:12:14 -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 2686HZ84022333; Fri, 8 Jul 2022 03:12:14 -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=mg/JdJHy3lG//CiufsHDJaVUwA0Sntok17tcu/D/eQY=; b=SDA3nts19MdpovVYmROfhsi7JYL+NHkQJspQ5NldzhL4MoILm1XadveaimcWsUAorm6J B7oKFDhNhJbWuwPN5jzGLK9Qwv6+weOZHBszfCcEp2i2XbmGtzL6HJ7TDeIeTh+c3V+V Vx+gNQbSmvcNAOKFKfFSlYpTZJSJJl+z6ak= Received: from nam10-mw2-obe.outbound.protection.outlook.com (mail-mw2nam10lp2104.outbound.protection.outlook.com [104.47.55.104]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3h6f69rxs4-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 Jul 2022 03:12:14 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=XpzMvo/DTg8s3fd2OFGU/TMf7IrXq1HE0oaly56XijezUeXvtaKgZPdqimHX6+51nDIIpE+8Gox+afUWJc6vhC57sotZmDhiWQTKTWcbXDQceyF0yXGmPqNiClBlMab3qjc7xJTsRuszgVBCFSIyzWYox2LeWVlopNxTBteJ3AN3FSl5rPTbHzTkyceabvdfCTc5STp/TRRGWD28ufMDeqTk7lZPZW7EG7WsAPDjc367XAwMb6V2mrC3Fjh/eyE7+2FWHn4iOrvQwnIPVDtfBwZOVslYLRVW4QDJIA/ZoEujEu4+QE0RiQs228+ra/bxXO6sxFCIrjIwlEm0rX2tTA== 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=mg/JdJHy3lG//CiufsHDJaVUwA0Sntok17tcu/D/eQY=; b=nUX8qVbnyanZ+AGBvqQRVrlUOi5GDhu5b708r+lZbQzZOdsRAC7B08UbxgeI7gV6lR/ueBbNSbfkfdqQk6TIZYYmQbApLmy43uw6BkUy7ZAILZJLPEqd+N5VYikbfor/4z/x4bsf5ej7YmSDNgi5lAMcA+Arwa7ZuCTMIwO9dso2qXRfwttQJ4GDLVV+onxEAFp5G58Lvb+NWWyhM9wdQtn3GGH0TNQq7YKl3o8vMPXUMRTtIzDYgrv0bAbvMKwk1aNQ5gXMu7S2ir7KCth6tFPPw/AR46jl6m3+9udlLj29nTydw75hgoEjJfZSNfNWIMWVTaiyBfcmoIowRWULqg== 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 BYAPR15MB2501.namprd15.prod.outlook.com (2603:10b6:a02:88::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5417.20; Fri, 8 Jul 2022 10:12:11 +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.5417.017; Fri, 8 Jul 2022 10:12:11 +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" , "kexec@lists.infradead.org" CC: Alexander Viro , Mimi Zohar , Dmitry Kasatkin , James Morris , "Serge E. Hallyn" , Matthew Garrett , Dmitrii Potoskuev Subject: [RFC PATCH 4/7] lib/cpio: Allow use outside of initramfs creation Thread-Topic: [RFC PATCH 4/7] lib/cpio: Allow use outside of initramfs creation Thread-Index: AQHYkrMwcn7RjV8qMUGa5f8X0WAuow== Date: Fri, 8 Jul 2022 10:12:11 +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: fc77a384-c0e5-46e5-31cd-08da60ca5309 x-ms-traffictypediagnostic: BYAPR15MB2501: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: GPFOJF4c5UuzCeA4qYVds6nBgBGYFXxEa0tjaNcKNQzvHZcQTbYgk3gFcLx9QAjkbAV2rDqJkGRWRy2aAr5aUMw7Fvlf7hPY/WBxJJUYivxL36ndmqBgNVuyVUzukOFjYpJpsGTvVYGXU5eBcBgPcQpkH7y5Pxoj+r1q8wt3MH6V585i4Ivd3lQ/sY89ijJ3YGj/8UCN6Hi3TFnr7Li37WQ11Z+wkSK4+Eca1sTBwGcw+6GPk92/NnLdlMAoU7Eg2yGHYbOrNEUL5K0mUtn8bx/i3sBlDUmDIT0pdNiE3p5qoxDurNyR6iZ9Cl3GJW42uOpMF7h2FRps/z/yaXSytYrqsxtdP2Yz61qnBAxEg0QhVHCA8xuf63oIZfBu0BYNC7SJc/4fm9AK9z7xmBVYZNTxYRaEbnqThIA2iv5Eu7icOpWs6INH+v7Qw35E+2t9gED/S1RTc3UitKYSwnzBsbEbMauWwtESl4Eup2hLaaPTftgUwMsA3R6GucHUPIJ+Eq0kl32Hkjeh0h1B3R+WlRme3dox64RWny9FABiFvrLCxNhfg6DtSQrEsDrEdD1jNygJWHVqZi1If35QRUYfZ8LnHCWXwt8Y7BlNg+X7GApyiI33njc727w0ATd3oU7SNqDRXXlSVbfw2EwwqhSxqUvnVxmQrMpvEhTn5OoMMAXncHeYj7TRcNd/ROGeSTOKgD9F7bJzlQoUL88zbKghf3yGCee3YVOvJT3vA7Hlw9Y+49HUeLOlgPOOlI+5HwDhfHoXwVqItgI5GSoiPRJCFkcXNUxErrxPRts7YwLGp1Th7DbwsrBFedtiGAXyNEKi 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)(376002)(136003)(396003)(346002)(39860400002)(366004)(38100700002)(110136005)(2906002)(54906003)(122000001)(316002)(7416002)(30864003)(83380400001)(8936002)(2616005)(5660300002)(36756003)(6506007)(38070700005)(6512007)(26005)(76116006)(91956017)(8676002)(66946007)(4326008)(64756008)(66446008)(66476007)(66556008)(71200400001)(186003)(86362001)(6486002)(478600001)(41300700001);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: W7plsep5qgGCLA46Ysf/ac+dRAC6sPNo2ejM16mONHantzIkHnoSgoYZMTI/4IkhdJO3xV3PSZUU7dpSdhVPb5XKDX5zZ8jI+4iX+g4DAQAUGyvy3O/9IlGcRbpCcyPmghZrlwnZeXK3VKkU3Sixp+Y4fMD0DbTU00rMzIieBq9nma7/YMunX5kghluWlVfapfoFRnugstc352X/FAiIOiApccGWWQ0v+qCBILN4GlOViRtzquJPW5gbjAShC8r2mepwCbOVwnvwP5X+VRiNaYVWxbmJDH4keV5qCo0DRDqadQqrlfsS8IB7wEuVP9lTxvXqWuRExRQuptYLuS9tMf05Kgdpt7Fp+hgo0YGrLABZqhSLgIJh3oDRrkRKiXzD3jK4fkiG3lbLVXhC+RuDOk27RZTy9L6d81vWZn3Z0Rzbmhj1pjiN1mStWHE2sTNtZ7atS/dBjRjldzwk/goLOBzl3Fl6mh8fs23+ppLSPKy8Tk3VpNO71cPnGX9pqvg6bab6FMSAev8vhRcJj+XXUKgx5TaNZgjAb/geg/fbgUh4H49B5qJAdJ2BLLtlxu9Tj+t7p/SX9kWgzFIdkt4Hctc1byord8zVSsL65uCSAVAvPGK3Si6Qtz54hZbolzEW04HBFu55CZZHqHo1ef7jIGKAGyWGEYlcPX0hskb7/9FzTLDRcNhHw3IN/qMEmKg+7nOwWB+oPJu6PfoY8J9nvpus17GxmPwsSn32NEhzr/dU8kuiHEIByMP7husojMM1NIcr3xrFNTdRE6MfJun8X/6ihFZNGKu9fd2EEEyhDHmu7VDKKYsGUNfuhxnWF8nhjXDA/tm+csqYw8IXthRiEX5BiUgWyxLQkRNwl9vu2CXFqIdBSGBZ1jBLHsbEopgb/xoLPEZCH1pJlXDv8e9qOynyTL/IpqOHnTpfpGUcG4Udu7qTbp5DaFYn29hY3eAyJaii2XantOr6B9F937ca1JIqOjV1BUtrKvwUv63IacX3sP1U2pIc7IctRfsYHh5P3fv4PHcJcYtHWFuh0TsP2YD01EqV8JLLYMYipkhfa2k6NaEh5p5Q5IgFqd0H2dIwtkH53hVF4QSh+N8whvSUooiZk37fWQBNOUN9UD+75iiF+myFOqxAZwqpf9KViMifb7Ith7MtT4StK6B2HCHf4470TLjwqo2mSZDXX1m4VwKRuRCKevx2oXV27hQ3GzAp4pOwhd4zyr2ECjwON89KZcnKzoR4AbqCQlBZ8Frma7on8S/l2u8K02Y6ml60tisC0lIx11QxwjRYD1FPdGRnpAtPfTZ0KQ0Fk1in4rB8DTa0AqosYVFXHKuMZfBnqJkc2ebwlu8bdXUTcG3N0P+UYvIDg3v6OZ+2FnScqWAK32rh4SBX42SAn0B0xHXL/rxxIWRiD7Yo88j44u+EaMkoMFbZJaylYtVSuMqs7b14AJP4KmXoo6RR4Oo3kXNpLgUY6pITldSJn64VRcaG+pfYXtLXU12yWkpfKJrRhegR2Gb3LQLwGKcWHt+J9w7ZmjIDI4fQY4UxEQXOSdCJrZ3NxsamOVLiMn6ZgUZW05LC9Cb5Lokoc26euXgbdN5mGGOg Content-ID: <3306CB3219946B499FFEBB779F9F1CC3@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: fc77a384-c0e5-46e5-31cd-08da60ca5309 X-MS-Exchange-CrossTenant-originalarrivaltime: 08 Jul 2022 10:12:11.8806 (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: of0lBE5vQJCodteXPRXiWoavoLwmctDka2QquQ08nbuw9IglLr6q+9EQzk2wahk1 X-MS-Exchange-Transport-CrossTenantHeadersStamped: BYAPR15MB2501 X-Proofpoint-ORIG-GUID: kp7xG-ALwE3gmzBmGrmQyAyR4xvFnOEB X-Proofpoint-GUID: kp7xG-ALwE3gmzBmGrmQyAyR4xvFnOEB 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-08_08,2022-06-28_01,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 --- include/linux/cpio.h | 20 ++++++++--- lib/Kconfig | 3 ++ lib/cpio.c | 80 +++++++++++++++++++++++--------------------- 3 files changed, 61 insertions(+), 42 deletions(-) diff --git a/include/linux/cpio.h b/include/linux/cpio.h index d8c1344a6cc3..b05140a565cb 100644 --- a/include/linux/cpio.h +++ b/include/linux/cpio.h @@ -11,6 +11,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, @@ -67,11 +79,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 6ae443a1c103..16629ad1e339 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; @@ -397,14 +397,18 @@ static int __init do_name(struct cpio_context *ctx) } } else if (S_ISDIR(ctx->mode)) { dentry = kern_path_create(AT_FDCWD, ctx->collected, &path, LOOKUP_DIRECTORY); - if (IS_ERR(dentry)) - return PTR_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); - if (error) + 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); @@ -438,7 +442,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; @@ -468,7 +472,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; @@ -497,7 +501,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, @@ -508,7 +512,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; @@ -526,7 +530,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; @@ -557,7 +561,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); @@ -573,7 +577,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 Fri Jul 8 10:12: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: 12910890 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 DD0D2C43334 for ; Fri, 8 Jul 2022 10:12:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237516AbiGHKMk (ORCPT ); Fri, 8 Jul 2022 06:12:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56960 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237961AbiGHKMZ (ORCPT ); Fri, 8 Jul 2022 06:12:25 -0400 Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B659783F3D; Fri, 8 Jul 2022 03:12:24 -0700 (PDT) Received: from pps.filterd (m0109333.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 267LPjkM002415; Fri, 8 Jul 2022 03:12:24 -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=vKUzmmaj9HD089hhxLbjvs0fUXwF6qLRWuimkKOR9tc=; b=odbZaz4jO+mv5h4T40r86aerUD52QnhP+ZY1i8ha2KWUu436elXfL43ZI4dQxQOZXJOO BOIZzT6fZGweFBTil7Dg6LK55Hwvo46Nq7YqSyXb9IINh+zqcH6daalahzxpb/xNylen lwVygHg8IvvOAVAuuYwLVqkkqMs9J58Ijpo= Received: from nam10-mw2-obe.outbound.protection.outlook.com (mail-mw2nam10lp2109.outbound.protection.outlook.com [104.47.55.109]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3h67d23c6j-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 Jul 2022 03:12:24 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=AlKn/Wk0WI6Jq9M9PThjvrNeiv45B2IvNsVKekpT6Anh/siD6UpDpSRrphPf7axtFseSPAqJITKUNVRRk9IZ04qfwiVg3q7ZPq3Kd7emOduk5OrIJ4ykrzphcVF38TgDVUxq30qb9pYqb6WZuGogxDlyqoqF2NI8NX4E5YG+tCMyRMG6QaiPo97jVyHuBQg8PVtYsCIL79VqTY0CCO6rFAY5FTGI701UfKTc18oRJkJ0opEcD/xLMkc/rllEOLgU7ve/9mb5BP9WN7sum46rKfzOkt6vaKVdWxDKONsbmmrMHsB6c8HvyeB6mRaP4bXnSgNDM3Y6969l0clid36Xsg== 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=vKUzmmaj9HD089hhxLbjvs0fUXwF6qLRWuimkKOR9tc=; b=nGyWPboa2kPPLFZznXen8Z6/a2VSMTQc8h+44dASbV/fVFfgGqnsO69Zpi0OKQVaMMsUdpqquzV2E2U6vZA4Qf0WlHB4zBiAJUlAe6cqdiczyNgv2pvPXGt52pBmle0PVGXRSGyHn73Wr9BKlIxUpNui0YTsM1EGGCI0Fjunwgdg0OFdZB7oCuK/y8011vZijvsD9M/ZcUVe2uVVLOf6GTrjobEIRHKei7b+ac8BCZgZ55lzXvHCictFE5AsmfmiQ3ft+tXl9Cd2S9IiFrhgc53q5VQn6MSgbjzGYmx7y03cUt2G1eh1MSJ5EBml97RWWwEbtkANMLjW/WGjRdaNsg== 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 BYAPR15MB2501.namprd15.prod.outlook.com (2603:10b6:a02:88::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5417.20; Fri, 8 Jul 2022 10:12: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.5417.017; Fri, 8 Jul 2022 10:12: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" , "kexec@lists.infradead.org" CC: Alexander Viro , Mimi Zohar , Dmitry Kasatkin , James Morris , "Serge E. Hallyn" , Matthew Garrett , Dmitrii Potoskuev Subject: [RFC PATCH 5/7] lib/cpio: Add a parse-only option that doesn't extract any files Thread-Topic: [RFC PATCH 5/7] lib/cpio: Add a parse-only option that doesn't extract any files Thread-Index: AQHYkrM2UIzPSfO/y02wvkpXYXbtcw== Date: Fri, 8 Jul 2022 10:12:22 +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: cf9c15bc-651b-4f73-0768-08da60ca5927 x-ms-traffictypediagnostic: BYAPR15MB2501: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: svbtnW8+4R/botIKPLcPPhQEiof4E4vT6+GlfoftHBkxw95+fVNKo9NYL/OO5Q1Ok8WgyDObH4G+t+rEFtgekfh1T2xr/m3AD56U8jYbFy/HZwdVKu2TozbZlseM8uPB7zxkFe05t0ipG4e0+loxKIZRcVikGn7venbYoqxM7zqgKiFi1ec7gLWeRQBcQJItyK0Gxy/gtrzrEzjGfq+pyCS8LRqmMZ1Xsx1tTKxlaMjQeO2gelhdVOESG6q9qLGetc5aAc2xMYSjaaeWc5b2hpMMlanRY3E7aw+dfCwUi0dljWJOkGjrZDwg4IcdrDF1lUSLKPwJwgc4Z+0N21BRkXEdZD6gYbCpcbV90SiL1sTJz/BkaSRrWDBWYtd+nV0MqUbkMuQMIF4XNDReYXkRHw+wqEnLtAIkvbLqkTxG0J4k/FmUpCsZhJCJOWUIk0vCKa0APahg3v9FfpyQozsEXljCHXU5/Hi+YPQ8Z5JglkBG+H/5ur6GQRmtMhamnnICsZn6QE97qw2E5ByZEe+uXeFmn/u/6pKSa/eQjy/Iz6AWuX5n4KuPlxzpjuMyCxQMkGUs3olhr3PM6MCim9wnZiNeMoh6Bp7XQioIDY9mzv4glzKE30W7YDfWRnXM7wUaG1k8lbeaaC5zO5JKj2Gna7vrCqB5c/VWuy5yMOblFlI/EJO8ugKPCaLb+VSdGZWv91oRqflc4NcK2vaUKA6W6ewluKgP09QgqilCGvHfHUofvjEdWRcYrOxFJGP6cAcQ7jUPXoI9nWp6L2aJtBYCP/qW2g+KkOYkQKPKL0XM71rgyJSRbrRFDVy86Hm8Y9ef 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)(376002)(136003)(396003)(346002)(39860400002)(366004)(38100700002)(110136005)(2906002)(54906003)(122000001)(316002)(7416002)(83380400001)(8936002)(2616005)(5660300002)(36756003)(6506007)(38070700005)(6512007)(26005)(76116006)(91956017)(8676002)(66946007)(4326008)(64756008)(66446008)(66476007)(66556008)(71200400001)(186003)(86362001)(6486002)(478600001)(41300700001);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: WSyiQEewKk72uRrJo6vTlJ5sTsju0ISQtOyM4AsEMZwV8azPdtCAZxyGksQEQEfsskrJZ6Q0rv7uDR5gOtIN/8hIYvw72JUh/CnEYHNruNFhfNvDFlKhNBQMURWIjA2QlaENDsXk7Qe2Q+NpsayCEhnBc5TyiDRNMQXO26pVewezLX4j6TxbKUrD7vhN42dDHYCylxtJQSd4qTVmJqkfOnTGACvfZiLA4k7TYhV3Tzf+GMarY2RVjde5TePEggTwMXg9UTyp9efA6nbaz0a8f3hdgkk4pi8rTsRBdYIyFO+zNuFBAKg3LRyfgnm0DUeuzXC0ck2yBrpc2i9plnPyWISQvhQBwaj5XHrVa5hEWcUMRHhhjbS3PBSzuNjngHjCPx9HEjxx/l8vjsSNvT4Y13q3mENwDyC0tVuukzgHPqyd89p7RYgXjsLY/AnwvkbYtqIc4Go2nMycr8WX86tme5/c90cCLf/OcxKwNZ/p4yEtTlHh25QmhPT7n5zAmbg3wxmRVVq+8M6x02EgRdszQpQbcS/7elK7F+b+TF6vR+kcfW2jO8v+PH1suIrrRTrkfaxk90BjuUEeAoOWxAHbm1pF7cTtnozKAVEZAyTfHZV4Oyndbdi3lfJKQhd7ZORW7vszXCA3qYl+WJogvuSuxYd2qbRPy8quMg71cmifEhk+mZuDwRikZLFra2qrdLelEl4JDCY0u+GndV2nYjQdx8WxXtT06ynyUIt3WUSzavaXDU5mWavxzzFnNuDfBu9mrtICqOZvH5mq8MHtuV5PDCIZy7Jdp7XOM5eEy92QLMksxJ0LjTLj1g48NUexv+elZBuFsoBdDujt5i5BqTZswk5kZSM8v8SPQ7NAK/+aNJ7sQq61/E6wpQFJbGyyRzOwxk1YlNBuUY/zxOBP0GHFeSFtu2jAxhv6FkJqPK7FCfYZtC7we4Ne4XIyq44s+yLIw4mHkNzbxiIHP0Pc7LysaLRGu6bDCmYdtHb3DCkSSHNAsTJJWy674KN7hQXj7jqK0kfLOtZYvsqe3HGeOyNCIX8/9Ed0P72k/3tKP45Q2mpVjF7uEpfGRa7AOofYb3h4EvR7Erql6WCVgixFuw0mD3EBigILM5cTYBNG9ec7sDAjvkJWuvzasiScDA5oU29vgnImAjLX1dBVPsJjdHNs4QlWDsIDduZjA9sLgt+OYCzIw8cxk7Jz5rP2bVz9mkJMz7x7pZKQurjqhYH6icwec5iUecXX5FS/vxDvmz30qSYypeEWTionMmR6+0uXVr83jAQjNdRYAcxqqQgzbt2lJavnl3T5H9a7/eErfgppYKcVnOvCOgcVvl1jp52QCJy/b3COK3hNt+XGIXejqy3jF4azoucWJsL9/M4/WAYmGi5cEl/b6jm9p0GrIAyue9UhFKxVq88+Et9OYFydiaTxqqYrHarNhcGcUNo649nOadfOBCPhSWN5xTMFOQbyu923rRPEsYPSwiXXE4i/CdkJsQnrSJ7sbX5OxhtJsOFHDhIKLvljZwCoRLRRk6mgpb9LOzHxXYFMcPjs2FXm56aZXBnM1cMpIN3i0oI5BCxrNaSM6yFMv9AqBY50dsnbz9UO Content-ID: <0BEEE6E71A15F449B39A5A2AF84B6F74@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: cf9c15bc-651b-4f73-0768-08da60ca5927 X-MS-Exchange-CrossTenant-originalarrivaltime: 08 Jul 2022 10:12:22.1268 (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: zdp7/B8hTBq9FchY0v7PzPCx9QAT6ztgCcKfS5j5+fxQUVaqysFzN2tgGcfDF5pa X-MS-Exchange-Transport-CrossTenantHeadersStamped: BYAPR15MB2501 X-Proofpoint-GUID: dfGwPNSXUFXQGG0wBPbnBPYjVR2Cuyo6 X-Proofpoint-ORIG-GUID: dfGwPNSXUFXQGG0wBPbnBPYjVR2Cuyo6 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-08_08,2022-06-28_01,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 b05140a565cb..86a43270d186 100644 --- a/include/linux/cpio.h +++ b/include/linux/cpio.h @@ -77,6 +77,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 16629ad1e339..36357806eb70 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); @@ -452,8 +465,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; @@ -478,6 +493,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); @@ -496,8 +517,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; } @@ -579,7 +599,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 Fri Jul 8 10:12:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan McDowell X-Patchwork-Id: 12910891 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 89F97CCA480 for ; Fri, 8 Jul 2022 10:12:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237826AbiGHKMl (ORCPT ); Fri, 8 Jul 2022 06:12:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57090 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237988AbiGHKMf (ORCPT ); Fri, 8 Jul 2022 06:12:35 -0400 Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1E66684ED8; Fri, 8 Jul 2022 03:12:35 -0700 (PDT) Received: from pps.filterd (m0044010.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 2686IFFj028448; Fri, 8 Jul 2022 03:12:35 -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=D5UZlRMEIRV2T2pFb6Ty03JZQMkDGOiv12a6PyZkxmk=; b=H9wQj4vFte9ukhIZaD7o7/VUIQ/WwF++Clqe0DPgwrXzwTdyz7INADkzmBXGQTXO3L/1 K44A6T7afbX0o6BiZhlKE9zfEvo0cV3Ln45ScwDNcay5f9OjsSFBkrNUNZGqMFwMsr9R N+BqNpYO0fQX0XEI69yMD7IfH9PptfUAnS8= Received: from nam10-mw2-obe.outbound.protection.outlook.com (mail-mw2nam10lp2108.outbound.protection.outlook.com [104.47.55.108]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3h6f69gxqs-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 Jul 2022 03:12:34 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=dz8HRg13MdJPlupmouOJCpvnDK9r7ZaFDD1W59BD+A7fDnxqfjWW59w7RBgnZOACUF5LEAEqsxUHEEvwPX1H9t/DlMzmCtj2/bUOrEpsJmV61Bvw+Tvnw6XXNheN4D3MO/9SBgbXlJRPPUmXYlYetSQ6MnrAZxCQ+t5yEjwEmBopH203tNsy7xZaahLPp/941crJ6pUW+5rqOkfG+lCltbEkJWzvBtqTrzVf8T81xwgjQmqVT1ndQDMK6Arszm8MbOggPa+PbZFPNrLmzRGIMxbHzodcF7tLx6yUF4gyCPOS5VN+6NotFkQYbZOQJJG35xb5bJMaHNBKqWa1ccNp7g== 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=D5UZlRMEIRV2T2pFb6Ty03JZQMkDGOiv12a6PyZkxmk=; b=iA+2v5w8uESd3GLqd79E6ek10YASlh5dOEg1d2Q4A2p37SuOOGMzpBKTWGdb7d22Do53gS4/MDjWMrqZSKOs6q8iEoB9s8m9RvRjua9bpNTjf231/u476XB0XUL+Ew3YdQdiQmufgWrpHOIgHk9B5uZsi8RyeiVJ3m7DfmIntjdf9eZsOREEr+P7bC5mWbnZE9UEIMt4Yo82DkzduAjPb7DXAOkE70MBNs3/B3gqDbN2ZyTktAse/mra3GJhWGGO7o5kexftjJdAXLed6svvFXZw/HvR+CwdrsJgZkTs9shaA30iiOX1bEwBlrtIIQMzDA2pPGrXm87yJk4IHQ7QTQ== 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 BYAPR15MB2501.namprd15.prod.outlook.com (2603:10b6:a02:88::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5417.20; Fri, 8 Jul 2022 10:12:32 +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.5417.017; Fri, 8 Jul 2022 10:12:32 +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" , "kexec@lists.infradead.org" CC: Alexander Viro , Mimi Zohar , Dmitry Kasatkin , James Morris , "Serge E. Hallyn" , Matthew Garrett , Dmitrii Potoskuev Subject: [RFC PATCH 6/7] HACK: Allow the use of generic decompress with gzip outside __init Thread-Topic: [RFC PATCH 6/7] HACK: Allow the use of generic decompress with gzip outside __init Thread-Index: AQHYkrM9uTGnvX3+A0mmGfCUTcA11A== Date: Fri, 8 Jul 2022 10:12:32 +0000 Message-ID: <942e53a4062d7915b5e90e370742f18f42741fbe.1657272362.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: 56ff9d7a-e73e-4b80-6bea-08da60ca5f90 x-ms-traffictypediagnostic: BYAPR15MB2501: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: Xz89tZ6E1RWzoPXNXP7EPQ/yhEWYzB0wLh0Be+JSMntO9ycXHt67EsWMYYlH9zk+2RL8qXKthKdcZGKXdLCiy/2EcOGrc5XQebtpsNM8jyD3BAALzdSq/aNxc8F7OAh6dGBpImJTAGHmWtHxkGlce4u4s7Mihr1tLYKLKhJoMZQNBEOgB5CxcXvHoxe30BnduYTeCLCvc0Qli8WDLsDQuO4jPx6zYc/Mulv2MuLlQRTeZ2XzMCxC0sO6ESy87KkgpOqsrKcpEg916xvoyRp2yjfKeOonHlQ4ahAdXV7u2SCoIM3sXQWaA8IaUEe6FJ7emETWBaOgDd6CPGtjEz4Z7Q/9GomKoVc7wPF/URaRrlzR0zQHH2a4xP8TS8dXbnl5lKZSw906DUGg2F9lXOgXaoBzojVhNEzMU1wvggpnXozUuwDL+4YCN2SJHeUDjs0y9LcLqvqhg3Hx5oSPegJvU0epFo29axGnaa0JeWHTD4hBmxbNu5tvk9LoHsGk+09e0Tm1Zq4UmNBADjgMJRgdmoXcTLMM0mujNB7vqOJxF6Wdl7FAq/Mh4VUAhLVSggsjN0Yl3wJwfW9nUJ7LYaoff7XzslZDVB7y9t0Ghbinwni4kLe1ClDXpErDEjBQ5BGGSRcsnAKW/7SK787dQ7jfutNEMEzgnCAz5kCUgbN3KdU8Y52b4PS9fEktZ1jBJ+a5OEv/wg6s1r+UyJK/HDDePPUnNyEPauEeD4R5BYoslsn4qMNcTVGKrPgESOIV2JY7q/4xoXqyMBaryhoSNAnT8d8r0CJKyb4iUo0Y0s9L9dxj/3E1A3FXiIUQSdQuo4W+VN1KGmrxLLnBNV4Cl05lNg== 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)(376002)(136003)(396003)(346002)(39860400002)(366004)(38100700002)(110136005)(2906002)(54906003)(122000001)(316002)(7416002)(83380400001)(8936002)(2616005)(5660300002)(36756003)(6506007)(38070700005)(6512007)(26005)(76116006)(91956017)(8676002)(66946007)(4326008)(64756008)(66446008)(66476007)(66556008)(71200400001)(186003)(86362001)(6486002)(478600001)(41300700001)(41533002);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: xuIsnMou8Xm2uXRyfS1tNT0ZNqYxL3DGCa9ndwigcx679+VajcF976vbXzHXgMhwUkpPQe92Fmun8TOhR09TMD3jY/fP1f09UP1pMdbNicZxfrg9aEoS8IzFooir+CmS/LWQ3bObLNijvye0lpG1gp2nOuqcxD+q8ysJm/NHCUZRINsK/h+GHKp0GpgGMRkp0DeZ3ceQk4KtFHzAgQeFPqrbdsZaWIMPxLa04uVBk7+j+/TajZSy7+qc2FYDVIiVHai6AI2E7Wn6dUHVwlL/fzJXfKFHR9wtRDTAoXQyxgSm5RWEW6nvlSNex+pIZftUjTNFo22a7Jc6FjUlyYbhApAmkiTyFxcpwPzjizZebwlFaDo7hxhsvLmBsl93ouUVdVBOv05C0vsU86/y8JC6KXA3LuAMEvmcMm9VmrUZetU/+LATxc4eVrhdXbvPxNKvgv7POz7rAgwVebfoBFJaR1vGQlOyGBGcHJnnOabN+M2X8LucszGittTyTIHRPHnOctbZM3V4motiKFU7k1Orb8Wgi87Rlr8YwpuZpoAOagc+5X3irxNWDlI34stsd+REHpDEa3a+Q7aJpBZmDpZIeXZNrjZb9CZmwO9SPO20ea429iayTVJUryboGKzObb/AoBIi8a71YUYvB3YEc2L8NYGeoCnV9foS6hP83NqcwRuMRaIH3QRaH7I6QvqAcDx227ImYjwLL28KQ4ejik+HvekwCCcfrVLhBlxBTy82/M0JBssXpKYNk3BtxI84qUpUqx08Tr0rNpr9MBBIStzz33tEXw4JRJToAkv5St99VZMpCJh/1Ub/RU36UmBF5jnwyJa1S15JIatv0S4EmEOa+LNF9doK7wSWf29EVkG18lj4jFn0UjOge9fVDV8D6dXx8mooObh3mffwqI4GxI/BHl9GTr0NvZze3ww0wsinUmcPnjamWg47pGbhBBQhVMeN/UK7e0xjml5pfhSHp2151nw6LGukLxyFdqNwQVx6uaR/cdFPDEC9NZlINZJrQul8kp/KDhHpqkO1G3n0NDTo5qwtD5aaFW3/yyWw01j79vdWJenaUdiQKqYG3Ps9G0/qi3nOAEXTcWvgtavlhhcdVHqT0Wp0F4TgkWn1mhoVjOjjRAnqbsNkBH4FELx2dU/s4IsHyQp75Jq0C4YDBJXdWvAv+sGKhFZZ2Rj4lYy75Ry58s1EAhO49MZwSFLxmE+3ahpoMXnn3SShgcK4uMVQmVLNXBfuaN9LZzgwN+cIUXAbV8u81/RCn9k7U46RUN2MKnRrONuY0KYFPANmEzxm3x/AZfPIKXQC/dpj9YGdspUD1VnlY7AFO6bK5mby33dTP3HoOy+MJVJwIlBbVrj9tjdXLpYs9h/KDuDyiQe69ecqCiH/+mfM2ihYW53GPpk3+OxadBGm+FWrUZ+3sj8ByNaO6RLO8Lem9AWrb+TihJc+Qbnr9hTIlBqYscR2c6vVXfZVq++pTtrtqLUiRkDur75u49qm3dLYK9VUg9R0ndy8acdlRsQdZX7lG7u99nBdiVp/cMi1wXyhJ3NZqsV9DmGNCPKhl+fh+n+xx8H0cDYrk0/Jv4PCMhu2E9myBCLY Content-ID: 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: 56ff9d7a-e73e-4b80-6bea-08da60ca5f90 X-MS-Exchange-CrossTenant-originalarrivaltime: 08 Jul 2022 10:12:32.8993 (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: k6BSxXFMrnJOxc1pTr/X9jvGxn4fAj2UamSfHNamJZqRtngLLQX00wZcemkgACHp X-MS-Exchange-Transport-CrossTenantHeadersStamped: BYAPR15MB2501 X-Proofpoint-GUID: 2mNxPY7shnpBdOyeUn52qduFvv0AaXmj X-Proofpoint-ORIG-GUID: 2mNxPY7shnpBdOyeUn52qduFvv0AaXmj 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-08_08,2022-06-28_01,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 Fri Jul 8 10:12:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan McDowell X-Patchwork-Id: 12910892 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 AE1E4C433EF for ; Fri, 8 Jul 2022 10:13:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238034AbiGHKND (ORCPT ); Fri, 8 Jul 2022 06:13:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57366 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238003AbiGHKMv (ORCPT ); Fri, 8 Jul 2022 06:12:51 -0400 Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8A94284EE0; Fri, 8 Jul 2022 03:12:45 -0700 (PDT) Received: from pps.filterd (m0109333.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 267LQ5tS003531; Fri, 8 Jul 2022 03:12:45 -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=zjZxs3sHJCcGfe2WaxNN4wBqJbhgFayELS86JTHs9Sg=; b=DrzGp/QosIM2Jyf+0p0OZaseK/OIvYEev/xoIEB3jHWRv3QgsJikn8a4L8SQ00xBjU+N RsmTGUy01xwu1AYK8VSX1gv8h8gAtprK+RZenEejvAF1qAetuqMXZjGPaotJ2/qbjBeg UDPeeJaSbko5SH2MezgQj8t8pjN6MsaBVhs= Received: from nam10-mw2-obe.outbound.protection.outlook.com (mail-mw2nam10lp2106.outbound.protection.outlook.com [104.47.55.106]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3h67d23c7w-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 Jul 2022 03:12:45 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=mN0qUfoHPS5jpS5JB+pYHYQtCRMuFgIsyQ3Gabx/dx5CMnk82lYZIsC41t8CkPoceZjE1XtfC2CQuhDPI9M/jsyWbGI/4Zt96SsN8kvqE3PenL0A0ZxvYNZTeJQUJKskZcL42eJlNBiVRj5cGrgEiKx+7PRDDFnNlTWw0RbWvfEcSmiAKCkFvYFNrpNjwIQf52DvMf8kMk0cwrZpwraiocojp8YRoGInRjmQmzX+S/Nb07YldSZQnjbGGZu0kuH0siRj73Zzu4w6aHzIrStZicy5MTgrtCQRZ4Yfm9fqhwz/8EAzPPJOHSq5qfiLX9BpYQOcDNkRFoMzJZQc9+KFww== 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=zjZxs3sHJCcGfe2WaxNN4wBqJbhgFayELS86JTHs9Sg=; b=m4BoQ5TCKVgAgvBo5H0CuE/cb4/1Uc8/Xy3t8+grtgaDkFHPgFIo0ekX0zPMUwk51THFGXHgZU++CN79QOJtpBPUO0lLB8jvC7ZjQsnWePZRG4G5Xf+CcSVVfFbja5Pj1Y3m8/3OfdajscVcJxD/yn5soLU3VyjuitWWvNXB5Phz83QoahmYJU3hcn1zvSGpeit2v39C6gMZNumlnYLvWeXh+Vr30nk4mIH5ZARjyyhcDIn7TSd1vtQ92K+g7TXlgGrrJbqDQW1jrG9fEnmFQnaI6vVBAEboo3zLqvNPgPHddizf4SQgHv1x+NSpFQ7nEwkmxj6Aaw5AmVcaeKAJSA== 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 BYAPR15MB2501.namprd15.prod.outlook.com (2603:10b6:a02:88::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5417.20; Fri, 8 Jul 2022 10:12:42 +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.5417.017; Fri, 8 Jul 2022 10:12:42 +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" , "kexec@lists.infradead.org" CC: Alexander Viro , Mimi Zohar , Dmitry Kasatkin , James Morris , "Serge E. Hallyn" , Matthew Garrett , Dmitrii Potoskuev Subject: [RFC PATCH 7/7] ima: Support measurement of kexec initramfs components Thread-Topic: [RFC PATCH 7/7] ima: Support measurement of kexec initramfs components Thread-Index: AQHYkrNDsat2nr2ZjUCutP79WCPZOA== Date: Fri, 8 Jul 2022 10:12:42 +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: e4be3d2c-f562-473d-fdb8-08da60ca657f x-ms-traffictypediagnostic: BYAPR15MB2501: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: 2D66VnBiNdVwZsmRWbqOZHKUZo1/xzzn+cSwa1zazDEXgaYCKEsKsa4Mf+Q8Hxm/9M4Ur8BTwXTv3kA6vfVeCvOS5cWnNw0d7rZntRz++arIrn+IokBzXX4cKEDO3HV43AeC27NRau0b1oYzKSkOYjkWcvYCkyDIJLsfUszjNrV5/Mx+El48BbQylv0UuvmH2QPWyKcWAUyPVD2wP5snRfrbHdsMY2mGK4H0oyBbwHxV5wMOCmn7ijQRyhozvGeLXcTJEiC8QUW0qlM+Oi05g1TXMZfzj6hV17SVibXmZPqmKE9P7SkL7+I7ELnnYWTVOp+jlsPRsbGY9NGpTP6LREgH9Jw2kGFdZWmwiSomgmpFPyyBnZtcuPdnaN1TpKaGHlr5iRGZTcvGudQfx4G8FGrCLBI1TGoG4jvDelgKLBtotOODt7gc8dLMkfr6jb8nTfIxkiwFOniudELbUhHtCennOnR/GbQ/AJcQc2898WJhkcHIIw8olJ98D0R2hnwT8ypD/ogxDuoIk5DnzmtUT5sbSqK7aej522ptvMds/Uf4ecPlGaB27j73CXkP0iZdcx/3Wy4L+lY+ZpcyNk84/zHUWuMAn5MBiQllERYMo9KLho2TbvGoJjRu6XFSWEvoZzVcBjt5xRxRfXy2QCuoSuJ1gwwlSbtSgtAh+eGSeE9YEk+uv0weSUrpExz4WqAvhtmE9Ajy4Q3qzOs8+ZrKhQ1b+1X1Bc4ZKeFQcYL5vJmfhRBWZDiXbAFNF4cvsAT3VnZrxj8kp+mf1t4nfzkW524J5RhxxHnRQkDLDeCjy7jNkun654D7+ir0mYSi702X 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)(376002)(136003)(396003)(346002)(39860400002)(366004)(38100700002)(110136005)(2906002)(54906003)(122000001)(316002)(7416002)(83380400001)(8936002)(2616005)(5660300002)(36756003)(6506007)(38070700005)(6512007)(26005)(76116006)(91956017)(8676002)(66946007)(4326008)(64756008)(66446008)(66476007)(66556008)(71200400001)(186003)(86362001)(6486002)(478600001)(41300700001);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: ARjriCiTSV+Zv29LiNfp08sxvG//0y5t7e3Y1HN7KCZ4Fp2hoZ4+7JGV3wF53OqCnRN/2F8sfgPD+HFeaaFuxwTTyfU2UsT2SC5uG9QNBIp67a4LFyBpLI9IjoGijhElVkTHbcYZYSYqnGnowBS08eXBpAO7GCtCCYZZoqhegaRdAnFlVudFa8UftCmd47QaaP19T2G4T5HxgnotDNGRksmzL1WR626AraEIW0QNC5NlZFPBCK46R7Ap5I9FCfEWvBxN+5a1uSsPyoPZIi65KMvA1zFktm/U/e3UaLc/UwPqqqygS3Tfgi2qD6t4mcm/Jlg3yBzBSDFRsVSExRhbBflO32maXYI74qmtXRNoUGwmDfT3EdvINofT9pZfdE5474R4jfkgyzNZjbDdGN7LyXCXxVBIcdee3l4777Mcb0Xygst+o4reuj6o4AGpht6AXDswIsbZw/7CNCAUoAmoC9HUmFr5ubDjSwo5qu4Hc6k0rOUWH+Me/W9NrRrcSpWlNelmRPVTzGA7wlQQDac/trqsaQgiBWpmEMXWzA6LbnhrE2PLkyGaJJ0teC0pez12re0JCNFtnKq2gonKqhy2NDcvEQZde8Kjg4n/DKCdRsZN6rka/QqQPT3xuaqs/RYVkXoP43cT6LgMcXvOcM7FDNZsF1Z/nI8dMbEqDTI4r9id5ZHWZ28+S146CHPed7Qmenusd4wtz7+IasB5aRT5msn8hoa2SxtsjiSuU0awQdqwrPWTs5nDKxnvhyOORaztfzi5+D6cO+IJwgpLX3aKi6QDQAsOlHwWhfxForQWH+W0+flBn5fd2md12oqouVqmMhH8+eXyyG7HovaZjwji7kg5IczO5HQPzVTG/5f3qfK6LtpcVYicTBnTkSyXq+36b/jniKcVQg9ypISBklIoPnMV4ScqNU3x+PLL4juzSckHNUm8KJdblAvyU+0MCsOUJbDAaw5gAx41K4K8v/hGSf8zRvS5dCvgeOPmxEuUW46KopgZgwscPbdeIocERgjaei7W5DZf+tOg6oFPBEOjiveli+6cEOjgpkdCJbvBxH6xPNvbU6tv/4i1VocXfbDN1bmctqakUwik1g1p1IDgD7ZXCUYxn+CiWBHd1RZi/HmbK/z/fiP8P4TM4saC9HAgGyqtQ6X4PcOlyK+iZUhMposD6RyfsYNKc0MvKfzaPpyGnC79Pah50e3aKWmUre/TbqbsXS2BcC15s/viT4b/jR9PaCUIp01zN7k9sFkaY694mmfSlON9/ONs0x8j/sF524vjHPoFcEvGYm4zl0ftycGCDjZKFmo3uKdf5IYfULzPLnQgv5rzpNU5fZQujB+OwZ8ziMB6ROXhe9vWPYnLFCbBihpjvBypVvfofxs15LSquBxxOx16cILx3S7+KGXOEPyFvVxiQxgx7zBYsL0WVMOqEDqfe/u6DmGRO+VGSXN6YLZ0Luss8kH5zMInzPqAzrskeSYzg4+xRE2Besu0DhRUG72Q8Tb2OemUg3Qc75TgmcFrtMQXrAiM6obYx321SH8Z6BFmGa7IPUd2IjT90qZUzr+wEka40noVcvVJaQ1LVUsuEhxv4NadJS1BpbB1 Content-ID: <44B9BED31809C24DBE92192698654E43@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: e4be3d2c-f562-473d-fdb8-08da60ca657f X-MS-Exchange-CrossTenant-originalarrivaltime: 08 Jul 2022 10:12:42.8737 (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: TXIlD1GSxQyOahVixBQnULEq6s2K5Y+X17vPTGiMYsm+9vAAs6uZGtx5tWiG90E6 X-MS-Exchange-Transport-CrossTenantHeadersStamped: BYAPR15MB2501 X-Proofpoint-GUID: Ud51Ebe8-mman3GWqjyu2wzU2rc49v5R X-Proofpoint-ORIG-GUID: Ud51Ebe8-mman3GWqjyu2wzU2rc49v5R 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-08_08,2022-06-28_01,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) {