golang/go

archive/tar: slice bounds out of range

dvyukov opened this issue · 6 comments

The following program crashes with a panic:

package main

import (
    "archive/tar"
    "bytes"
    "io"
    "io/ioutil"
)

func main() {
    data := []byte("\x13\x0300\x13\x03-821950296t\x13\x13\x83" +
        "s|\x83s\x1300qw\xe1f\xbb\x03000\x00\x00\x00\x10" +
        "011\x13s\xf410100t\x13\x13\x83s|\x83ss" +
        "\x000\x13s|\x83ss\xf4xS\x13s\xf410100t" +
        "\x13\x13\x83s|\x83ss\xf40\x13s|\x83ss\xf4qS0" +
        "\xd4t0\x1300q0\xf40\x00\x00\x00\x1001\x80\x00\x100" +
        "11\x13s\xf4101\xf40t\x1300q\xd4\xe1f\xbb\x03" +
        "\x00\x00\x00\xff\x80\x80\x80\x00\x80\x00\x00\x00\x00\x00\x9b\x921\x13\xff\xff" +
        "\xff\x80100txS00t0\x1300qw010" +
        "100t\x13\x13\x83s|\x83ss\xf4xS00t0\x13" +
        "00qw\xe1f\xbb\x03000\x00\x00\x00\x10011\x13s" +
        "\xf410100t\x13\x13\x83s|\x83ss\xf40\x13s|" +
        "\x83ss\xf4xS\x13s\xf410100t\x13\x13\x83s|" +
        "\x83ss00\x13s|\x83ss0xS00t0\x130" +
        "0q00\x00\x80\x00\x00\x1001s\xf410100t\x13" +
        "\x00\x00\x00 \xe1f\xbb\x0304\x00\x00\x00\x10011\x13\xff\xff" +
        "\xff\x80100txS00t0\x1300qw\xe1f\xbb" +
        "\x03000\x00\x00\x00\x10011\x13s\x83ss\xf4xS\x13" +
        "s\xf410100t\x13\x13\x83s|\x83ss\xf4311" +
        "033624846128380s|\x83ss" +
        "\xf4xS00t0\x1300q000\x00\x00\x00\x1001" +
        "\x00\x00\x10011\x13s\xf410100t\x1300q\xd4" +
        "\xe1f\xbb\x0304\x00\x00\x00\x10\x83s|\x83ss\xf40\x13s" +
        "|\x83ss\xf4xS00t0\x1300q000\x00\x00" +
        "\x00\x1001\x00\x00\x10011\x13s\xf410100t\x13" +
        "00x0\xe1f\xbb\x03\x00\x00\x100")
    t := tar.NewReader(bytes.NewReader(data))
    for {
        _, err := t.Next()
        if err != nil {
            return
        }
        io.Copy(ioutil.Discard, t)
    }
}
panic: runtime error: slice bounds out of range

goroutine 1 [running]:
archive/tar.(*regFileReader).Read(0xc20800e420, 0xc208074000, 0x2000, 0x2000, 0x0, 0x0, 0x0)
    src/archive/tar/reader.go:748 +0x170
archive/tar.(*Reader).Read(0xc208070000, 0xc208074000, 0x2000, 0x2000, 0x4feab0, 0x0, 0x0)
    src/archive/tar/reader.go:735 +0x9d
io/ioutil.devNull.ReadFrom(0x0, 0x7feaee410268, 0xc208070000, 0x0, 0x0, 0x0)
    src/io/ioutil/ioutil.go:151 +0xa1
io/ioutil.(*devNull).ReadFrom(0xc20800a4a0, 0x7feaee410268, 0xc208070000, 0xc208041e40, 0x0, 0x0)
    <autogenerated>:9 +0xb4
io.copyBuffer(0x7feaee4101c0, 0xc20800a4a0, 0x7feaee410268, 0xc208070000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    src/io/io.go:375 +0x183
io.Copy(0x7feaee4101c0, 0xc20800a4a0, 0x7feaee410268, 0xc208070000, 0x200, 0x0, 0x0)
    src/io/io.go:351 +0x6b
main.main()
    tar.go:43 +0x1df

on commit 8017ace

Neat bug, but I don't have time to pick it up.

It's also probably been there forever, so I don't think it's critical for go1.5.

heartbleed was also there forever

If you can make a case that this is a security hole (beyond just a DoS vector) then we can reprioritise.

DoS can also be an issue. Note that you can use this bug to (1) cause a panic, (2) cause swapping and affect the whole machine or (3) terminate the program instantly with a fatal error at your discretion.

I don't have anything more serious. This does not mean that a bad guy does not have the other part of the puzzle and he just waits for a way to force a server to panic (panic/defer/recover mechanism did have a bunch of bugs that compromise memory safety).

CL https://golang.org/cl/10402 mentions this issue.