Messages in this thread | | | Date | Mon, 12 Jun 2017 22:15:02 +0200 | From | Marcin Szewczyk <> | Subject | An inconsistent behaviour if using built-in initramfs and damaged external one |
| |
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
| |