From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752636AbdFLVEB (ORCPT ); Mon, 12 Jun 2017 17:04:01 -0400 Received: from smtp2.n26.netmark.pl ([94.124.9.106]:41350 "EHLO n26.netmark.pl" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752076AbdFLVEA (ORCPT ); Mon, 12 Jun 2017 17:04:00 -0400 X-Greylist: delayed 2926 seconds by postgrey-1.27 at vger.kernel.org; Mon, 12 Jun 2017 17:03:59 EDT Date: Mon, 12 Jun 2017 22:15:02 +0200 From: Marcin Szewczyk To: linux-kernel@vger.kernel.org Subject: An inconsistent behaviour if using built-in initramfs and damaged external one Message-ID: <20170612201502.GA3272@orkisz> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit User-Agent: Mutt/1.5.23 (2014-03-12) X-OutGoing-Spam-Status: No, score=-2.9 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - n26.netmark.pl X-AntiAbuse: Original Domain - vger.kernel.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - wodny.org X-Get-Message-Sender-Via: n26.netmark.pl: authenticated_id: wodny/from_h X-Authenticated-Sender: n26.netmark.pl: marcin.szewczyk@wodny.org Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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