Skip to content

archive/tar: reader returns bogus headers #12436

Closed
@dvyukov

Description

@dvyukov

The following program crashes:

package main

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

func main() {
    t := tar.NewReader(bytes.NewReader([]byte(data)))
    var headers []*tar.Header
    for {
        hdr, err := t.Next()
        if err == io.EOF {
            break
        }
        if err != nil {
            return
        }
        hdr1 := *hdr // make a copy to be safe
        headers = append(headers, &hdr1)
    }
    buf := new(bytes.Buffer)
    w := tar.NewWriter(buf)
    for _, hdr := range headers {
        err := w.WriteHeader(hdr)
        if err != nil {
            panic(err)
        }
    }
}

var data =  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" +
    "\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x0000000000\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t" +
    "\xbf\x97\xd4\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
panic: archive/tar: header field too long

The problem is that reader produces the following header:

tar.Header{Name:"", Mode:9151314442816847872, Uid:0, Gid:0, Size:0, ModTime:time.Time{sec:62135596800, nsec:0, loc:(*time.Location)(0x5d6f40)}, Typeflag:0x0, Linkname:"", Uname:"", Gname:"", Devmajor:0, Devminor:0, AccessTime:time.Time{sec:0, nsec:0, loc:(*time.Location)(nil)}, ChangeTime:time.Time{sec:0, nsec:0, loc:(*time.Location)(nil)}, Xattrs:map[string]string(nil)}

Mode is bogus. Then, cString tries to serialize that mode in octal format into 8-byte buffer. It does not fit.
I've inserted panic when this error is generated, and there is output:

b="\x00\x00\x00\x00\x00\x00\x00\x00"
s="774000000000000000000"
panic: archive/tar: header field too long

goroutine 1 [running]:
archive/tar.(*Writer).cString(0xc820090480, 0xc820090517, 0x8, 0x19c, 0xc8200ae0e0, 0x15, 0x505f00, 0x0, 0x0, 0x0)
    src/archive/tar/writer.go:83 +0x333
archive/tar.(*Writer).octal(0xc820090480, 0xc820090517, 0x8, 0x19c, 0x7f00000000000000)
    src/archive/tar/writer.go:102 +0xea
archive/tar.(*Writer).writeHeader(0xc820090480, 0xc8200b8f70, 0x517701, 0x0, 0x0)
    src/archive/tar/writer.go:193 +0x651
archive/tar.(*Writer).WriteHeader(0xc820090480, 0xc8200b8f70, 0x0, 0x0)
    src/archive/tar/writer.go:142 +0x3c
main.main()
    /tmp/tar.go:26 +0x336
exit status 2

go version devel +9c514e1 Tue Sep 1 04:00:12 2015 +0000 linux/amd64

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions