1
0
Fork 1
mirror of https://github.com/vbatts/tar-split.git synced 2025-06-26 12:18:28 +00:00

archive/tar: fix the archive/tar.Writer CVE

The remainder of:
0bf7ee9

Reference from https://github.com/vbatts/tar-split/issues/76#issuecomment-2618694926

Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
This commit is contained in:
Vincent Batts 2025-01-30 17:46:54 -05:00
parent b8ca13f886
commit 0a078f222d
Signed by: vbatts
GPG key ID: E30EFAA812C6E5ED
4 changed files with 40 additions and 1 deletions

View file

@ -6,6 +6,7 @@ package tar
import (
"bytes"
"compress/bzip2"
"crypto/md5"
"errors"
"fmt"
@ -243,6 +244,9 @@ func TestReader(t *testing.T) {
}, {
file: "testdata/pax-bad-hdr-file.tar",
err: ErrHeader,
}, {
file: "testdata/pax-bad-hdr-large.tar.bz2",
err: ErrFieldTooLong,
}, {
file: "testdata/pax-bad-mtime-file.tar",
err: ErrHeader,
@ -625,9 +629,14 @@ func TestReader(t *testing.T) {
}
defer f.Close()
var fr io.Reader = f
if strings.HasSuffix(v.file, ".bz2") {
fr = bzip2.NewReader(fr)
}
// Capture all headers and checksums.
var (
tr = NewReader(f)
tr = NewReader(fr)
hdrs []*Header
chksums []string
rdbuf = make([]byte, 8)

Binary file not shown.

View file

@ -199,6 +199,9 @@ func (tw *Writer) writePAXHeader(hdr *Header, paxHdrs map[string]string) error {
flag = TypeXHeader
}
data := buf.String()
if len(data) > maxSpecialFileSize {
return ErrFieldTooLong
}
if err := tw.writeRawFile(name, data, flag, FormatPAX); err != nil || isGlobal {
return err // Global headers return here
}

View file

@ -1006,6 +1006,33 @@ func TestIssue12594(t *testing.T) {
}
}
func TestWriteLongHeader(t *testing.T) {
for _, test := range []struct {
name string
h *Header
}{{
name: "name too long",
h: &Header{Name: strings.Repeat("a", maxSpecialFileSize)},
}, {
name: "linkname too long",
h: &Header{Linkname: strings.Repeat("a", maxSpecialFileSize)},
}, {
name: "uname too long",
h: &Header{Uname: strings.Repeat("a", maxSpecialFileSize)},
}, {
name: "gname too long",
h: &Header{Gname: strings.Repeat("a", maxSpecialFileSize)},
}, {
name: "PAX header too long",
h: &Header{PAXRecords: map[string]string{"GOLANG.x": strings.Repeat("a", maxSpecialFileSize)}},
}} {
w := NewWriter(io.Discard)
if err := w.WriteHeader(test.h); err != ErrFieldTooLong {
t.Errorf("%v: w.WriteHeader() = %v, want ErrFieldTooLong", test.name, err)
}
}
}
// testNonEmptyWriter wraps an io.Writer and ensures that
// Write is never called with an empty buffer.
type testNonEmptyWriter struct{ io.Writer }