Linux userland API discussions
 help / color / mirror / Atom feed
* [PATCH v5 0/4] initramfs: add support for xattrs in the initial ram disk
@ 2026-10-30 21:09 Danny Hu
  2026-10-30 21:09 ` [PATCH v5 1/4] ima: skip algorithm availability check until initramfs unpacking is finished Danny Hu
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Danny Hu @ 2026-10-30 21:09 UTC (permalink / raw)
  To: Alexander Viro, Christian Brauner
  Cc: Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
	Jan Kara, Victor Kamensky, Taras Kondratiuk, Tianxing Zhang,
	Zheng Zengkai, zhoushuiqing, zhangguangzhi, Danny Hu, Jason Yan,
	silviu.vlasceanu, hpa, arnd, rob, james.w.mcmechan, niveditas98,
	pierre, julien, kbharathi, erosca, alexandr.lobakin, jim_baxter,
	linux-fsdevel, linux-integrity, linux-security-module,
	linux-kbuild, initramfs, linux-api, linux-kernel, bug-cpio

This patch set aims at solving the following use case: appraise files from
the initial ram disk. To do that, IMA checks the signature/hash from the
security.ima xattr. Unfortunately, this use case cannot be implemented
currently, as the CPIO format does not support xattrs.

This proposal consists in including file metadata as additional files named
METADATA!!!, for each file added to the ram disk. The CPIO parser in the
kernel recognizes these special files from the file name, and calls the
appropriate parser to add metadata to the previously extracted file. It has
been proposed to use bit 17:16 of the file mode as a way to recognize files
with metadata, but both the kernel and the cpio tool declare the file mode
as unsigned short.

This v5 revives Roberto Sassu's v4 series posted on May 23, 2019
(https://lkml.org/lkml/2019/5/23/415). The github issue tracking the
revival of this patchset is here
(https://github.com/linux-integrity/linux/issues/11).
This revision incorporates unpublished changes
from other contributors that can be found in
(https://github.com/linux-integrity/linux/tree/initramfs-xattr-v1-devel-v1)
and adapts the implementation to newer kernel interfaces. Compared with
v4, this revision adds an IMA deadlock fix for restoring security.ima
xattrs during initramfs unpacking, switches to a Kconfig choice for
metadata type selection, and updates gen_initramfs.sh to pass source
paths to gen_init_cpio for nonregular entries, allowing their xattrs to be
read from the correct source object that will be included in the archive.
This revision also includes various improvements to error path cleanup,
debug output and tool documentation.

The difference from v2, v3 (https://lkml.org/lkml/2019/5/9/230,
https://lkml.org/lkml/2019/5/17/466) is that file metadata are stored in
separate files instead of a single file. Given that files with metadata
must immediately follow the files metadata will be added to, image
generators have to be modified in this version.

The difference from v1 (https://lkml.org/lkml/2018/11/22/1182) is that
all files have the same name. The file metadata are added to is always the
previous one, and the image generator in user space will make sure that
files are in the correct sequence.

The difference with another proposal
(https://lore.kernel.org/patchwork/cover/888071/) is that xattrs can be
included in an image without changing the image format. Files with metadata
will appear as regular files. It will be task of the parser in the kernel
to process them.

This patch set extends the format of data defined in patch 9/15 of the last
proposal. It adds header version and type, so that new formats can be
defined and arbitrary metadata types can be processed.

The changes introduced by this patch set don't cause any compatibility
issue: kernels without the metadata parser simply extract the special files
and don't process metadata; kernels with the metadata parser don't process
metadata if the special files are not included in the image.

From the kernel space perspective, backporting this functionality to older
kernels should be very easy. It is sufficient to add two calls to the new
function do_process_metadata() in do_copy(), and to check the file name in
do_name(). From the user space perspective, unlike the previous version of
the patch set, it is required to modify the image generators in order to
include metadata as separate files.

Changelog

Changes in v5 relative to v4:
- Rebase onto vfs.all
- Add an IMA fix to avoid a deadlock during initramfs metadata restoration
- Use u32 metadata record lengths and reject records smaller than their
  header
- Improve debug output for binary xattr data
- Cleanup metadata buffers at the end of unpack_to_rootfs() 
- For CONFIG_INITRAMFS_FILE_METADATA, replace the metadata string prompt
  with a none/xattr choice
- Fix resource cleanup and format specifiers in gen_init_cpio
- Update gen_initramfs.sh to pass source paths to gen_init_cpio.c for
  nonregular entries (slink, dir, nod). Modify gen_init_cpio to
  properly collect xattrs from the source object. Without this change,
  xattrs will not get included for slink, dir and nod.
- Add documentation of xattr option in usage() for gen_init_cpio

v3:
- include file metadata as separate files named METADATA!!!
- add the possibility to include in the ram disk arbitrary metadata types

v2:
- replace ksys_lsetxattr() with kern_path() and vfs_setxattr()
  (suggested by Jann Horn)
- replace ksys_open()/ksys_read()/ksys_close() with
  filp_open()/kernel_read()/fput()
  (suggested by Jann Horn)
- use path variable instead of name_buf in do_readxattrs()
- set last byte of str to 0 in do_readxattrs()
- call do_readxattrs() in do_name() before replacing an existing
  .xattr-list
- pass pathname to do_setxattrs()

v1:
- move xattr unmarshaling to CPIO parser

Danny Hu (1):
  ima: skip algorithm availability check until initramfs unpacking is
    finished

Mimi Zohar (1):
  initramfs: add file metadata

Roberto Sassu (2):
  initramfs: read metadata from special file METADATA!!!
  gen_init_cpio: add support for file metadata

 include/linux/initramfs.h             |  19 +++
 init/initramfs.c                      | 140 ++++++++++++++++-
 security/integrity/ima/ima_appraise.c |  25 +++
 usr/Kconfig                           |  19 +++
 usr/Makefile                          |   3 +-
 usr/gen_init_cpio.c                   | 216 ++++++++++++++++++++++----
 usr/gen_initramfs.sh                  |  15 +-
 7 files changed, 401 insertions(+), 36 deletions(-)
 create mode 100644 include/linux/initramfs.h


base-commit: 2c3ba1f1cb416b81d617b92a24a4bcaa48d574e3
-- 
2.51.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v5 1/4] ima: skip algorithm availability check until initramfs unpacking is finished
  2026-10-30 21:09 [PATCH v5 0/4] initramfs: add support for xattrs in the initial ram disk Danny Hu
@ 2026-10-30 21:09 ` Danny Hu
  2026-10-30 21:09 ` [PATCH v5 2/4] initramfs: add file metadata Danny Hu
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Danny Hu @ 2026-10-30 21:09 UTC (permalink / raw)
  To: Alexander Viro, Christian Brauner
  Cc: Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
	Jan Kara, Victor Kamensky, Taras Kondratiuk, Tianxing Zhang,
	Zheng Zengkai, zhoushuiqing, zhangguangzhi, Danny Hu, Jason Yan,
	silviu.vlasceanu, hpa, arnd, rob, james.w.mcmechan, niveditas98,
	pierre, julien, kbharathi, erosca, alexandr.lobakin, jim_baxter,
	linux-fsdevel, linux-integrity, linux-security-module,
	linux-kbuild, initramfs, linux-api, linux-kernel, bug-cpio

With CONFIG_IMA_APPRAISE=y, restoring xattrs during initramfs unpacking
can deadlock the kernel if the xattr being restored is signed with a hash
that the kernel does not already have available. This occurs when the
ima_inode_setxattr() hook calls crypto_has_alg(). crypto_has_alg() may
synchronously request a module leading to a circular dependency where the
userspace helper waits for initramfs unpacking to complete while initramfs
unpacking waits for the userspace helper.

Guard this crypto availability check in validate_hash_algo() until
initramfs unpacking is complete. This prevents the kernel from requesting
a module during unpacking and allows security.ima xattrs to be restored
even if the hash algorithm is unavailable in the running kernel.
Essentially, this flag distinguishes restoration of existing metadata
during initial population from setting/changing an xattr during runtime.

A benefit of this approach is that once unpacking is complete, all
subsequent xattr updates go through the same codepath as before which
preserves the existing behavior during normal userspace operation.

Signed-off-by: Danny Hu <dannyhu@arista.com>
---
 security/integrity/ima/ima_appraise.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 63b0cb957c65..1403f5653973 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -20,6 +20,14 @@
 
 #include "ima.h"
 
+static bool ima_initramfs_populated __ro_after_init =
+	!IS_ENABLED(CONFIG_BLK_DEV_INITRD);
+
+static void ima_notify_initramfs_populated(void)
+{
+	ima_initramfs_populated = true;
+}
+
 #ifdef CONFIG_IMA_APPRAISE_BOOTPARAM
 static char *ima_appraise_cmdline_default __initdata;
 core_param(ima_appraise, ima_appraise_cmdline_default, charp, 0);
@@ -738,6 +746,22 @@ static int validate_hash_algo(struct dentry *dentry,
 		if (likely(xattr_hash_algo == ima_hash_algo))
 			return 0;
 
+		/*
+		 * IMA validates the crypto algorithm whenever the security.ima
+		 * xattr is set. Restoring xattrs during initramfs unpacking
+		 * can call crypto_has_alg() before unpacking has completed.
+		 *
+		 * If the algo is unavailable, crypto_has_alg() may
+		 * synchronously request a module. The userspace helper waits
+		 * for initramfs unpacking to finish and creates a circular
+		 * dependency.
+		 *
+		 * Skip the algorithm availability check until initramfs is
+		 * populated to avoid this deadlock.
+		 */
+		if (!ima_initramfs_populated)
+			return 0;
+
 		/* allow any xattr using an algorithm built in the kernel */
 		if (crypto_has_alg(hash_algo_name[xattr_hash_algo], 0, 0))
 			return 0;
@@ -829,6 +853,7 @@ static struct security_hook_list ima_appraise_hooks[] __ro_after_init = {
 	LSM_HOOK_INIT(inode_set_acl, ima_inode_set_acl),
 	LSM_HOOK_INIT(inode_removexattr, ima_inode_removexattr),
 	LSM_HOOK_INIT(inode_remove_acl, ima_inode_remove_acl),
+	LSM_HOOK_INIT(initramfs_populated, ima_notify_initramfs_populated),
 };
 
 void __init init_ima_appraise_lsm(const struct lsm_id *lsmid)
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v5 2/4] initramfs: add file metadata
  2026-10-30 21:09 [PATCH v5 0/4] initramfs: add support for xattrs in the initial ram disk Danny Hu
  2026-10-30 21:09 ` [PATCH v5 1/4] ima: skip algorithm availability check until initramfs unpacking is finished Danny Hu
