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

archive, image, debug, encoding, x/net/html: DO NOT PANIC #47653

Open
FiloSottile opened this issue Aug 11, 2021 · 13 comments
Open

archive, image, debug, encoding, x/net/html: DO NOT PANIC #47653

FiloSottile opened this issue Aug 11, 2021 · 13 comments
Assignees
Labels
NeedsFix
Milestone

Comments

@FiloSottile
Copy link
Contributor

@FiloSottile FiloSottile commented Aug 11, 2021

We have a number of packages that implement parsers where a panic might lead to a Denial of Service, but returning an invalid input error instead would be perfectly harmless. We should wrap them all in a recover() and prevent the panic from propagating, as a robustness and defense in depth measure.

We need to be careful about preserving documented panic conditions, and about not leaving behind persistent state that might be corrupt following a panic.

Ideas for other packages that can benefit are welcome. Crypto packages were intentionally left out, as we should be confident in their operation. math/big has a lot of entry points and persistent state by definition (and we have a plan to drag it out of the security perimeter).

/cc @golang/security

@FiloSottile FiloSottile added the NeedsFix label Aug 11, 2021
@FiloSottile FiloSottile added this to the Go1.18 milestone Aug 11, 2021
@FiloSottile FiloSottile self-assigned this Aug 11, 2021
@FiloSottile FiloSottile changed the title archive, image, encoding, x/net/html: DO NOT PANIC archive, image, debug, encoding, x/net/html: DO NOT PANIC Aug 27, 2021
@gopherbot
Copy link

@gopherbot gopherbot commented Oct 4, 2021

Change https://golang.org/cl/353850 mentions this issue: archive/zip, archive/tar: DO NOT PANIC

@gopherbot
Copy link

@gopherbot gopherbot commented Oct 4, 2021

Change https://golang.org/cl/353851 mentions this issue: image/gif, image/jpeg, image/png: DO NOT PANIC

@gopherbot
Copy link

@gopherbot gopherbot commented Oct 4, 2021

Change https://golang.org/cl/353852 mentions this issue: debug/macho: DO NOT PANIC

@mengzhuo
Copy link
Contributor

@mengzhuo mengzhuo commented Oct 18, 2021

Related to: #48085

@bcmills
Copy link
Member

@bcmills bcmills commented Oct 27, 2021

For libraries that wrap user-provided interfaces (such as reading from a user-provided io.Reader), I think it's important that we recover only panics that originate within the library, and not those that originate in the user code. Otherwise the recover can turn a diagnosable crash (or, worse, an intended panic/recover pair) into a hard-to-diagnose deadlock, which has its own problems.

One way to detect panics that originate within the library might be to use runtime.Callers to snoop the package for the first non-runtime frame. But then, the caller may be doing that already, and recovering the panic at all (even if it is re-panicked) will destroy the original stack trace. (The language provides no way to re-throw a recovered panic without destroying it, and since the language defines the behavior of panic and recover, any change to a package's recovery behavior is arguably a breaking change!)

Fortunately, we can use a variable to detect an abnormal exit, then snoop the caller stack, and finally recover only if the stack originates in the specific package (or perhaps one of a specific set of packages): https://play.golang.org/p/NAzk0ATvGx5

That would allow these packages to recover from internal bugs, but without masking (or destroying information from) panics in user code.

@bcmills
Copy link
Member

@bcmills bcmills commented Oct 27, 2021

That said, now that we have fuzzing coming I wonder whether the recovers are even necessary long-term. These packages seem like they should be extremely deterministic, so they should be very effective targets for fuzzer-generated inputs — and if we can find (and fix) the panics through fuzzing, there should be essentially nothing left to recover.

(That's in contrast with, say, packages with a large amount of nondeterminism like net/http.)

@fweimer-rh
Copy link

@fweimer-rh fweimer-rh commented Nov 12, 2021

Memory allocation failures remain an issue, though. I'm not sure to what extent the Go runtime even bothers to handle them.

With compression and APIs that expose entire sections of the file as arrays, it's really not possible to avoid memory allocation failures merely by checking the input file sizes prior to decoding. In other cases, there is a section which supposedly-small section that gets exposed as an array, and the bulk of the data is represented separately and can be accessed through a streaming interface (so its size does not matter for memory consumption purposes). Archive formats typically have this property.

For example, archive/zip represents the ZIP central directory as a []File array in Reader. Applications may want to process ZIP archives containing very large files (multiple gigabytes), not ZIP files with a billion entries in the central directory.

Maybe you could add a Security Considerations section to the package documentation detailing such issues?

@gopherbot
Copy link

@gopherbot gopherbot commented Dec 13, 2021

Change https://golang.org/cl/371394 mentions this issue: _content/doc/fuzz: fix example

@odeke-em
Copy link
Member

@odeke-em odeke-em commented Dec 20, 2021

@FiloSottile thank you for filing this issue!

So we have a bunch of CLs addressing parts of this issue starting from October 2021, but none of them have been merged. Shall we punt this issue instead to Go1.19 when we shall have more adequate time? What do y'all think @FiloSottile @bcmills @katiehockman @julieqiu? Thank you!

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jan 28, 2022

@FiloSottile @golang/security This is in the 1.18 milestone; time to move to 1.19? Thanks.

@rsc
Copy link
Contributor

@rsc rsc commented Feb 2, 2022

Agree about moving this to Go 1.19.

@gopherbot
Copy link

@gopherbot gopherbot commented Mar 18, 2022

Change https://go.dev/cl/393874 mentions this issue: debug/dwarf: better error detection in parseUnits

gopherbot pushed a commit that referenced this issue Mar 21, 2022
Tweak the (*Data).parseUnits method to check a bit more carefully for
buffer read errors, so as to avoid infinite looping on malformed
inputs.

Fixes #51758.
Updates #47653.

Change-Id: I6d67fcb53392acf651ceec636789ab9e49ad5a5c
Reviewed-on: https://go-review.googlesource.com/c/go/+/393874
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Trust: Than McIntosh <thanm@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
@gopherbot
Copy link

@gopherbot gopherbot commented Mar 31, 2022

Change https://go.dev/cl/396880 mentions this issue: debug/elf: check for negative shoff and phoff fields

gopherbot pushed a commit that referenced this issue Mar 31, 2022
No test because we could add an infinite number of tests of bogus data.

For #47653
Fixes #52035

Change-Id: Iec7e2fe23f2dd1cf14bad2475422f243f51028f5
Reviewed-on: https://go-review.googlesource.com/c/go/+/396880
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsFix
Projects
None yet
Development

No branches or pull requests

8 participants