Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

image/png: panic in Decode #19553

Closed
fishy opened this issue Mar 15, 2017 · 19 comments
Closed

image/png: panic in Decode #19553

fishy opened this issue Mar 15, 2017 · 19 comments

Comments

@fishy
Copy link

fishy commented Mar 15, 2017

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

1.8

What operating system and processor architecture are you using (go env)?

linux/amd64

What did you do?

Calling png.Decode panicked at image/png.(*decoder).readImagePass, here's the call stack:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x97f9c8]

goroutine 52345 [running]:
image/png.(*decoder).readImagePass(0xc423806400, 0x7f91a3f47ac8, 0xc42130b6d0, 0x0, 0xc42130b600, 0x0, 0x0, 0xc422d84000, 0xc423806478)
        /usr/local/go/src/image/png/reader.go:615 +0x1028
image/png.(*decoder).decode(0xc423806400, 0x0, 0x0, 0x0, 0x0)
        /usr/local/go/src/image/png/reader.go:365 +0x621
image/png.(*decoder).parseIDAT(0xc423806400, 0x4f, 0xfdb929, 0x4)
        /usr/local/go/src/image/png/reader.go:827 +0x36
image/png.(*decoder).parseChunk(0xc423806400, 0x0, 0x0)
        /usr/local/go/src/image/png/reader.go:887 +0x45a
image/png.Decode(0x1783fe0, 0xc42675ef30, 0xfdad15, 0x1, 0xc42316f740, 0x2)
        /usr/local/go/src/image/png/reader.go:946 +0x161
(caller deducted)

Looking at image/png/reader.go:615, I think it might be because of gray was nil. gray was only initialized before on line 438, in the case of !d.useTransparent, so when d.useTransparent == true and it's the cbG8 case, it might panic. (I'm no PNG expert so I'm not sure whether that's a case that's not supposed to happen)

What did you expect to see?

What did you see instead?

@bradfitz
Copy link
Contributor

Can you share the source file?

@bradfitz bradfitz changed the title panic in png.Decode image/png: panic in Decode Mar 15, 2017
@bradfitz bradfitz added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. labels Mar 15, 2017
@bradfitz bradfitz added this to the Go1.9Maybe milestone Mar 15, 2017
@fishy
Copy link
Author

fishy commented Mar 15, 2017

This is the hex values of the []byte (with bytes.NewReader, of course) I passed to png.Decode:

89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 00 0f 00 00 00 0b 08 00 00 00 00 85 2c 88 80 00 00 00 02 74 52 4e 53 00 ff 5b 91 22 b5 00 00 00 02 62 4b 47 44 00 ff 87 8f cc bf 00 00 00 09 70 48 59 73 00 00 0a f0 00 00 0a f0 01 42 ac 34 98 00 00 00 07 74 49 4d 45 07 d5 04 02 12 11 11 f7 65 3d 8b 00 00 00 4f 49 44 41 54 08 d7 63 f8 ff ff ff b9 bd 70 f0 8c 01 c8 af 6e 99 02 05 d9 7b c1 fc 6b ff a1 a0 87 30 ff d9 de bd d5 4b f7 ee fd 0e e3 ef cd 06 19 14 f5 1e ce ef 01 31 92 d7 82 41 31 9c 3f 07 02 ee a1 aa ff ff 9f e1 d9 56 30 f8 0e e5 03 00 a9 42 84 3d df 8f a6 8f 00 00 00 00 49 45 4e 44 ae 42 60 82

@fishy
Copy link
Author

fishy commented Mar 15, 2017

foo

This is the original file.

@ghost
Copy link

ghost commented Mar 15, 2017

Just started fuzzing image/png, and it took about an hour to get the very same crasher.

@dgryski
Copy link
Contributor

dgryski commented Mar 16, 2017

Seems like the last time png was fuzzed was ~2 years ago: https://github.com/dvyukov/go-fuzz/tree/master/examples/png ?

@gopherbot
Copy link

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

@hyhlinux
Copy link

hi @gopherbot , i get the sam err.
the pic url:https://github.com/hyhlinux/docker/blob/master/bug/pngBug.png

@bradfitz
Copy link
Contributor

@hyhlinux, if you still get an error, please file a new (and complete) bug report, including details of which version of Go you're using.

This issue is closed and replies are not necessarily tracked.

@nigeltao
Copy link
Contributor

@hyhlinux, FWIW, the PNG image that you attached decodes fine on tip (which will become Go 1.9). Still, as @bradfitz said, "if you still get an error, please file a new (and complete) bug report, including details of which version of Go you're using."

@nigeltao nigeltao modified the milestones: Go1.8.1, Go1.9Maybe Mar 30, 2017
@nigeltao nigeltao removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. labels Mar 30, 2017
@rsc rsc reopened this Mar 30, 2017
@rsc
Copy link
Contributor

rsc commented Mar 30, 2017

Reopening until it's fixed in the release branch.

@rsc
Copy link
Contributor

rsc commented Apr 5, 2017

Wait, so this never worked, right? If it's not a regression from Go 1.7, it's not for the point release.

@rsc
Copy link
Contributor

rsc commented Apr 5, 2017

It's kind of a regression in that an error turned into a panic. But the CL turns it into working code. I'm not happy about adding new functionality in a point release.

$ cat /tmp/x.go
package main

import (
	"bytes"
	"fmt"
	"image/png"
	"log"
)

var buf = []byte{
	0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x85, 0x2c, 0x88, 0x80, 0x00, 0x00, 0x00, 0x02, 0x74, 0x52, 0x4e, 0x53, 0x00, 0xff, 0x5b, 0x91, 0x22, 0xb5, 0x00, 0x00, 0x00, 0x02, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0a, 0xf0, 0x00, 0x00, 0x0a, 0xf0, 0x01, 0x42, 0xac, 0x34, 0x98, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xd5, 0x04, 0x02, 0x12, 0x11, 0x11, 0xf7, 0x65, 0x3d, 0x8b, 0x00, 0x00, 0x00, 0x4f, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0xf8, 0xff, 0xff, 0xff, 0xb9, 0xbd, 0x70, 0xf0, 0x8c, 0x01, 0xc8, 0xaf, 0x6e, 0x99, 0x02, 0x05, 0xd9, 0x7b, 0xc1, 0xfc, 0x6b, 0xff, 0xa1, 0xa0, 0x87, 0x30, 0xff, 0xd9, 0xde, 0xbd, 0xd5, 0x4b, 0xf7, 0xee, 0xfd, 0x0e, 0xe3, 0xef, 0xcd, 0x06, 0x19, 0x14, 0xf5, 0x1e, 0xce, 0xef, 0x01, 0x31, 0x92, 0xd7, 0x82, 0x41, 0x31, 0x9c, 0x3f, 0x07, 0x02, 0xee, 0xa1, 0xaa, 0xff, 0xff, 0x9f, 0xe1, 0xd9, 0x56, 0x30, 0xf8, 0x0e, 0xe5, 0x03, 0x00, 0xa9, 0x42, 0x84, 0x3d, 0xdf, 0x8f, 0xa6, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
}

func main() {
	m, err := png.Decode(bytes.NewReader(buf))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%T\n", m)
}
$ go run /tmp/x.go
*image.NRGBA
$ go1.8 run /tmp/x.go
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x10a2278]

goroutine 1 [running]:
image/png.(*decoder).readImagePass(0xc420031000, 0x11fa058, 0xc420016230, 0x0, 0xc420016200, 0x0, 0x0, 0xc42008a000, 0xc420031078)
	/Users/rsc/go1.8/src/image/png/reader.go:615 +0x1028
image/png.(*decoder).decode(0xc420031000, 0x0, 0x0, 0x0, 0x0)
	/Users/rsc/go1.8/src/image/png/reader.go:365 +0x621
image/png.(*decoder).parseIDAT(0xc420031000, 0x4f, 0x10dd8c9, 0x4)
	/Users/rsc/go1.8/src/image/png/reader.go:827 +0x36
image/png.(*decoder).parseChunk(0xc420031000, 0x0, 0x0)
	/Users/rsc/go1.8/src/image/png/reader.go:887 +0x45a
image/png.Decode(0x1143100, 0xc4200122a0, 0x10042bc, 0xc42001a0b8, 0x0, 0x10cfdc0)
	/Users/rsc/go1.8/src/image/png/reader.go:946 +0x161
main.main()
	/tmp/x.go:15 +0xba
exit status 2
$ go1.7 run /tmp/x.go
2017/04/05 10:31:27 png: invalid format: chunk out of order
exit status 1
$ go1.6 run /tmp/x.go
2017/04/05 10:31:31 png: invalid format: chunk out of order
exit status 1
$ 

I will send a CL for the release branch that restores the old error instead. New functionality can wait for Go 1.9.

@bradfitz
Copy link
Contributor

bradfitz commented Apr 5, 2017

I just discovered the same.

bradfitz@gdev:~$ go run png.go
Success at devel +592037f Wed Mar 29 22:32:57 2017 +0000
bradfitz@gdev:~$ GOROOT=$HOME/go1.8 go run png.go
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x49f208]
 
goroutine 1 [running]:
image/png.(*decoder).readImagePass(0xc42002b000, 0x7fc9e192d058, 0xc42004e0f0, 0x0, 0xc42004e000, 0x0, 0x0, 0xc42008a000, 0xc42002b078)
        /home/bradfitz/go1.8/src/image/png/reader.go:615 +0x1028
image/png.(*decoder).decode(0xc42002b000, 0x0, 0x0, 0x0, 0x0)
        /home/bradfitz/go1.8/src/image/png/reader.go:365 +0x621
image/png.(*decoder).parseIDAT(0xc42002b000, 0x4f, 0x4dbaff, 0x4)
        /home/bradfitz/go1.8/src/image/png/reader.go:827 +0x36
image/png.(*decoder).parseChunk(0xc42002b000, 0x0, 0x0)
        /home/bradfitz/go1.8/src/image/png/reader.go:887 +0x45a
image/png.Decode(0x540120, 0xc420010240, 0xc42007c410, 0xcc, 0xcc, 0x0)
        /home/bradfitz/go1.8/src/image/png/reader.go:946 +0x161
main.main()
        /home/bradfitz/png.go:17 +0x11d
exit status 2
bradfitz@gdev:~$ GOROOT=$HOME/go1.7 go run png.go
2017/04/05 14:36:28 Decode returned err: png: invalid format: chunk out of order
bradfitz@gdev:~$ GOROOT=$HOME/go1.6 go run png.go
2017/04/05 14:36:31 Decode returned err: png: invalid format: chunk out of order
bradfitz@gdev:~$ GOROOT=$HOME/go1.5 go run png.go
2017/04/05 14:36:33 Decode returned err: png: invalid format: chunk out of order

@gopherbot
Copy link

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

@rsc
Copy link
Contributor

rsc commented Apr 5, 2017

Cherry-pick submitted.

@rsc rsc closed this as completed Apr 5, 2017
gopherbot pushed a commit that referenced this issue Apr 5, 2017
…rent gray8 images

Go 1.7 and earlier rejected these images with chunkOrderError.
Go 1.8 panicked during decoding.
Go 1.9 will handle them successfully.

Make Go 1.8.1 match Go 1.7 and earlier, to remove the panic
without introducing new functionality in a minor release.

Fixes #19553.

Change-Id: I3c73a27aa3932300326273b6b563cdf606f3ab64
Reviewed-on: https://go-review.googlesource.com/39593
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
@nigeltao
Copy link
Contributor

nigeltao commented Apr 5, 2017

For the record, the Go 1.8 release notes at https://golang.org/doc/go1.8 says:

Minor changes to the library
...
image/png
Decode (and DecodeConfig) now supports True Color and grayscale transparency.

and the "grayscale transparency" part of that was implemented by https://go-review.googlesource.com/32143, submitted October 2016. That feature had a panic'ing bug, fixed on tip by https://go-review.googlesource.com/38271, submitted March 2017.

So by restoring Go 1.7's behavior, we are removing a feature (which admittedly had a panic'ing bug) that we added in Go 1.8.0.

I'm not saying that restoring Go 1.7's behavior is wrong. I'm just making sure that everyone's clear on the context.

@bradfitz
Copy link
Contributor

bradfitz commented Apr 5, 2017

Oh.

That makes me less happy about the cherry-pick.

Is there a middle ground option between removing features and adding features, whereby we just return an error instead of panicking?

Looking at 16663a8, maybe just return an error if pixOffset > len(gray.Pix)?

@nigeltao
Copy link
Contributor

nigeltao commented Apr 5, 2017

On a closer inspection, rsc's cherry-pick only affects Gray8 transparency, not all grayscale transparency. To repeat, it does not affect Gray1, Gray2, Gray4 or Gray16 transparency. So it's not a big of a rollback as I first feared.

Such Gray8 transparent images never worked in Go 1.8.0. Non-8 images, such as Gray1, will continue to decode without error in 1.8.1 as they did in 1.8.0.

Still, it's a little weird in 1.8.x for G1, G2, G4 and G16 to all work, but G8 to return an error.

@bradfitz
Copy link
Contributor

bradfitz commented Apr 6, 2017

@rsc says: "I think it's fine to leave as is (returning an error). That code path never worked. I do see the discrepancy with the other gray depths, but those are the ones that actually got implemented for Go 1.8, and this one didn't."

@golang golang locked and limited conversation to collaborators Apr 6, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants