Skip to content

Commit

Permalink
tiff: Validate palette indices when parsing palette-color images
Browse files Browse the repository at this point in the history
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 <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
  • Loading branch information
jswright authored and gopherbot committed Jun 18, 2024
1 parent 6c5fa46 commit 3bbf4a6
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 2 deletions.
Binary file added testdata/invalid-palette-ref.tiff
Binary file not shown.
12 changes: 10 additions & 2 deletions tiff/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ func (e UnsupportedError) Error() string {
return "tiff: unsupported feature: " + string(e)
}

var errNoPixels = FormatError("not enough pixel data")
var (
errNoPixels = FormatError("not enough pixel data")
errInvalidColorIndex = FormatError("invalid color index")
)

const maxChunkSize = 10 << 20 // 10M

Expand Down Expand Up @@ -337,13 +340,18 @@ func (d *decoder) decode(dst image.Image, xmin, ymin, xmax, ymax int) error {
}
case mPaletted:
img := dst.(*image.Paletted)
pLen := len(d.palette)
for y := ymin; y < rMaxY; y++ {
for x := xmin; x < rMaxX; x++ {
v, ok := d.readBits(d.bpp)
if !ok {
return errNoPixels
}
img.SetColorIndex(x, y, uint8(v))
idx := uint8(v)
if int(idx) >= pLen {
return errInvalidColorIndex
}
img.SetColorIndex(x, y, idx)
}
d.flushBits()
}
Expand Down
10 changes: 10 additions & 0 deletions tiff/reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,16 @@ func TestLargeIFDEntry(t *testing.T) {
}
}

func TestInvalidPaletteRef(t *testing.T) {
contents, err := ioutil.ReadFile(testdataDir + "invalid-palette-ref.tiff")
if err != nil {
t.Fatal(err)
}
if _, err := Decode(bytes.NewReader(contents)); err == nil {
t.Fatal("Decode with invalid palette index: got nil error, want non-nil")
}
}

// benchmarkDecode benchmarks the decoding of an image.
func benchmarkDecode(b *testing.B, filename string) {
b.Helper()
Expand Down

0 comments on commit 3bbf4a6

Please sign in to comment.