• Andrew Morton's avatar
    [PATCH] initramfs uncpio fix · 385b866c
    Andrew Morton authored
    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).
    385b866c
initramfs.c 9.85 KB