From: Jonathan McDowell <noodles@fb.com>
To: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"linux-fsdevel@vger.kernel.org" <linux-fsdevel@vger.kernel.org>,
"linux-integrity@vger.kernel.org"
<linux-integrity@vger.kernel.org>,
"linux-security-module@vger.kernel.org"
<linux-security-module@vger.kernel.org>,
"kexec@lists.infradead.org" <kexec@lists.infradead.org>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>,
Mimi Zohar <zohar@linux.ibm.com>,
Dmitry Kasatkin <dmitry.kasatkin@gmail.com>,
James Morris <jmorris@namei.org>,
"Serge E. Hallyn" <serge@hallyn.com>,
Matthew Garrett <mjg59@srcf.ucam.org>,
Dmitrii Potoskuev <dpotoskuev@fb.com>
Subject: [RFC PATCH 4/7] lib/cpio: Allow use outside of initramfs creation
Date: Fri, 8 Jul 2022 10:12:11 +0000 [thread overview]
Message-ID: <b298adc612237dd67c6dee77e49cbbf3278fd985.1657272362.git.noodles@fb.com> (raw)
In-Reply-To: <cover.1657272362.git.noodles@fb.com>
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 <noodles@fb.com>
---
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 <linux/security.h>
#include <linux/slab.h>
-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);
--
2.36.1
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
next prev parent reply other threads:[~2022-07-08 10:12 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-08 10:10 [RFC PATCH 0/7] ima: Support measurement of kexec initramfs components Jonathan McDowell
2022-07-08 10:11 ` [RFC PATCH 1/7] initramfs: Move cpio handling routines into lib/ Jonathan McDowell
2022-07-08 10:11 ` [RFC PATCH 2/7] lib/cpio: Improve error handling Jonathan McDowell
2022-07-08 10:12 ` [RFC PATCH 3/7] lib/cpio: use non __init filesystem related functions Jonathan McDowell
2022-07-11 8:38 ` [lib/cpio] 0e4846b4e7: Initramfs_unpacking_failed kernel test robot
2022-07-08 10:12 ` Jonathan McDowell [this message]
2022-07-08 10:12 ` [RFC PATCH 5/7] lib/cpio: Add a parse-only option that doesn't extract any files Jonathan McDowell
2022-07-08 10:12 ` [RFC PATCH 6/7] HACK: Allow the use of generic decompress with gzip outside __init Jonathan McDowell
2022-07-08 10:12 ` [RFC PATCH 7/7] ima: Support measurement of kexec initramfs components Jonathan McDowell
2022-07-08 11:49 ` [RFC PATCH 0/7] " Mimi Zohar
2022-07-08 15:34 ` Jonathan McDowell
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=b298adc612237dd67c6dee77e49cbbf3278fd985.1657272362.git.noodles@fb.com \
--to=noodles@fb.com \
--cc=dmitry.kasatkin@gmail.com \
--cc=dpotoskuev@fb.com \
--cc=jmorris@namei.org \
--cc=kexec@lists.infradead.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=mjg59@srcf.ucam.org \
--cc=serge@hallyn.com \
--cc=viro@zeniv.linux.org.uk \
--cc=zohar@linux.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