Go: cmd/compile: depth limit reached in type formatting routine

Created on 17 Dec 2018  路  13Comments  路  Source: golang/go

Place holder issue for cases of overly deep types or (invalid) recursive types. See #29264 for an example.

NeedsInvestigation

Most helpful comment

This exploit doesn't require multiple threads, unlike Russ' example.
We've tried to keep Go strongly type safe in the absence of unsafe and data races. This exploit breaks that idea.

All 13 comments

Change https://golang.org/cl/154583 mentions this issue: cmd/compile: increase nesting depth limit for type descriptors

A recursive type where we currently fail:

type T interface {
    M(interface {
        T
    })
}

(from #16369).

32547 is a test case that fails due to the recursion limit, although the test itself does not use recursion. It just uses a very very very deep pointer type.

An update on this bug:

At Google CTF finals this year a team was able to exploit this behavior and obtain remote code execution without importing any package except for "fmt".

The issue is that some code that was supposedly safe had a memory corruption due to a very deep type.

Here you can find a write up of the challenge, and here is the exploit.

When there is a very deep type (253 in this case) the compiler generates an incorrect program. In my opinion this should not be the case and it should instead reject the invalid code (after all, the generated program will not work anyways).

/cc @mvdan @FiloSottile

Marking as a release blocker for 1.14.

I don't see a reason to block the beta release for this.

Is there a threat model in which this attack is possible but https://research.swtch.com/gorace isn鈥檛?

This exploit doesn't require multiple threads, unlike Russ' example.
We've tried to keep Go strongly type safe in the absence of unsafe and data races. This exploit breaks that idea.

This bug has been there for quite a while and the threat model requires a lot of control on the attacker side (almost arbitrary code).

I don't know if this is exploitable by creating the type via reflection but even if it is it would still require the attacker to call arbitrary primitives, which is unlikely.

It would be nice to have this fixed for the next release but I would not say this is a blocker for 1.14.

This is a classic type confusion and definitely a mis-compilation (as well as an amazing CTF trick). It also introduces unsafety which can't be detected by looking for usages of unsafe or by the race detector. It sounds like something we should fix.

However, I believe we (rightfully) gave up on this threat model with the removal of "safe" mode in Go 1.12 (5185744962d402df083d118036f9bef8c2e2d3b6), so I agree that this is not a security issue.

/cc @randall77 @griesemer Please let us know when there are updates on this issue, as this is currently marked a release blocker for 1.14.

Change https://golang.org/cl/213517 mentions this issue: cmd/compile: give every really deep type a unique name

The security hole aspects of this issue have been fixed. Removing release blocker and punting to 1.15.

Change https://golang.org/cl/214239 mentions this issue: cmd/compile: print recursive types correctly

Was this page helpful?
0 / 5 - 0 ratings