Commit 385b866c authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] initramfs uncpio fix

From: <viro@parcelfarce.linux.theplanet.co.uk>

init/initramfs.c::do_skip() has an off-by-one that leads to unpacking
failures for some gzipped cpio images.  We have

static int __init do_skip(void)
{
        if (this_header + count <= next_header) {
                eat(count);
                return 1;
        } else {
                eat(next_header - this_header);
                state = next_state;
                return 0;
        }
}

and that <= should actually be <.  It almost never matters, since if we hit
the boundary case (header ending exactly on the gunzip window end) the
current variant will simply end up doing extra call of do_skip() when we
get to the next window and that will finish the work (assign state).  The
only exception is when we hit that in the last window.  That is, if there's
nothing after the final header (trailer).  Then we miss the final state
transition (Skip -> Reset) and get "junk in archive" panic.  Normally
cpio(1) pads the image to multiple of 512, so we actually have a bunch of
zeroes after the trailer.  And that almost always saves our butts - trailer
is followed by zeroes, so we get to Reset state just fine.

So we never see that on small in-kernel image (it's less than 512 bytes, so
it gets a lot of padding) and we almost never see that on external ones
(1:127 odds of hitting the bug).
parent 70c6e41e
......@@ -207,7 +207,7 @@ static int __init do_header(void)
static int __init do_skip(void)
{
if (this_header + count <= next_header) {
if (this_header + count < next_header) {
eat(count);
return 1;
} else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment