lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20170612201502.GA3272@orkisz>
Date:   Mon, 12 Jun 2017 22:15:02 +0200
From:   Marcin Szewczyk <marcin.szewczyk@...ny.org>
To:     linux-kernel@...r.kernel.org
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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