@ 2026-10-30 21:09 ` Danny Hu
  2026-10-30 21:09 ` [PATCH v5 3/4] initramfs: read metadata from special file METADATA!!! Danny Hu
  2026-10-30 21:09 ` [PATCH v5 4/4] gen_init_cpio: add support for file metadata Danny Hu
  3 siblings, 0 replies; 5+ messages in thread
From: Danny Hu @ 2026-10-30 21:09 UTC (permalink / raw)
  To: Alexander Viro, Christian Brauner
  Cc: Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
	Jan Kara, Victor Kamensky, Taras Kondratiuk, Tianxing Zhang,
	Zheng Zengkai, zhoushuiqing, zhangguangzhi, Danny Hu, Jason Yan,
	silviu.vlasceanu, hpa, arnd, rob, james.w.mcmechan, niveditas98,
	pierre, julien, kbharathi, erosca, alexandr.lobakin, jim_baxter,
	linux-fsdevel, linux-integrity, linux-security-module,
	linux-kbuild, initramfs, linux-api, linux-kernel, bug-cpio

From: Mimi Zohar <zohar@linux.vnet.ibm.com>

This patch adds metadata to a file from a supplied buffer. The buffer might
contains multiple metadata records. The format of each record is:

<metadata len (ASCII, 8 chars)><version><type><metadata>

For now, only the TYPE_XATTR metadata type is supported. The specific
format of this metadata type is:

<xattr #N name>\0<xattr #N value>

[kamensky: fixed restoring of xattrs for symbolic links by using
           sys_lsetxattr() instead of sys_setxattr()]

[sassu: removed state management, kept only do_setxattrs(), added support
        for generic file metadata, replaced sys_lsetxattr() with
        vfs_setxattr(), added check for entry_size, added check for
        hdr->c_size, replaced strlen() with strnlen(); moved do_setxattrs()
        before do_name()]

[zhangguangzhi: fix checkpatch warning EMBEDDED_FILENAME in
                include/linux/initramfs.h]

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Signed-off-by: Victor Kamensky <kamensky@cisco.com>
Signed-off-by: Taras Kondratiuk <takondra@cisco.com>
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Signed-off-by: Tianxing Zhang <zhangtianxing3@huawei.com>
Reviewed-by: Jason Yan <yanaijie@huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
Signed-off-by: zhoushuiqing <zhoushuiqing2@huawei.com>
Signed-off-by: zhangguangzhi <zhangguangzhi3@huawei.com>
Signed-off-by: Danny Hu <dannyhu@arista.com>
---
Changes in v5:
 - For debug print in do_setxattrs(), use print_hex_dump_debug() rather
   than printing the xattr value as a string
 - Use u32 metadata record lengths and reject records smaller than their
   header

 include/linux/initramfs.h | 19 +++++++++
 init/initramfs.c          | 89 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 107 insertions(+), 1 deletion(-)
 create mode 100644 include/linux/initramfs.h

diff --git a/include/linux/initramfs.h b/include/linux/initramfs.h
new file mode 100644
index 000000000000..9b3839dc88a1
--- /dev/null
+++ b/include/linux/initramfs.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Include file for file metadata in the initial ram disk.
+ */
+#ifndef _LINUX_INITRAMFS_H
+#define _LINUX_INITRAMFS_H
+
+#define METADATA_FILENAME "METADATA!!!"
+
+enum metadata_types { TYPE_NONE, TYPE_XATTR, TYPE__LAST };
+
+struct metadata_hdr {
+	char c_size[8];     /* total size including c_size field */
+	char c_version;     /* header version */
+	char c_type;        /* metadata type */
+	char c_metadata[];  /* metadata */
+} __packed;
+
+#endif /*LINUX_INITRAMFS_H*/
diff --git a/init/initramfs.c b/init/initramfs.c
index ebddde9c8f0d..36254dba7822 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -10,6 +10,7 @@
 #include <linux/hex.h>
 #include <linux/init.h>
 #include <linux/init_syscalls.h>
+#include <linux/initramfs.h>
 #include <linux/kstrtox.h>
 #include <linux/memblock.h>
 #include <linux/mm.h>
@@ -22,6 +23,7 @@
 #include <linux/types.h>
 #include <linux/umh.h>
 #include <linux/utime.h>
+#include <linux/xattr.h>
 
 #include <asm/byteorder.h>
 
@@ -189,7 +191,7 @@ static __initdata time64_t mtime;
 
 static __initdata unsigned long ino, major, minor, nlink;
 static __initdata umode_t mode;
-static __initdata unsigned long body_len, name_len;
+static __initdata unsigned long body_len, name_len, metadata_len;
 static __initdata uid_t uid;
 static __initdata gid_t gid;
 static __initdata unsigned rdev;
@@ -264,6 +266,7 @@ static void __init read_into(char *buf, unsigned size, enum state next)
 }
 
 static __initdata char *header_buf, *symlink_buf, *name_buf;
+static __initdata char *metadata_buf;
 
 static int __init do_start(void)
 {
@@ -365,6 +368,90 @@ static int __init maybe_link(void)
 	return 0;
 }
 
+static int __init do_setxattrs(char *pathname, char *buf, size_t size)
+{
+	struct path path;
+	char *xattr_name, *xattr_value;
+	uint32_t xattr_name_size, xattr_value_size;
+	int ret;
+
+	xattr_name = buf;
+	xattr_name_size = strnlen(xattr_name, size);
+	if (xattr_name_size == size) {
+		error("malformed xattrs");
+		return -EINVAL;
+	}
+
+	xattr_value = xattr_name + xattr_name_size + 1;
+	xattr_value_size = buf + size - xattr_value;
+
+	ret = kern_path(pathname, 0, &path);
+	if (!ret) {
+		ret = vfs_setxattr(&nop_mnt_idmap, path.dentry, xattr_name, xattr_value,
+				   xattr_value_size, 0);
+
+		path_put(&path);
+	}
+
+	pr_debug("%s: %s size: %u (ret: %d)\n", pathname, xattr_name,
+		 xattr_value_size, ret);
+	print_hex_dump_debug("xattr value: ", DUMP_PREFIX_OFFSET,
+			     16, 1, xattr_value, xattr_value_size, false);
+
+	return ret;
+}
+
+static int __init __maybe_unused do_parse_metadata(char *pathname)
+{
+	char *buf = metadata_buf;
+	char *bufend = metadata_buf + metadata_len;
+	struct metadata_hdr *hdr;
+	char str[sizeof(hdr->c_size) + 1];
+	uint32_t entry_size;
+
+	if (!metadata_len)
+		return 0;
+
+	str[sizeof(hdr->c_size)] = 0;
+
+	while (buf < bufend) {
+		int ret;
+
+		if (buf + sizeof(*hdr) > bufend) {
+			error("malformed metadata");
+			break;
+		}
+
+		hdr = (struct metadata_hdr *)buf;
+		if (hdr->c_version != 1) {
+			pr_debug("Unsupported header version\n");
+			break;
+		}
+
+		memcpy(str, hdr->c_size, sizeof(hdr->c_size));
+		ret = kstrtou32(str, 16, &entry_size);
+		if (ret || buf + entry_size > bufend ||
+		    entry_size < sizeof(*hdr)) {
+			error("malformed xattrs");
+			break;
+		}
+
+		switch (hdr->c_type) {
+		case TYPE_XATTR:
+			do_setxattrs(pathname, buf + sizeof(*hdr),
+				     entry_size - sizeof(*hdr));
+			break;
+		default:
+			pr_debug("Unsupported metadata type\n");
+			break;
+		}
+
+		buf += entry_size;
+	}
+
+	return 0;
+}
+
 static __initdata struct file *wfile;
 static __initdata loff_t wfile_pos;
 
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v5 3/4] initramfs: read metadata from special file METADATA!!!
  2026-10-30 21:09 [PATCH v5 0/4] initramfs: add support for xattrs in the initial ram disk Danny Hu
  2026-10-30 21:09 ` [PATCH v5 1/4] ima: skip algorithm availability check until initramfs unpacking is finished Danny Hu
  2026-10-30 21:09 ` [PATCH v5 2/4] initramfs: add file metadata Danny Hu
@ 2026-10-30 21:09 ` Danny Hu
  2026-10-30 21:09 ` [PATCH v5 4/4] gen_init_cpio: add support for file metadata Danny Hu
  3 siblings, 0 replies; 5+ messages in thread
From: Danny Hu @ 2026-10-30 21:09 UTC (permalink / raw)
  To: Alexander Viro, Christian Brauner
  Cc: Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
	Jan Kara, Victor Kamensky, Taras Kondratiuk, Tianxing Zhang,
	Zheng Zengkai, zhoushuiqing, zhangguangzhi, Danny Hu, Jason Yan,
	silviu.vlasceanu, hpa, arnd, rob, james.w.mcmechan, niveditas98,
	pierre, julien, kbharathi, erosca, alexandr.lobakin, jim_baxter,
	linux-fsdevel, linux-integrity, linux-security-module,
	linux-kbuild, initramfs, linux-api, linux-kernel, bug-cpio

From: Roberto Sassu <roberto.sassu@huawei.com>

Instead of changing the CPIO format, metadata are parsed from regular files
with special name 'METADATA!!!'. This file immediately follows the file
metadata are added to.

This patch checks if the file being extracted has the special name and, if
yes, creates a buffer with the content of that file and calls
do_parse_metadata() to parse metadata from the buffer.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Reported-by: kbuild test robot <lkp@intel.com>
Signed-off-by: Tianxing Zhang <zhangtianxing3@huawei.com>
Reviewed-by: Jason Yan <yanaijie@huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
Signed-off-by: zhoushuiqing <zhoushuiqing2@huawei.com>
Signed-off-by: zhangguangzhi <zhangguangzhi3@huawei.com>
Signed-off-by: Danny Hu <dannyhu@arista.com>
---
v5 changes:
 - clean up metadata buffer when returning from unpack_to_rootfs()

 init/initramfs.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 51 insertions(+), 2 deletions(-)

diff --git a/init/initramfs.c b/init/initramfs.c
index 36254dba7822..a1744cc9523c 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -265,8 +265,8 @@ static void __init read_into(char *buf, unsigned size, enum state next)
 	}
 }
 
-static __initdata char *header_buf, *symlink_buf, *name_buf;
-static __initdata char *metadata_buf;
+static __initdata char *header_buf, *symlink_buf, *name_buf, *previous_name_buf;
+static __initdata char *metadata_buf, *metadata_buf_ptr;
 
 static int __init do_start(void)
 {
@@ -454,6 +454,7 @@ static int __init __maybe_unused do_parse_metadata(char *pathname)
 
 static __initdata struct file *wfile;
 static __initdata loff_t wfile_pos;
+static __initdata int metadata;
 
 static int __init do_name(void)
 {
@@ -471,6 +472,10 @@ static int __init do_name(void)
 	if (strcmp(collected, "TRAILER!!!") == 0) {
 		free_hash();
 		return 0;
+	} else if (strcmp(collected, METADATA_FILENAME) == 0) {
+		metadata = 1;
+	} else {
+		memcpy(previous_name_buf, collected, strlen(collected) + 1);
 	}
 	clean_path(collected, mode);
 	if (S_ISREG(mode)) {
@@ -508,11 +513,47 @@ static int __init do_name(void)
 	return 0;
 }
 
+static int __init do_process_metadata(char *buf, int len, bool last)
+{
+	int ret = 0;
+
+	if (!metadata_buf) {
+		metadata_buf_ptr = metadata_buf = kmalloc(body_len, GFP_KERNEL);
+		if (!metadata_buf_ptr) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		metadata_len = body_len;
+	}
+
+	if (metadata_buf_ptr + len > metadata_buf + metadata_len) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	memcpy(metadata_buf_ptr, buf, len);
+	metadata_buf_ptr += len;
+
+	if (last)
+		do_parse_metadata(previous_name_buf);
+out:
+	if (ret < 0 || last) {
+		kfree(metadata_buf);
+		metadata_buf = NULL;
+		metadata = 0;
+	}
+
+	return ret;
+}
+
 static int __init do_copy(void)
 {
 	if (byte_count >= body_len) {
 		if (xwrite(wfile, victim, body_len, &wfile_pos) != body_len)
 			error("write error");
+		if (metadata)
+			do_process_metadata(victim, body_len, true);
 
 		do_utime_path(&wfile->f_path, mtime);
 		fput(wfile);
@@ -524,6 +565,8 @@ static int __init do_copy(void)
 	} else {
 		if (xwrite(wfile, victim, byte_count, &wfile_pos) != byte_count)
 			error("write error");
+		if (metadata)
+			do_process_metadata(victim, byte_count, false);
 		body_len -= byte_count;
 		eat(byte_count);
 		return 1;
@@ -539,6 +582,7 @@ static int __init do_symlink(void)
 		return 1;
 	}
 	collected[N_ALIGN(name_len) + body_len] = '\0';
+	memcpy(previous_name_buf, collected, strlen(collected) + 1);
 	clean_path(collected, 0);
 	init_symlink(collected + N_ALIGN(name_len), collected);
 	init_chown(collected, uid, gid, AT_SYMLINK_NOFOLLOW);
@@ -614,6 +658,7 @@ char * __init unpack_to_rootfs(char *buf, unsigned long len)
 		char header[CPIO_HDRLEN];
 		char symlink[PATH_MAX + N_ALIGN(PATH_MAX) + 1];
 		char name[N_ALIGN(PATH_MAX)];
+		char prev_name[PATH_MAX + N_ALIGN(PATH_MAX) + 1];
 	} *bufs = kmalloc_obj(*bufs);
 
 	if (!bufs)
@@ -622,6 +667,7 @@ char * __init unpack_to_rootfs(char *buf, unsigned long len)
 	header_buf = bufs->header;
 	symlink_buf = bufs->symlink;
 	name_buf = bufs->name;
+	previous_name_buf = bufs->prev_name;
 
 	state = Start;
 	this_header = 0;
@@ -664,6 +710,9 @@ char * __init unpack_to_rootfs(char *buf, unsigned long len)
 	dir_utime();
 	/* free any hardlink state collected without optional TRAILER!!! */
 	free_hash();
+	kfree(metadata_buf);
+	metadata_buf = NULL;
+	metadata = 0;
 	kfree(bufs);
 	return message;
 }
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v5 4/4] gen_init_cpio: add support for file metadata
  2026-10-30 21:09 [PATCH v5 0/4] initramfs: add support for xattrs in the initial ram disk Danny Hu
                   ` (2 preceding siblings ...)
  2026-10-30 21:09 ` [PATCH v5 3/4] initramfs: read metadata from special file METADATA!!! Danny Hu
@ 2026-10-30 21:09 ` Danny Hu
  3 siblings, 0 replies; 5+ messages in thread
From: Danny Hu @ 2026-10-30 21:09 UTC (permalink / raw)
  To: Alexander Viro, Christian Brauner
  Cc: Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
	Jan Kara, Victor Kamensky, Taras Kondratiuk, Tianxing Zhang,
	Zheng Zengkai, zhoushuiqing, zhangguangzhi, Danny Hu, Jason Yan,
	silviu.vlasceanu, hpa, arnd, rob, james.w.mcmechan, niveditas98,
	pierre, julien, kbharathi, erosca, alexandr.lobakin, jim_baxter,
	linux-fsdevel, linux-integrity, linux-security-module,
	linux-kbuild, initramfs, linux-api, linux-kernel, bug-cpio

From: Roberto Sassu <roberto.sassu@huawei.com>

This patch adds support for file metadata (only TYPE_XATTR metadata type).
gen_init_cpio has been modified to read xattrs from files that will be
added to the image and to include file metadata as separate files with the
special name 'METADATA!!!'.

This behavior can be selected by setting the desired file metadata type as
value for CONFIG_INITRAMFS_FILE_METADATA.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Signed-off-by: Tianxing Zhang <zhangtianxing3@huawei.com>
Reviewed-by: Jason Yan <yanaijie@huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
Signed-off-by: zhoushuiqing <zhoushuiqing2@huawei.com>
Signed-off-by: zhangguangzhi <zhangguangzhi3@huawei.com>
Signed-off-by: Danny Hu <dannyhu@arista.com>
---
Changes in v5:
 - context adapt usr/Makefile, usr/gen_initramfs.sh (zhangguangzhi)
 - del duplicate code in usr/Makefile (zhangguangzhi)
 - fix checkpatch warning STATIC_CONST_CHAR_ARRAY in usr/gen_init_cpio.c:38
   (zhangguangzhi)
 - make CONFIG_INITRAMFS_FILE_METADATA a choice rather than having to
   specify it manually
 - document -e option and supported values in gen_init_cpio usage()
 - Update gen_initramfs.sh to pass source paths to gen_init_cpio.c for
   nonregular entries (slink, dir, nod). Modify gen_init_cpio to
   properly collect xattrs from the source object. Without this change,
   xattrs will not get included for slink, dir and nod.
 - xattr collection now uses llistxattr() and lgetxattr() so symlink
   xattrs come from the link itself rather than the target.
 - use the size_t hexadecimal format specifier in write_xattrs()
 - initialize xattr_value as NULL to prevent free of uninitialized ptr
 - free xattr_list after checking whether xattr iteration completed
 - clean up temporary metadata file before gen_init_cpio exits

 usr/Kconfig          |  19 ++++
 usr/Makefile         |   3 +-
 usr/gen_init_cpio.c  | 216 +++++++++++++++++++++++++++++++++++++------
 usr/gen_initramfs.sh |  15 ++-
 4 files changed, 219 insertions(+), 34 deletions(-)

