From ba8788ebcead55e99e631c6a1157ad7b35535d11 Mon Sep 17 00:00:00 2001 From: Roland Shoemaker Date: Wed, 15 Jun 2022 10:43:05 -0700 Subject: [release-branch.go1.17] go/parser: limit recursion depth Limit nested parsing to 100,000, which prevents stack exhaustion when parsing deeply nested statements, types, and expressions. Also limit the scope depth to 1,000 during object resolution. Thanks to Juho Nurminen of Mattermost for reporting this issue. Fixes #53707 Updates #53616 Fixes CVE-2022-1962 Change-Id: I4d7b86c1d75d0bf3c7af1fdea91582aa74272c64 Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1491025 Reviewed-by: Russ Cox Reviewed-by: Damien Neil (cherry picked from commit 6a856f08d58e4b6705c0c337d461c540c1235c83) Reviewed-on: https://go-review.googlesource.com/c/go/+/417070 Reviewed-by: Heschi Kreinick TryBot-Result: Gopher Robot Run-TryBot: Michael Knyszek --- src/go/parser/resolver.go | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/go/parser/resolver.go') diff --git a/src/go/parser/resolver.go b/src/go/parser/resolver.go index cf92c7e4f5..f55bdb7f17 100644 --- a/src/go/parser/resolver.go +++ b/src/go/parser/resolver.go @@ -25,6 +25,7 @@ func resolveFile(file *ast.File, handle *token.File, declErr func(token.Pos, str declErr: declErr, topScope: pkgScope, pkgScope: pkgScope, + depth: 1, } for _, decl := range file.Decls { @@ -53,6 +54,8 @@ func resolveFile(file *ast.File, handle *token.File, declErr func(token.Pos, str file.Unresolved = r.unresolved[0:i] } +const maxScopeDepth int = 1e3 + type resolver struct { handle *token.File declErr func(token.Pos, string) @@ -61,6 +64,7 @@ type resolver struct { pkgScope *ast.Scope // pkgScope.Outer == nil topScope *ast.Scope // top-most scope; may be pkgScope unresolved []*ast.Ident // unresolved identifiers + depth int // scope depth // Label scopes // (maintained by open/close LabelScope) @@ -83,6 +87,10 @@ func (r *resolver) sprintf(format string, args ...interface{}) string { } func (r *resolver) openScope(pos token.Pos) { + r.depth++ + if r.depth > maxScopeDepth { + panic(bailout{pos: pos, msg: "exceeded max scope depth during object resolution"}) + } if debugResolve { r.dump("opening scope @%v", pos) } @@ -90,6 +98,7 @@ func (r *resolver) openScope(pos token.Pos) { } func (r *resolver) closeScope() { + r.depth-- if debugResolve { r.dump("closing scope") } -- cgit v1.2.3-54-g00ecf