public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* An inconsistent behaviour if using built-in initramfs and damaged external one
@ 2017-06-12 20:15 Marcin Szewczyk
  2017-06-13  0:06 ` Henrique de Moraes Holschuh
  0 siblings, 1 reply; 3+ messages in thread
From: Marcin Szewczyk @ 2017-06-12 20:15 UTC (permalink / raw)
  To: linux-kernel

Hi,

during my experiments with initramfs I have noticed there is something 
that looks like a bug in the 9-year old code[1] of the clean_rootfs() 
function in init/initramfs.c. An inconsistent behaviour appears when 
I have both the built-in initramfs and the one in the external file but 
the latter is somehow damaged (e.g. wrong padding).

I wanted to leverage the functionality described in the ramfs 
documentation[2]: "It can also be used to supplement the kernel's 
built-in initramfs image. The files in the external archive will 
overwrite any conflicting files in the built-in initramfs archive."

Clearly there is an intention in the code to do cleanup and return to 
the built-in initramfs if the external initramfs was only partially 
unpacked:

#v+
    char *err = unpack_to_rootfs(__initramfs_start, __initramfs_size);
    if (err)
        panic(err);    /* Failed to decompress INTERNAL initramfs */
    if (initrd_start) {
#ifdef CONFIG_BLK_DEV_RAM
        int fd;
        printk(KERN_INFO "Trying to unpack rootfs image as initramfs...\n");
        err = unpack_to_rootfs((char *)initrd_start,
            initrd_end - initrd_start);
        if (!err) {
            free_initrd();
            goto done;
        } else {
            clean_rootfs();
            unpack_to_rootfs(__initramfs_start, __initramfs_size);
        }
        printk(KERN_INFO "rootfs image is not initramfs (%s)"
                "; looks like an initrd\n", err);
#v-

But inside the clean_rootfs() function non-empty directories are not 
going to be removed:
#v+
    ret = sys_newlstat(dirp->d_name, &st);
    WARN_ON_ONCE(ret);
    if (!ret) {
        if (S_ISDIR(st.st_mode))
            sys_rmdir(dirp->d_name);
        else
            sys_unlink(dirp->d_name);
    }
    num -= dirp->d_reclen;
#v-
Call to sys_rmdir() is assumed to be always successful.

I am aware that this is not a serious bug (if a bug at all) but I would 
like this note to last in the mailing list archive because debugging it 
took me some time and possibly some could stumble upon it as well.

Because I missed the "rootfs image is not initramfs […] looks like an
initrd" message in the dmesg at first I thought that files are not
overwritten with their external versions at all. I wondered how it was
possible to have the following effects:

- if no /etc/shadow in the built-in image, /etc/shadow in the external 
  though damaged image → password from the *external* image works,

- if /etc/shadow in the built-in image, /etc/shadow in the external 
  though damaged image → password from the *built-in* image works,

- files in / from the external though damaged initramfs disappear, but 
  files in /etc survive.



[1]: https://github.com/torvalds/linux/commit/df52092f3c97788592ef72501a43fb7ac6a3cfe0
[2]: https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt

-- 
Marcin Szewczyk
http://wodny.org

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

end of thread, other threads:[~2017-06-13  0:24 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-06-12 20:15 An inconsistent behaviour if using built-in initramfs and damaged external one Marcin Szewczyk
2017-06-13  0:06 ` Henrique de Moraes Holschuh
2017-06-13  0:24   ` Henrique de Moraes Holschuh

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