2006-03-22 06:12:22

by Michael Neuling

[permalink] [raw]
Subject: [PATCH] initramfs: CPIO unpacking fix


Unlink files, symlinks, FIFOs, devices etc. (except directories) before
writing them when extracting CPIOs. This stops weird behaviour like:
1) writing through symlinks created in earlier CPIOs. eg foo->bar in
the first CPIO. Having foo as a non-link in a subsequent CPIO,
results in bar being written and foo remaining as a symlink.
2) if the first version of file foo is larger than foo in a
subsequent CPIO, we end up with a mix of the two. ie. neither
the first or second version of /foo.
3) special files like devices, fifo etc. can't be overwritten in
subsequent CPIOS.

With this, the kernel will more closely replicate
for i in *.cpio; do cpio --extract --unconditional < $i ; done

This is a change but it's regarded as fixing broken functionality.

Signed-off-by: Michael Neuling <[email protected]>
---
This is a retransmission.

init/initramfs.c | 3 +++
1 files changed, 3 insertions(+)

Index: linux-2.6.15/init/initramfs.c
===================================================================
--- linux-2.6.15.orig/init/initramfs.c
+++ linux-2.6.15/init/initramfs.c
@@ -249,6 +249,7 @@ static int __init do_name(void)
if (dry_run)
return 0;
if (S_ISREG(mode)) {
+ sys_unlink(collected);
if (maybe_link() >= 0) {
wfd = sys_open(collected, O_WRONLY|O_CREAT, mode);
if (wfd >= 0) {
@@ -263,6 +264,7 @@ static int __init do_name(void)
sys_chmod(collected, mode);
} else if (S_ISBLK(mode) || S_ISCHR(mode) ||
S_ISFIFO(mode) || S_ISSOCK(mode)) {
+ sys_unlink(collected);
if (maybe_link() == 0) {
sys_mknod(collected, mode, rdev);
sys_chown(collected, uid, gid);
@@ -291,6 +293,7 @@ static int __init do_copy(void)
static int __init do_symlink(void)
{
collected[N_ALIGN(name_len) + body_len] = '\0';
+ sys_unlink(collected);
sys_symlink(collected + N_ALIGN(name_len), collected);
sys_lchown(collected, uid, gid);
state = SkipIt;



2006-03-22 07:14:09

by Jeff Garzik

[permalink] [raw]
Subject: Re: [PATCH] initramfs: CPIO unpacking fix

Michael Neuling wrote:
> Unlink files, symlinks, FIFOs, devices etc. (except directories) before
> writing them when extracting CPIOs. This stops weird behaviour like:
> 1) writing through symlinks created in earlier CPIOs. eg foo->bar in
> the first CPIO. Having foo as a non-link in a subsequent CPIO,
> results in bar being written and foo remaining as a symlink.
> 2) if the first version of file foo is larger than foo in a
> subsequent CPIO, we end up with a mix of the two. ie. neither
> the first or second version of /foo.
> 3) special files like devices, fifo etc. can't be overwritten in
> subsequent CPIOS.
>
> With this, the kernel will more closely replicate
> for i in *.cpio; do cpio --extract --unconditional < $i ; done
>
> This is a change but it's regarded as fixing broken functionality.
>
> Signed-off-by: Michael Neuling <[email protected]>

For the kernel, I would regard that as needless code... Coding for a
chain of CPIO archives overwriting each other seems like overengineering.

Jeff



2006-03-22 16:05:54

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [klibc] Re: [PATCH] initramfs: CPIO unpacking fix

Jeff Garzik wrote:
>
> For the kernel, I would regard that as needless code... Coding for a
> chain of CPIO archives overwriting each other seems like overengineering.
>

No, it's actually significant. The ability to compose initramfs
contents from multiple sources is one of the major improvements over initrd.

For example, people has asked that kinit should be able to be called
from user-provided (initrd-loaded) initramfs code. The easiest way to
do that is to have the in-kernel module have:

/init -> /kinit
/kinit

... and allow /init to be overwritten.

-hpa

2006-03-22 22:24:13

by Rob Landley

[permalink] [raw]
Subject: Re: [PATCH] initramfs: CPIO unpacking fix

On Wednesday 22 March 2006 2:14 am, Jeff Garzik wrote:
> Michael Neuling wrote:
> > Unlink files, symlinks, FIFOs, devices etc. (except directories) before
> > writing them when extracting CPIOs. This stops weird behaviour like:
> > 1) writing through symlinks created in earlier CPIOs. eg foo->bar in
> > the first CPIO. Having foo as a non-link in a subsequent CPIO,
> > results in bar being written and foo remaining as a symlink.
> > 2) if the first version of file foo is larger than foo in a
> > subsequent CPIO, we end up with a mix of the two. ie. neither
> > the first or second version of /foo.
> > 3) special files like devices, fifo etc. can't be overwritten in
> > subsequent CPIOS.
> >
> > With this, the kernel will more closely replicate
> > for i in *.cpio; do cpio --extract --unconditional < $i ; done
> >
> > This is a change but it's regarded as fixing broken functionality.
> >
> > Signed-off-by: Michael Neuling <[email protected]>
>
> For the kernel, I would regard that as needless code... Coding for a
> chain of CPIO archives overwriting each other seems like overengineering.

There's an obvious use case:

First initramfs.cpio.gz built into the kernel, second initramfs.cpio.gz
supplied as an external file via the initrd mechanism. Both get extracted
into the same rootfs, and I believe external one will overwrite the internal
one if files conflict.

And yes, there are people out there who want to deploy the same binary kernel
image across a product line (or at least put each new one through 3 months of
testing). And others who want to be able to twiddle the rootfs contents
without rebuilding the kernel from source each time. (And of course anybody
who needs to supply binary firmware to a statically linked device driver like
ipw2200 is probably pretty happy about the ability to keep it in a separate
file from the kernel, for license reasons. Or should be, anyway.)

I'm actually fiddling with a script to let people do this for
vmlinux->bzImage. Objcopy with a new init.ramfs section and then go through
the song and dance to make a bzImage. Replacing the initramfs _in_ a
bzimage? Not fun. Turning vmlinux into each of the other binary packaging
types for other platforms? Also not fun. (I don't even have a complete list
of what they all _are_ yet. Working on it...)

> Jeff

Rob
--
Never bet against the cheap plastic solution.

2006-03-22 23:22:41

by Jeff Garzik

[permalink] [raw]
Subject: Re: [PATCH] initramfs: CPIO unpacking fix

Rob Landley wrote:
> First initramfs.cpio.gz built into the kernel, second initramfs.cpio.gz
> supplied as an external file via the initrd mechanism. Both get extracted
> into the same rootfs, and I believe external one will overwrite the internal
> one if files conflict.

Based on this and HPA's response, I definitely stand corrected.

Jeff