]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
initramfs_test: add fill_cpio() inject_ox parameter
authorDavid Disseldorp <ddiss@suse.de>
Tue, 31 Mar 2026 06:57:31 +0000 (17:57 +1100)
committerChristian Brauner <brauner@kernel.org>
Thu, 21 May 2026 07:32:46 +0000 (09:32 +0200)
fill_cpio() uses sprintf() to write out the in-memory cpio archive from
an array of struct initramfs_test_cpio. This change allows callers to
modify the cpio sprintf() format string so that future tests can
intentionally corrupt the header with "0x" and "0X" prefixed fields.

Signed-off-by: David Disseldorp <ddiss@suse.de>
Link: https://patch.msgid.link/20260331070519.5974-2-ddiss@suse.de
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
init/initramfs_test.c

index 2ce38d9a8fd0faa0ffcf509cb2038bd6db8c9a96..6fe1c44a74a586d1822efc85a71ecbf2e2c428cc 100644 (file)
@@ -27,7 +27,18 @@ struct initramfs_test_cpio {
        char *data;
 };
 
-static size_t fill_cpio(struct initramfs_test_cpio *cs, size_t csz, char *out)
+/* regular newc header format */
+#define CPIO_HDR_FMT "%s%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%s"
+/*
+ * Bogus newc header with "0x" prefixes on the uid, gid, and namesize values.
+ * parse_header()/simple_str[n]toul() accept this, contrary to the initramfs
+ * specification.
+ */
+#define CPIO_HDR_OX_INJECT \
+       "%s%08x%08x0x%06x0X%06x%08x%08x%08x%08x%08x%08x%08x0x%06x%08x%s"
+
+static size_t fill_cpio(struct initramfs_test_cpio *cs, size_t csz,
+                       bool inject_ox, char *out)
 {
        int i;
        size_t off = 0;
@@ -38,9 +49,8 @@ static size_t fill_cpio(struct initramfs_test_cpio *cs, size_t csz, char *out)
                size_t thislen;
 
                /* +1 to account for nulterm */
-               thislen = sprintf(pos, "%s"
-                       "%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x"
-                       "%s",
+               thislen = sprintf(pos,
+                       inject_ox ? CPIO_HDR_OX_INJECT : CPIO_HDR_FMT,
                        c->magic, c->ino, c->mode, c->uid, c->gid, c->nlink,
                        c->mtime, c->filesize, c->devmajor, c->devminor,
                        c->rdevmajor, c->rdevminor, c->namesize, c->csum,
@@ -102,7 +112,7 @@ static void __init initramfs_test_extract(struct kunit *test)
        /* +3 to cater for any 4-byte end-alignment */
        cpio_srcbuf = kzalloc(ARRAY_SIZE(c) * (CPIO_HDRLEN + PATH_MAX + 3),
                              GFP_KERNEL);
-       len = fill_cpio(c, ARRAY_SIZE(c), cpio_srcbuf);
+       len = fill_cpio(c, ARRAY_SIZE(c), false, cpio_srcbuf);
 
        ktime_get_real_ts64(&ts_before);
        err = unpack_to_rootfs(cpio_srcbuf, len);
@@ -177,7 +187,7 @@ static void __init initramfs_test_fname_overrun(struct kunit *test)
        /* limit overrun to avoid crashes / filp_open() ENAMETOOLONG */
        cpio_srcbuf[CPIO_HDRLEN + strlen(c[0].fname) + 20] = '\0';
 
-       len = fill_cpio(c, ARRAY_SIZE(c), cpio_srcbuf);
+       len = fill_cpio(c, ARRAY_SIZE(c), false, cpio_srcbuf);
        /* overwrite trailing fname terminator and padding */
        suffix_off = len - 1;
        while (cpio_srcbuf[suffix_off] == '\0') {
@@ -219,7 +229,7 @@ static void __init initramfs_test_data(struct kunit *test)
        cpio_srcbuf = kmalloc(CPIO_HDRLEN + c[0].namesize + c[0].filesize + 6,
                              GFP_KERNEL);
 
-       len = fill_cpio(c, ARRAY_SIZE(c), cpio_srcbuf);
+       len = fill_cpio(c, ARRAY_SIZE(c), false, cpio_srcbuf);
 
        err = unpack_to_rootfs(cpio_srcbuf, len);
        KUNIT_EXPECT_NULL(test, err);
@@ -274,7 +284,7 @@ static void __init initramfs_test_csum(struct kunit *test)
 
        cpio_srcbuf = kmalloc(8192, GFP_KERNEL);
 
-       len = fill_cpio(c, ARRAY_SIZE(c), cpio_srcbuf);
+       len = fill_cpio(c, ARRAY_SIZE(c), false, cpio_srcbuf);
 
        err = unpack_to_rootfs(cpio_srcbuf, len);
        KUNIT_EXPECT_NULL(test, err);
@@ -284,7 +294,7 @@ static void __init initramfs_test_csum(struct kunit *test)
 
        /* mess up the csum and confirm that unpack fails */
        c[0].csum--;
-       len = fill_cpio(c, ARRAY_SIZE(c), cpio_srcbuf);
+       len = fill_cpio(c, ARRAY_SIZE(c), false, cpio_srcbuf);
 
        err = unpack_to_rootfs(cpio_srcbuf, len);
        KUNIT_EXPECT_NOT_NULL(test, err);
@@ -330,7 +340,7 @@ static void __init initramfs_test_hardlink(struct kunit *test)
 
        cpio_srcbuf = kmalloc(8192, GFP_KERNEL);
 
-       len = fill_cpio(c, ARRAY_SIZE(c), cpio_srcbuf);
+       len = fill_cpio(c, ARRAY_SIZE(c), false, cpio_srcbuf);
 
        err = unpack_to_rootfs(cpio_srcbuf, len);
        KUNIT_EXPECT_NULL(test, err);
@@ -371,7 +381,7 @@ static void __init initramfs_test_many(struct kunit *test)
                };
 
                c.namesize = 1 + sprintf(thispath, "initramfs_test_many-%d", i);
-               p += fill_cpio(&c, 1, p);
+               p += fill_cpio(&c, 1, false, p);
        }
 
        len = p - cpio_srcbuf;
@@ -425,7 +435,7 @@ static void __init initramfs_test_fname_pad(struct kunit *test)
        } };
 
        memcpy(tbufs->padded_fname, "padded_fname", sizeof("padded_fname"));
-       len = fill_cpio(c, ARRAY_SIZE(c), tbufs->cpio_srcbuf);
+       len = fill_cpio(c, ARRAY_SIZE(c), false, tbufs->cpio_srcbuf);
 
        err = unpack_to_rootfs(tbufs->cpio_srcbuf, len);
        KUNIT_EXPECT_NULL(test, err);
@@ -481,7 +491,7 @@ static void __init initramfs_test_fname_path_max(struct kunit *test)
        memcpy(tbufs->fname_oversize, "fname_oversize",
               sizeof("fname_oversize") - 1);
        memcpy(tbufs->fname_ok, "fname_ok", sizeof("fname_ok") - 1);
-       len = fill_cpio(c, ARRAY_SIZE(c), tbufs->cpio_src);
+       len = fill_cpio(c, ARRAY_SIZE(c), false, tbufs->cpio_src);
 
        /* unpack skips over fname_oversize instead of returning an error */
        err = unpack_to_rootfs(tbufs->cpio_src, len);