Skip to content

Commit 3bbf4a6

Browse files
jswrightgopherbot
authored andcommitted
tiff: Validate palette indices when parsing palette-color images
The existing implementation will succeed to parse a corrupt or malicious image with color indices out of range of the actual palette, which will eventually result in a panic when the consumer tries to read the color at any corrupted pixel. This issue was originally discovered and filed against a downstream library: disintegration/imaging#165. This is also referenced in https://osv.dev/vulnerability/GHSA-q7pp-wcgr-pffx. Fixes golang/go#67624 Change-Id: I7d7577adb7d549ecfcd59e84e04a92d198d94c18 Reviewed-on: https://go-review.googlesource.com/c/image/+/588115 Auto-Submit: Damien Neil <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Damien Neil <[email protected]>
1 parent 6c5fa46 commit 3bbf4a6

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

testdata/invalid-palette-ref.tiff

9.44 KB
Binary file not shown.

tiff/reader.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ func (e UnsupportedError) Error() string {
3636
return "tiff: unsupported feature: " + string(e)
3737
}
3838

39-
var errNoPixels = FormatError("not enough pixel data")
39+
var (
40+
errNoPixels = FormatError("not enough pixel data")
41+
errInvalidColorIndex = FormatError("invalid color index")
42+
)
4043

4144
const maxChunkSize = 10 << 20 // 10M
4245

@@ -337,13 +340,18 @@ func (d *decoder) decode(dst image.Image, xmin, ymin, xmax, ymax int) error {
337340
}
338341
case mPaletted:
339342
img := dst.(*image.Paletted)
343+
pLen := len(d.palette)
340344
for y := ymin; y < rMaxY; y++ {
341345
for x := xmin; x < rMaxX; x++ {
342346
v, ok := d.readBits(d.bpp)
343347
if !ok {
344348
return errNoPixels
345349
}
346-
img.SetColorIndex(x, y, uint8(v))
350+
idx := uint8(v)
351+
if int(idx) >= pLen {
352+
return errInvalidColorIndex
353+
}
354+
img.SetColorIndex(x, y, idx)
347355
}
348356
d.flushBits()
349357
}

tiff/reader_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,16 @@ func TestLargeIFDEntry(t *testing.T) {
414414
}
415415
}
416416

417+
func TestInvalidPaletteRef(t *testing.T) {
418+
contents, err := ioutil.ReadFile(testdataDir + "invalid-palette-ref.tiff")
419+
if err != nil {
420+
t.Fatal(err)
421+
}
422+
if _, err := Decode(bytes.NewReader(contents)); err == nil {
423+
t.Fatal("Decode with invalid palette index: got nil error, want non-nil")
424+
}
425+
}
426+
417427
// benchmarkDecode benchmarks the decoding of an image.
418428
func benchmarkDecode(b *testing.B, filename string) {
419429
b.Helper()

0 commit comments

Comments
 (0)