diff --git a/usr/Kconfig b/usr/Kconfig
index 9279a2893ab0..135a9248bba2 100644
--- a/usr/Kconfig
+++ b/usr/Kconfig
@@ -227,3 +227,22 @@ config INITRAMFS_COMPRESSION_NONE
 	  filesystem image will be present in memory simultaneously
 
 endchoice
+
+choice
+	prompt "File metadata type"
+	default INITRAMFS_FILE_METADATA_NONE
+	help
+	  Specify the metadata types to be included in the image.
+
+	  If you are not sure, leave unchanged.
+
+	config INITRAMFS_FILE_METADATA_NONE
+		bool "no xattrs (default)"
+	config INITRAMFS_FILE_METADATA_XATTR
+		bool "xattr"
+endchoice
+
+config INITRAMFS_FILE_METADATA
+	string
+	default "" if INITRAMFS_FILE_METADATA_NONE
+	default "xattr" if INITRAMFS_FILE_METADATA_XATTR
diff --git a/usr/Makefile b/usr/Makefile
index e8f42478a0b7..dc4a1f4b3da2 100644
--- a/usr/Makefile
+++ b/usr/Makefile
@@ -65,7 +65,8 @@ quiet_cmd_initfs = GEN     $@
 	$(addprefix -u , $(CONFIG_INITRAMFS_ROOT_UID)) \
 	$(addprefix -g , $(CONFIG_INITRAMFS_ROOT_GID)) \
 	$(if $(KBUILD_BUILD_TIMESTAMP), -d "$(KBUILD_BUILD_TIMESTAMP)") \
-	$(ramfs-input)
+	$(if $(filter-out "",$(CONFIG_INITRAMFS_FILE_METADATA)), \
+	  -e $(CONFIG_INITRAMFS_FILE_METADATA)) $(ramfs-input)
 
 # We rebuild initramfs_data.cpio if:
 # 1) Any included file is newer than initramfs_data.cpio
diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c
index b7296edc6626..f07be54c9219 100644
--- a/usr/gen_init_cpio.c
+++ b/usr/gen_init_cpio.c
@@ -6,6 +6,7 @@
 #include <stdbool.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/xattr.h>
 #include <string.h>
 #include <unistd.h>
 #include <time.h>
@@ -13,6 +14,7 @@
 #include <errno.h>
 #include <ctype.h>
 #include <limits.h>
+#include "../include/linux/initramfs.h"
 
 /*
  * Original work by Jeff Garzik
@@ -37,12 +39,126 @@ static bool do_file_mtime;
 static bool do_csum = false;
 static int outfd = STDOUT_FILENO;
 static unsigned int dalign;
+static char metadata_path[] = "/tmp/cpio-metadata-XXXXXX";
+static int metadata_fd = -1;
 
 struct file_handler {
 	const char *type;
 	int (*handler)(const char *line);
 };
 
+static enum metadata_types parse_metadata_type(char *arg)
+{
+	static char *metadata_type_str[TYPE__LAST] = {
+		[TYPE_NONE] = "none",
+		[TYPE_XATTR] = "xattr",
+	};
+	int i;
+
+	for (i = 0; i < TYPE__LAST; i++)
+		if (!strcmp(metadata_type_str[i], arg))
+			return i;
+
+	return TYPE_NONE;
+}
+
+static int cpio_mkfile(const char *name, const char *location,
+		       unsigned int mode, uid_t uid, gid_t gid,
+		       unsigned int nlinks);
+
+static char *cpio_replace_env(char *new_location);
+
+static int write_xattrs(const char *path)
+{
+	struct metadata_hdr hdr = { .c_version = 1, .c_type = TYPE_XATTR };
+	char str[sizeof(hdr.c_size) + 1];
+	char *xattr_list, *list_ptr;
+	char *xattr_value = NULL;
+	ssize_t list_len, name_len, value_len, len;
+	int ret = -EINVAL;
+
+	if (metadata_fd < 0)
+		return 0;
+
+	if (path == metadata_path)
+		return 0;
+
+	list_len = llistxattr(path, NULL, 0);
+	if (list_len <= 0)
+		return 0;
+
+	list_ptr = xattr_list = malloc(list_len);
+	if (!list_ptr) {
+		fprintf(stderr, "out of memory\n");
+		return ret;
+	}
+
+	len = llistxattr(path, xattr_list, list_len);
+	if (len != list_len)
+		goto out;
+
+	if (ftruncate(metadata_fd, 0))
+		goto out;
+
+	lseek(metadata_fd, 0, SEEK_SET);
+
+	while (list_ptr < xattr_list + list_len) {
+		name_len = strlen(list_ptr);
+
+		value_len = lgetxattr(path, list_ptr, NULL, 0);
+		if (value_len < 0) {
+			fprintf(stderr, "cannot get xattrs\n");
+			break;
+		}
+
+		if (value_len) {
+			xattr_value = malloc(value_len);
+			if (!xattr_value) {
+				fprintf(stderr, "out of memory\n");
+				break;
+			}
+		} else {
+			xattr_value = NULL;
+		}
+
+		len = lgetxattr(path, list_ptr, xattr_value, value_len);
+		if (len != value_len)
+			break;
+
+		snprintf(str, sizeof(str), "%.8zx",
+			 sizeof(hdr) + name_len + 1 + value_len);
+
+		memcpy(hdr.c_size, str, sizeof(hdr.c_size));
+
+		if (write(metadata_fd, &hdr, sizeof(hdr)) != sizeof(hdr))
+			break;
+
+		if (write(metadata_fd, list_ptr, name_len + 1) != name_len + 1)
+			break;
+
+		if (write(metadata_fd, xattr_value, value_len) != value_len)
+			break;
+
+		if (fsync(metadata_fd))
+			break;
+
+		list_ptr += name_len + 1;
+		free(xattr_value);
+		xattr_value = NULL;
+	}
+
+	free(xattr_value);
+out:
+	if (list_ptr != xattr_list + list_len) {
+		free(xattr_list);
+		return ret;
+	}
+
+	free(xattr_list);
+
+	return cpio_mkfile(METADATA_FILENAME, metadata_path, S_IFREG, 0, 0, 1);
+}
+
 static int push_buf(const char *name, size_t name_len)
 {
 	ssize_t len;
@@ -119,7 +235,8 @@ static int cpio_trailer(void)
 }
 
 static int cpio_mkslink(const char *name, const char *target,
-			 unsigned int mode, uid_t uid, gid_t gid)
+			const char *location, unsigned int mode,
+			uid_t uid, gid_t gid)
 {
 	int len;
 	unsigned int namesize, targetsize = strlen(target) + 1;
@@ -150,7 +267,8 @@ static int cpio_mkslink(const char *name, const char *target,
 	    push_buf(name, namesize) < 0 ||
 	    push_pad(padlen(offset, 4)) < 0 ||
 	    push_buf(target, targetsize) < 0 ||
-	    push_pad(padlen(offset, 4)) < 0)
+	    push_pad(padlen(offset, 4)) < 0 ||
+	    write_xattrs(location) < 0)
 		return -1;
 
 	return 0;
@@ -161,22 +279,29 @@ static int cpio_mkslink_line(const char *line)
 {
 	char name[PATH_MAX + 1];
 	char target[PATH_MAX + 1];
+	char location[PATH_MAX + 1];
 	unsigned int mode;
 	int uid;
 	int gid;
+	int nfields;
 	int rc = -1;
 
-	if (5 != sscanf(line, "%" str(PATH_MAX) "s %" str(PATH_MAX) "s %o %d %d", name, target, &mode, &uid, &gid)) {
-		fprintf(stderr, "Unrecognized dir format '%s'", line);
+	nfields = sscanf(line, "%" str(PATH_MAX) "s %" str(PATH_MAX)
+			 "s %o %d %d %" str(PATH_MAX) "s",
+			 name, target, &mode, &uid, &gid, location);
+	if (nfields < 5) {
+		fprintf(stderr, "Unrecognized slink format '%s'", line);
 		goto fail;
 	}
-	rc = cpio_mkslink(name, target, mode, uid, gid);
+	rc = cpio_mkslink(name, target,
+			  nfields == 6 ? cpio_replace_env(location) : NULL,
+			  mode, uid, gid);
  fail:
 	return rc;
 }
 
-static int cpio_mkgeneric(const char *name, unsigned int mode,
-		       uid_t uid, gid_t gid)
+static int cpio_mkgeneric(const char *name, const char *location,
+			  unsigned int mode, uid_t uid, gid_t gid)
 {
 	int len;
 	unsigned int namesize;
@@ -204,7 +329,8 @@ static int cpio_mkgeneric(const char *name, unsigned int mode,
 	offset += len;
 
 	if (len != CPIO_HDR_LEN ||
-	    push_rest(name, namesize) < 0)
+	    push_rest(name, namesize) < 0 ||
+	    write_xattrs(location) < 0)
 		return -1;
 
 	return 0;
@@ -239,18 +365,24 @@ static const struct generic_type generic_type_table[] = {
 static int cpio_mkgeneric_line(const char *line, enum generic_types gt)
 {
 	char name[PATH_MAX + 1];
+	char location[PATH_MAX + 1];
 	unsigned int mode;
 	int uid;
 	int gid;
+	int nfields;
 	int rc = -1;
 
-	if (4 != sscanf(line, "%" str(PATH_MAX) "s %o %d %d", name, &mode, &uid, &gid)) {
+	nfields = sscanf(line, "%" str(PATH_MAX) "s %o %d %d %"
+			 str(PATH_MAX) "s", name, &mode, &uid, &gid, location);
+	if (nfields < 4) {
 		fprintf(stderr, "Unrecognized %s format '%s'",
-			line, generic_type_table[gt].type);
+			generic_type_table[gt].type, line);
 		goto fail;
 	}
 	mode |= generic_type_table[gt].mode;
-	rc = cpio_mkgeneric(name, mode, uid, gid);
+	rc = cpio_mkgeneric(name,
+			   nfields == 5 ? cpio_replace_env(location) : NULL,
+			   mode, uid, gid);
  fail:
 	return rc;
 }
@@ -270,9 +402,9 @@ static int cpio_mksock_line(const char *line)
 	return cpio_mkgeneric_line(line, GT_SOCK);
 }
 
-static int cpio_mknod(const char *name, unsigned int mode,
-		       uid_t uid, gid_t gid, char dev_type,
-		       unsigned int maj, unsigned int min)
+static int cpio_mknod(const char *name, const char *location,
+		      unsigned int mode, uid_t uid, gid_t gid, char dev_type,
+		      unsigned int maj, unsigned int min)
 {
 	int len;
 	unsigned int namesize;
@@ -305,7 +437,8 @@ static int cpio_mknod(const char *name, unsigned int mode,
 	offset += len;
 
 	if (len != CPIO_HDR_LEN ||
-	    push_rest(name, namesize) < 0)
+	    push_rest(name, namesize) < 0 ||
+	    write_xattrs(location) < 0)
 		return -1;
 
 	return 0;
@@ -314,20 +447,26 @@ static int cpio_mknod(const char *name, unsigned int mode,
 static int cpio_mknod_line(const char *line)
 {
 	char name[PATH_MAX + 1];
+	char location[PATH_MAX + 1];
 	unsigned int mode;
 	int uid;
 	int gid;
 	char dev_type;
 	unsigned int maj;
 	unsigned int min;
+	int nfields;
 	int rc = -1;
 
-	if (7 != sscanf(line, "%" str(PATH_MAX) "s %o %d %d %c %u %u",
-			 name, &mode, &uid, &gid, &dev_type, &maj, &min)) {
+	nfields = sscanf(line, "%" str(PATH_MAX) "s %o %d %d %c %u %u %"
+			 str(PATH_MAX) "s", name, &mode, &uid, &gid, &dev_type,
+			 &maj, &min, location);
+	if (nfields < 7) {
 		fprintf(stderr, "Unrecognized nod format '%s'", line);
 		goto fail;
 	}
-	rc = cpio_mknod(name, mode, uid, gid, dev_type, maj, min);
+	rc = cpio_mknod(name,
+			nfields == 8 ? cpio_replace_env(location) : NULL,
+			mode, uid, gid, dev_type, maj, min);
  fail:
 	return rc;
 }
@@ -490,7 +629,7 @@ static int cpio_mkfile(const char *name, const char *location,
 		name += namesize;
 	}
 	ino++;
-	rc = 0;
+	rc = write_xattrs(location);
 
 error:
 	if (file >= 0)
@@ -570,22 +709,24 @@ static int cpio_mkfile_line(const char *line)
 static void usage(const char *prog)
 {
 	fprintf(stderr, "Usage:\n"
-		"\t%s [-t <timestamp>] [-c] [-o <output_file>] [-a <data_align>] <cpio_list>\n"
+		"\t%s [-t <timestamp>] [-c] [-o <output_file>] [-a <data_align>] [-e <type>] <cpio_list>\n"
 		"\n"
 		"<cpio_list> is a file containing newline separated entries that\n"
 		"describe the files to be included in the initramfs archive:\n"
 		"\n"
 		"# a comment\n"
 		"file <name> <location> <mode> <uid> <gid> [<hard links>]\n"
-		"dir <name> <mode> <uid> <gid>\n"
-		"nod <name> <mode> <uid> <gid> <dev_type> <maj> <min>\n"
-		"slink <name> <target> <mode> <uid> <gid>\n"
-		"pipe <name> <mode> <uid> <gid>\n"
-		"sock <name> <mode> <uid> <gid>\n"
+		"dir <name> <mode> <uid> <gid> [<location>]\n"
+		"nod <name> <mode> <uid> <gid> <dev_type> <maj> <min> [<location>]\n"
+		"slink <name> <target> <mode> <uid> <gid> [<location>]\n"
+		"pipe <name> <mode> <uid> <gid> [<location>]\n"
+		"sock <name> <mode> <uid> <gid> [<location>]\n"
 		"\n"
 		"<name>       name of the file/dir/nod/etc in the archive\n"
 		"<location>   location of the file in the current filesystem\n"
 		"             expands shell variables quoted with ${}\n"
+		"             optional for nonregular entries; used to read xattrs\n"
+		"             with -e xattr. If omitted, no xattrs are included.\n"
 		"<target>     link target\n"
 		"<mode>       mode/permissions of the file\n"
 		"<uid>        user id (0=root)\n"
@@ -611,7 +752,8 @@ static void usage(const char *prog)
 		"<output_file>: write cpio to this file instead of stdout\n"
 		"<data_align>: attempt to align file data by zero-padding the\n"
 		"filename field up to data_align. Must be a multiple of 4.\n"
-		"Alignment is best-effort; PATH_MAX limits filename padding.\n",
+		"Alignment is best-effort; PATH_MAX limits filename padding.\n"
+		"<type>: include file metadata: none (default) or xattr.\n",
 		prog);
 }
 
@@ -640,7 +782,7 @@ static const struct file_handler file_handler_table[] = {
 	}
 };
 
-#define LINE_SIZE (2 * PATH_MAX + 50)
+#define LINE_SIZE (3 * PATH_MAX + 50)
 
 int main (int argc, char *argv[])
 {
@@ -650,10 +792,11 @@ int main (int argc, char *argv[])
 	int ec = 0;
 	int line_nr = 0;
 	const char *filename;
+	enum metadata_types metadata_type = TYPE_NONE;
 
 	default_mtime = time(NULL);
 	while (1) {
-		int opt = getopt(argc, argv, "t:cho:a:");
+		int opt = getopt(argc, argv, "t:e:cho:a:");
 		char *invalid;
 
 		if (opt == -1)
@@ -669,6 +812,9 @@ int main (int argc, char *argv[])
 			}
 			do_file_mtime = true;
 			break;
+		case 'e':
+			metadata_type = parse_metadata_type(optarg);
+			break;
 		case 'c':
 			do_csum = true;
 			break;
@@ -721,6 +867,13 @@ int main (int argc, char *argv[])
 		usage(argv[0]);
 		exit(1);
 	}
+	if (metadata_type != TYPE_NONE) {
+		metadata_fd = mkstemp(metadata_path);
+		if (metadata_fd < 0) {
+			fprintf(stderr, "cannot create temporary file\n");
+			exit(1);
+		}
+	}
 
 	while (fgets(line, LINE_SIZE, cpio_list)) {
 		int type_idx;
@@ -777,5 +930,12 @@ int main (int argc, char *argv[])
 	if (ec == 0)
 		ec = cpio_trailer();
 
+	if (metadata_type != TYPE_NONE) {
+		close(metadata_fd);
+		if (unlink(metadata_path))
+			fprintf(stderr,
+				"warning: cannot remove temporary file %s: %s\n",
+				metadata_path, strerror(errno));
+	}
 	exit(ec);
 }
diff --git a/usr/gen_initramfs.sh b/usr/gen_initramfs.sh
index 7eba2fddf0ef..fea88d761d62 100755
--- a/usr/gen_initramfs.sh
+++ b/usr/gen_initramfs.sh
@@ -14,7 +14,7 @@ set -e
 usage() {
 cat << EOF
 Usage:
-$0 [-o <file>] [-l <dep_list>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} ...
+$0 [-o <file>] [-l <dep_list>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} [-e <type>]...
 	-o <file>      Create initramfs file named <file> by using gen_init_cpio
 	-l <dep_list>  Create dependency list named <dep_list>
 	-u <uid>       User ID to map to user ID 0 (root).
@@ -27,6 +27,7 @@ $0 [-o <file>] [-l <dep_list>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} ...
 	<cpio_source>  File list or directory for cpio archive.
 		       If <cpio_source> is a .cpio file it will be used
 		       as direct input to initramfs.
+	-e <type>      File metadata type to include in the cpio archive.
 
 All options except -o and -l may be repeated and are interpreted
 sequentially and immediately.  -u and -g states are preserved across
@@ -113,14 +114,14 @@ parse() {
 
 			[ -b "${location}" ] && dev="b" || dev="c"
 
-			str="${ftype} ${name} ${str} ${dev} ${maj} ${min}"
+			str="${ftype} ${name} ${str} ${dev} ${maj} ${min} ${location}"
 			;;
 		"slink")
 			local target=`readlink "${location}"`
-			str="${ftype} ${name} ${target} ${str}"
+			str="${ftype} ${name} ${target} ${str} ${location}"
 			;;
 		*)
-			str="${ftype} ${name} ${str}"
+			str="${ftype} ${name} ${str} ${location}"
 			;;
 	esac
 
@@ -228,6 +229,10 @@ while [ $# -gt 0 ]; do
 			fi
 			shift
 			;;
+		"-e")   # file metadata type
+			metadata_arg="-e $1"
+			shift
+			;;
 		"-h")
 			usage
 			exit 0
@@ -247,4 +252,4 @@ done
 
 # If output_file is set we will generate cpio archive
 # we are careful to delete tmp files
-usr/gen_init_cpio $output $timestamp $cpio_list
+usr/gen_init_cpio $output $metadata_arg $timestamp $cpio_list
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-10-30 21:10 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-30 21:09 [PATCH v5 0/4] initramfs: add support for xattrs in the initial ram disk Danny Hu
2026-10-30 21:09 ` [PATCH v5 1/4] ima: skip algorithm availability check until initramfs unpacking is finished Danny Hu
2026-10-30 21:09 ` [PATCH v5 2/4] initramfs: add file metadata Danny Hu
2026-10-30 21:09 ` [PATCH v5 3/4] initramfs: read metadata from special file METADATA!!! Danny Hu
2026-10-30 21:09 ` [PATCH v5 4/4] gen_init_cpio: add support for file metadata Danny Hu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox