Received: by 10.223.176.46 with SMTP id f43csp1571006wra; Wed, 24 Jan 2018 19:40:43 -0800 (PST) X-Google-Smtp-Source: AH8x227reOW5cFA5coBsU+z03lbtfgF2BImSXx76cOO5XtcCPi8U5j+NCd64Rhk6pRJbWkMZ5kCp X-Received: by 2002:a17:902:b109:: with SMTP id q9-v6mr2749706plr.396.1516851643876; Wed, 24 Jan 2018 19:40:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516851643; cv=none; d=google.com; s=arc-20160816; b=HKqZbVWkxJhXyRKmYCF+mA/G/i4ME+4VL5Cawefo+nMvZOO10jIpzUQNmguzFsXRaW Vxqroq2Na5RGIwZF5gLrvgMQ5XOpK3g0y07favNiPCoAssuoIRj2u2y8x3xo5sZH6zjz Iry5aGx3wkkiKJepxfTZlZzoMuWYZWy2NqWydyt954Xg88ELY5CneKN3xa4HbE96cw1Y bXy4zcDg7wnOjU0RaJyESMRWai5tw2SLXiBJjHELhQDQSN3lJvzE8Hgpauv2+xpi4e4B 7iDhj6q6TIPT5v/E9rWo0Wtlx2xfXW61Kk6cQ/yuFHpY0iehSNB8U61oerJ9ffz7srBn cS6g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=qYz6BZDfkTRecaPPVsTeyK8in6h5PqZ7+JeplT+9fk0=; b=Jv9s5AL6k8Mj8L4GhK1bU00EYFYoNA15fdhEFgGb75+4iVq5d7niisiublO+RLt3nq viFuHsHuBg7Fi8c4p6LVTCsGiOJnXlU4JkNb9wyHuiJhyN4ICfUMzcXzzVNwSEje1Urh LMWHONTtJCkIP7CbhKvtAILObj1BjnT3Td4EdqnPckMJhdG/By9ZoBd18A9ZVYKKUezZ 9wsOImKllrPIfLow7I9rn0pDJu6hRy6+w4OBBl5XuQlkTCkdRUj6fLQdfXuH8hHyAlDI 8MT2Gp3uhguWcgaaiEP/UxbPhR2HHLhWnMupk2FiTAvJ3TmKeHWuRxQ4m1UALO9I112I Dmhg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@cisco.com header.s=iport header.b=hm1XfgWv; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=cisco.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z21si970397pgn.768.2018.01.24.19.40.29; Wed, 24 Jan 2018 19:40:43 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@cisco.com header.s=iport header.b=hm1XfgWv; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=cisco.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933517AbeAYDhf (ORCPT + 99 others); Wed, 24 Jan 2018 22:37:35 -0500 Received: from alln-iport-6.cisco.com ([173.37.142.93]:21061 "EHLO alln-iport-6.cisco.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933490AbeAYDhc (ORCPT ); Wed, 24 Jan 2018 22:37:32 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=6633; q=dns/txt; s=iport; t=1516851452; x=1518061052; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=Pc7OJ9KRr7DC1sXDDCdANvV1Mr8g3BTUvvTi8ckcB34=; b=hm1XfgWvo7mfSpZK/c6qau566hJvMDNDSSJHwNWXsb0X+Bb2jmRS2aBH cvEgXVrXydXEbakWNyo2ubBZ35cD/R/xMOycMoR4ER2Kt8eQ3v16J9XV3 DIkV33ofs99aTLhn2iHlgNMKCfrFJQ2yozZr1J0IrdpLMRjJWocXRCn1F A=; X-IronPort-AV: E=Sophos;i="5.46,409,1511827200"; d="scan'208";a="60773962" Received: from rcdn-core-6.cisco.com ([173.37.93.157]) by alln-iport-6.cisco.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 25 Jan 2018 03:28:04 +0000 Received: from sjc-ads-7132.cisco.com (sjc-ads-7132.cisco.com [10.30.217.207]) (authenticated bits=0) by rcdn-core-6.cisco.com (8.14.5/8.14.5) with ESMTP id w0P3Ruix007601 (version=TLSv1/SSLv3 cipher=AES128-SHA256 bits=128 verify=NO); Thu, 25 Jan 2018 03:28:03 GMT From: Taras Kondratiuk To: "H. Peter Anvin" , Al Viro , Arnd Bergmann , Rob Landley , Mimi Zohar , Jonathan Corbet , James McMechan Cc: initramfs@vger.kernel.org, Victor Kamensky , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, xe-linux-external@cisco.com Subject: [PATCH v2 08/15] initramfs: add newcx format Date: Thu, 25 Jan 2018 03:27:48 +0000 Message-Id: <1516850875-25066-9-git-send-email-takondra@cisco.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1516850875-25066-1-git-send-email-takondra@cisco.com> References: <1516850875-25066-1-git-send-email-takondra@cisco.com> X-Auto-Response-Suppress: DR, OOF, AutoReply X-Authenticated-User: takondra@cisco.com Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add 'newcx' format that adds extended attributes and increased size of c_mtime and c_filesize fields. Refer to Documentation/early-userspace/buffer-format.txt for detailed format description. Signed-off-by: Taras Kondratiuk --- init/initramfs.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 85 insertions(+), 10 deletions(-) diff --git a/init/initramfs.c b/init/initramfs.c index 7f0bbfde94e3..3d0f46c28459 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -54,6 +54,7 @@ static void __init error(char *x) /* link hash */ #define N_ALIGN(len) ((((len) + 1) & ~3) + 2) +#define X_ALIGN(len) ((len + 3) & ~3) static __initdata struct hash { int ino, minor, major; @@ -154,7 +155,8 @@ static void __init dir_utime(void) static __initdata time64_t mtime; static __initdata u32 ino, major, minor, nlink, rmajor, rminor; static __initdata umode_t mode; -static __initdata u32 body_len, name_len; +static __initdata u32 name_len, xattr_len; +static __initdata u64 body_len, mtime_u64; static __initdata uid_t uid; static __initdata gid_t gid; static __initdata u32 mode_u32; @@ -167,6 +169,12 @@ struct cpio_hdr_field { const char *name; }; +static __initdata enum cpio_format { + CPIO_NO_MAGIC, + CPIO_NEWC, + CPIO_NEWCX, +} cpio_format; + #define HDR_FIELD(type, field, variable) \ { .offset = offsetof(type, field) + \ BUILD_BUG_ON_ZERO(sizeof(*(variable))*2 < FIELD_SIZEOF(type, field)),\ @@ -177,9 +185,11 @@ struct cpio_hdr_field { #define NEWC_FIELD(field, variable) \ HDR_FIELD(struct cpio_newc_header, field, variable) +#define NEWCX_FIELD(field, variable) \ + HDR_FIELD(struct cpio_newcx_header, field, variable) -#define CPIO_MAX_HEADER_SIZE sizeof(struct cpio_newc_header) -#define CPIO_MAX_FIELD_SIZE 8 +#define CPIO_MAX_HEADER_SIZE sizeof(struct cpio_newcx_header) +#define CPIO_MAX_FIELD_SIZE 16 #define CPIO_MAGIC_SIZE 6 struct cpio_newc_header { @@ -214,10 +224,44 @@ static struct cpio_hdr_field cpio_newc_header_info[] __initdata = { { 0 }, }; +struct cpio_newcx_header { + char c_ino[8]; + char c_mode[8]; + char c_uid[8]; + char c_gid[8]; + char c_nlink[8]; + char c_mtime[16]; + char c_filesize[16]; + char c_devmajor[8]; + char c_devminor[8]; + char c_rdevmajor[8]; + char c_rdevminor[8]; + char c_namesize[8]; + char c_xattrsize[8]; +}; + +static struct cpio_hdr_field cpio_newcx_header_info[] __initdata = { + NEWCX_FIELD(c_ino, &ino), + NEWCX_FIELD(c_mode, &mode_u32), + NEWCX_FIELD(c_uid, &uid), + NEWCX_FIELD(c_gid, &gid), + NEWCX_FIELD(c_nlink, &nlink), + NEWCX_FIELD(c_mtime, &mtime_u64), + NEWCX_FIELD(c_filesize, &body_len), + NEWCX_FIELD(c_devmajor, &major), + NEWCX_FIELD(c_devminor, &minor), + NEWCX_FIELD(c_rdevmajor, &rmajor), + NEWCX_FIELD(c_rdevminor, &rminor), + NEWCX_FIELD(c_namesize, &name_len), + NEWCX_FIELD(c_xattrsize, &xattr_len), + { 0 }, +}; + static void __init parse_header(char *s) { char buf[CPIO_MAX_FIELD_SIZE + 1]; - struct cpio_hdr_field *field = cpio_newc_header_info; + struct cpio_hdr_field *field = (cpio_format == CPIO_NEWC) ? + cpio_newc_header_info : cpio_newcx_header_info; while (field->size) { int ret = 0; @@ -243,7 +287,15 @@ static void __init parse_header(char *s) pr_err("invalid cpio header field (%d)", ret); field++; } + mode = mode_u32; + if (cpio_format == CPIO_NEWCX) { + /* Microseconds are ignored for now */ + do_div(mtime_u64, USEC_PER_SEC); + mtime = mtime_u64; + } else { + xattr_len = 0; + } } /* FSM */ @@ -254,6 +306,7 @@ static int __init do_format(void); static int __init do_header(void); static int __init do_skip(void); static int __init do_name(void); +static int __init do_xattrs(void); static int __init do_create(void); static int __init do_copy(void); static int __init do_symlink(void); @@ -291,7 +344,7 @@ static void __init read_into(char *buf, unsigned size, fsm_state_t next) } } -static __initdata char *header_buf, *symlink_buf, *name_buf; +static __initdata char *header_buf, *symlink_buf, *name_buf, *xattr_buf; static int __init do_start(void) { @@ -315,22 +368,34 @@ static int __init do_collect(void) static int __init do_format(void) { - if (memcmp(collected, "070707", CPIO_MAGIC_SIZE) == 0) { + int header_size = 0; + + cpio_format = CPIO_NO_MAGIC; + + if (!memcmp(collected, "070707", CPIO_MAGIC_SIZE)) { error("incorrect cpio method used: use -H newc option"); return 1; + } else if (!memcmp(collected, "070701", CPIO_MAGIC_SIZE)) { + cpio_format = CPIO_NEWC; + header_size = sizeof(struct cpio_newc_header); + } else if (!memcmp(collected, "070703", CPIO_MAGIC_SIZE)) { + cpio_format = CPIO_NEWCX; + header_size = sizeof(struct cpio_newcx_header); } - if (memcmp(collected, "070701", CPIO_MAGIC_SIZE)) { + + if (cpio_format == CPIO_NO_MAGIC) { error("no cpio magic"); return 1; } - read_into(header_buf, sizeof(struct cpio_newc_header), do_header); + read_into(header_buf, header_size, do_header); return 0; } static int __init do_header(void) { parse_header(collected); - next_header = this_header + N_ALIGN(name_len) + body_len; + next_header = this_header + N_ALIGN(name_len) + X_ALIGN(xattr_len) + + body_len; next_header = (next_header + 3) & ~3; state = do_skip; if (name_len <= 0 || name_len > PATH_MAX) @@ -400,9 +465,17 @@ static int __init do_name(void) } memcpy_optional(name_buf, collected, N_ALIGN(name_len)); state = do_create; + if (xattr_len > 0) + read_into(xattr_buf, X_ALIGN(xattr_len), do_xattrs); return 0; } +static int __init do_xattrs(void) +{ + /* Do nothing for now */ + state = do_create; + return 0; +} static __initdata int wfd; @@ -529,8 +602,9 @@ static char * __init unpack_to_rootfs(char *buf, unsigned long len) header_buf = kmalloc(CPIO_MAX_HEADER_SIZE, GFP_KERNEL); symlink_buf = kmalloc(PATH_MAX + 1, GFP_KERNEL); name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL); + xattr_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!header_buf || !symlink_buf || !name_buf) + if (!header_buf || !symlink_buf || !name_buf || !xattr_buf) panic("can't allocate buffers"); state = do_start; @@ -575,6 +649,7 @@ static char * __init unpack_to_rootfs(char *buf, unsigned long len) len -= my_inptr; } dir_utime(); + kfree(xattr_buf); kfree(name_buf); kfree(symlink_buf); kfree(header_buf); -- 2.10.3.dirty