From: Roberto Sassu <roberto.sassu@huawei.com>
To: <hpa@zytor.com>, <viro@zeniv.linux.org.uk>
Cc: <linux-security-module@vger.kernel.org>,
<linux-integrity@vger.kernel.org>, <initramfs@vger.kernel.org>,
<linux-api@vger.kernel.org>, <linux-fsdevel@vger.kernel.org>,
<linux-kernel@vger.kernel.org>, <zohar@linux.vnet.ibm.com>,
<silviu.vlasceanu@huawei.com>, <dmitry.kasatkin@huawei.com>,
<takondra@cisco.com>, <kamensky@cisco.com>, <arnd@arndb.de>,
<rob@landley.net>, <james.w.mcmechan@gmail.com>,
<niveditas98@gmail.com>
Subject: Re: [PATCH v3 2/2] initramfs: introduce do_readxattrs()
Date: Mon, 20 May 2019 10:47:27 +0200 [thread overview]
Message-ID: <2fbe55dc-2f4a-e476-79d0-06931b4f1dee@huawei.com> (raw)
In-Reply-To: <CD9A4F89-7CA5-4329-A06A-F8DEB87905A5@zytor.com>
On 5/17/2019 10:18 PM, hpa@zytor.com wrote:
> On May 17, 2019 9:55:19 AM PDT, Roberto Sassu <roberto.sassu@huawei.com> 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:
>>
>> <file #N data len (ASCII, 10 chars)><file #N path>\0
>> <xattr #N data len (ASCII, 8 chars)><xattr #N name>\0<xattr #N value>
>>
>> .xattr-list can be generated by executing:
>>
>> $ getfattr --absolute-names -d -h -R -e hex -m - \
>> <file list> | 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 <roberto.sassu@huawei.com>
>> ---
>> 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 <linux/namei.h>
>> #include <linux/xattr.h>
>>
>> +#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[]; /* <path>\0<xattrs> */
>> +};
>> +
>> +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
next prev parent reply other threads:[~2019-05-20 8:47 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-17 16:55 [PATCH v3 0/2] initramfs: add support for xattrs in the initial ram disk Roberto Sassu
2019-05-17 16:55 ` [PATCH v3 1/2] initramfs: set extended attributes Roberto Sassu
2019-05-17 16:55 ` [PATCH v3 2/2] initramfs: introduce do_readxattrs() Roberto Sassu
2019-05-17 20:18 ` hpa
2019-05-17 21:02 ` Arvind Sankar
2019-05-17 21:10 ` Arvind Sankar
2019-05-20 8:16 ` Roberto Sassu
2019-05-17 21:47 ` H. Peter Anvin
2019-05-17 22:17 ` Arvind Sankar
2019-05-20 9:39 ` Roberto Sassu
2019-05-22 16:17 ` hpa
2019-05-22 17:22 ` Roberto Sassu
2019-05-22 19:26 ` Rob Landley
2019-05-22 20:21 ` Taras Kondratiuk
2019-05-17 21:17 ` Rob Landley
2019-05-17 21:41 ` H. Peter Anvin
2019-05-18 2:16 ` Rob Landley
2019-05-22 16:18 ` hpa
2019-05-20 8:47 ` Roberto Sassu [this message]
2019-05-17 23:09 ` kbuild test robot
2019-05-18 1:02 ` kbuild test robot
2019-05-18 5:49 ` kbuild test robot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2fbe55dc-2f4a-e476-79d0-06931b4f1dee@huawei.com \
--to=roberto.sassu@huawei.com \
--cc=arnd@arndb.de \
--cc=dmitry.kasatkin@huawei.com \
--cc=hpa@zytor.com \
--cc=initramfs@vger.kernel.org \
--cc=james.w.mcmechan@gmail.com \
--cc=kamensky@cisco.com \
--cc=linux-api@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-integrity@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=niveditas98@gmail.com \
--cc=rob@landley.net \
--cc=silviu.vlasceanu@huawei.com \
--cc=takondra@cisco.com \
--cc=viro@zeniv.linux.org.uk \
--cc=zohar@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).