Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp4754249yba; Mon, 20 May 2019 03:13:59 -0700 (PDT) X-Google-Smtp-Source: APXvYqyz0AFL2bi90NHQZlxxXWBM4B/P/prtwpq6s6ofwqYIL8Ju66pm7Ot2d5D8mDrPSJZgLtez X-Received: by 2002:a63:1f04:: with SMTP id f4mr75082903pgf.423.1558347239382; Mon, 20 May 2019 03:13:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1558347239; cv=none; d=google.com; s=arc-20160816; b=AFju0Ar02CvPX0tiuZYeoQ19AkhyQA74yuVciuAM56Bzh0nr4t3LROuXEU29wdDn82 JHQMXonWAgHXufM03XcUesV9MigIxS4gPfvaqIRMzg95VNqAaUqIQTsvNUHTuT9zl/vE 7TkCYSCRwupglDyxvlJ9yHsLyj/1BmKliVBJ8YlAbOXRKUX8zupcDj6R9G4fnLLCbMrH eoNy/ZQwBCkpoEu8/FS1AaWuKCYEDK7eCzLF5xyX3FoG85FyHESDAa+mxxHcD0XoeVab N0+kpU3BGASc3E40/CkWjAeM53iyrIWj8m1ERxcPZIQhQ2GylJHaptvjijs4T1iCXy8F GlVw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject; bh=uUonoJj+fDRTr0UlqZR/rmtd4kt4/bhAkQsaUYmxfto=; b=jqXB1k3559PEKZYpswdkEEt2X3RsOwnSzinRKQaxTuO5uHkznlNVzkbwOK9OwRhzOy Nig1tKxr48rUkORWKmnnspNZ2qNKnIapxebcsKX1dKq+pqvZNp2aSZVYeYPA9jiXYi/I XGHcJk8fwFth4lmr4R5JAnNMxg6lI2czVzz5BrIVqUl4zVuCDJcas5Z+eLupuc1EtXGw iX3fxAJvQQ2RvqEXlLZpoPSwNJF2I3OYE/IRav4Wkw1lBy2GlLK+/rkREoLZj3NgyQyg t9qbgXFrP2hbq0CAyFZY+SaypDWUpujYvrVp5u73dDLvi8SPzyZj+crOA9KX37jsBCGE pX0w== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r15si17076825pgi.16.2019.05.20.03.13.44; Mon, 20 May 2019 03:13:59 -0700 (PDT) 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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730770AbfETIrb (ORCPT + 99 others); Mon, 20 May 2019 04:47:31 -0400 Received: from lhrrgout.huawei.com ([185.176.76.210]:32955 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727499AbfETIrb (ORCPT ); Mon, 20 May 2019 04:47:31 -0400 Received: from LHREML714-CAH.china.huawei.com (unknown [172.18.7.107]) by Forcepoint Email with ESMTP id 4BE9A91FD6E0516857B2; Mon, 20 May 2019 09:47:29 +0100 (IST) Received: from [10.220.96.108] (10.220.96.108) by smtpsuk.huawei.com (10.201.108.37) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 20 May 2019 09:47:21 +0100 Subject: Re: [PATCH v3 2/2] initramfs: introduce do_readxattrs() To: , CC: , , , , , , , , , , , , , , References: <20190517165519.11507-1-roberto.sassu@huawei.com> <20190517165519.11507-3-roberto.sassu@huawei.com> From: Roberto Sassu Message-ID: <2fbe55dc-2f4a-e476-79d0-06931b4f1dee@huawei.com> Date: Mon, 20 May 2019 10:47:27 +0200 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset="utf-8"; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Originating-IP: [10.220.96.108] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 5/17/2019 10:18 PM, hpa@zytor.com wrote: > On May 17, 2019 9:55:19 AM PDT, Roberto Sassu wrote: >> This patch adds support for an alternative method to add xattrs to >> files in >> the rootfs filesystem. Instead of extracting them directly from the ram >> disk image, they are extracted from a regular file called .xattr-list, >> that >> can be added by any ram disk generator available today. The file format >> is: >> >> \0 >> \0 >> >> .xattr-list can be generated by executing: >> >> $ getfattr --absolute-names -d -h -R -e hex -m - \ >> | xattr.awk -b > ${initdir}/.xattr-list >> >> where the content of the xattr.awk script is: >> >> #! /usr/bin/awk -f >> { >> if (!length($0)) { >> printf("%.10x%s\0", len, file); >> for (x in xattr) { >> printf("%.8x%s\0", xattr_len[x], x); >> for (i = 0; i < length(xattr[x]) / 2; i++) { >> printf("%c", strtonum("0x"substr(xattr[x], i * 2 + 1, 2))); >> } >> } >> i = 0; >> delete xattr; >> delete xattr_len; >> next; >> }; >> if (i == 0) { >> file=$3; >> len=length(file) + 8 + 1; >> } >> if (i > 0) { >> split($0, a, "="); >> xattr[a[1]]=substr(a[2], 3); >> xattr_len[a[1]]=length(a[1]) + 1 + 8 + length(xattr[a[1]]) / 2; >> len+=xattr_len[a[1]]; >> }; >> i++; >> } >> >> Signed-off-by: Roberto Sassu >> --- >> init/initramfs.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 99 insertions(+) >> >> diff --git a/init/initramfs.c b/init/initramfs.c >> index 0c6dd1d5d3f6..6ec018c6279a 100644 >> --- a/init/initramfs.c >> +++ b/init/initramfs.c >> @@ -13,6 +13,8 @@ >> #include >> #include >> >> +#define XATTR_LIST_FILENAME ".xattr-list" >> + >> static ssize_t __init xwrite(int fd, const char *p, size_t count) >> { >> ssize_t out = 0; >> @@ -382,6 +384,97 @@ static int __init __maybe_unused do_setxattrs(char >> *pathname) >> return 0; >> } >> >> +struct path_hdr { >> + char p_size[10]; /* total size including p_size field */ >> + char p_data[]; /* \0 */ >> +}; >> + >> +static int __init do_readxattrs(void) >> +{ >> + struct path_hdr hdr; >> + char *path = NULL; >> + char str[sizeof(hdr.p_size) + 1]; >> + unsigned long file_entry_size; >> + size_t size, path_size, total_size; >> + struct kstat st; >> + struct file *file; >> + loff_t pos; >> + int ret; >> + >> + ret = vfs_lstat(XATTR_LIST_FILENAME, &st); >> + if (ret < 0) >> + return ret; >> + >> + total_size = st.size; >> + >> + file = filp_open(XATTR_LIST_FILENAME, O_RDONLY, 0); >> + if (IS_ERR(file)) >> + return PTR_ERR(file); >> + >> + pos = file->f_pos; >> + >> + while (total_size) { >> + size = kernel_read(file, (char *)&hdr, sizeof(hdr), &pos); >> + if (size != sizeof(hdr)) { >> + ret = -EIO; >> + goto out; >> + } >> + >> + total_size -= size; >> + >> + str[sizeof(hdr.p_size)] = 0; >> + memcpy(str, hdr.p_size, sizeof(hdr.p_size)); >> + ret = kstrtoul(str, 16, &file_entry_size); >> + if (ret < 0) >> + goto out; >> + >> + file_entry_size -= sizeof(sizeof(hdr.p_size)); >> + if (file_entry_size > total_size) { >> + ret = -EINVAL; >> + goto out; >> + } >> + >> + path = vmalloc(file_entry_size); >> + if (!path) { >> + ret = -ENOMEM; >> + goto out; >> + } >> + >> + size = kernel_read(file, path, file_entry_size, &pos); >> + if (size != file_entry_size) { >> + ret = -EIO; >> + goto out_free; >> + } >> + >> + total_size -= size; >> + >> + path_size = strnlen(path, file_entry_size); >> + if (path_size == file_entry_size) { >> + ret = -EINVAL; >> + goto out_free; >> + } >> + >> + xattr_buf = path + path_size + 1; >> + xattr_len = file_entry_size - path_size - 1; >> + >> + ret = do_setxattrs(path); >> + vfree(path); >> + path = NULL; >> + >> + if (ret < 0) >> + break; >> + } >> +out_free: >> + vfree(path); >> +out: >> + fput(file); >> + >> + if (ret < 0) >> + error("Unable to parse xattrs"); >> + >> + return ret; >> +} >> + >> static __initdata int wfd; >> >> static int __init do_name(void) >> @@ -391,6 +484,11 @@ static int __init do_name(void) >> if (strcmp(collected, "TRAILER!!!") == 0) { >> free_hash(); >> return 0; >> + } else if (strcmp(collected, XATTR_LIST_FILENAME) == 0) { >> + struct kstat st; >> + >> + if (!vfs_lstat(collected, &st)) >> + do_readxattrs(); >> } >> clean_path(collected, mode); >> if (S_ISREG(mode)) { >> @@ -562,6 +660,7 @@ static char * __init unpack_to_rootfs(char *buf, >> unsigned long len) >> buf += my_inptr; >> len -= my_inptr; >> } >> + do_readxattrs(); >> dir_utime(); >> kfree(name_buf); >> kfree(symlink_buf); > > Ok... I just realized this does not work for a modular initramfs, composed at load time from multiple files, which is a very real problem. Should be easy enough to deal with: instead of one large file, use one companion file per source file, perhaps something like filename..xattrs (suggesting double dots to make it less likely to conflict with a "real" file.) No leading dot, as it makes it more likely that archivers will sort them before the file proper. Version 1 of the patch set worked exactly in this way. However, Rob pointed out that this would be a problem if file names plus the suffix exceed 255 characters. Roberto -- HUAWEI TECHNOLOGIES Duesseldorf GmbH, HRB 56063 Managing Director: Bo PENG, Jian LI, Yanli SHI