blob: 6b5dc2c8d9f59843046e78be5bb85261da51b449 [file] [log] [blame]
Patrick Williams8e7b46e2023-05-01 14:19:06 -05001From 110e4fb1c2e3a21631704bbfaf672230b9ba2492 Mon Sep 17 00:00:00 2001
2From: Damien Neil <dneil@google.com>
3Date: Wed, 22 Mar 2023 09:33:22 -0700
4Subject: [PATCH] go/scanner: reject large line and column numbers in //line
5 directives
6
7Setting a large line or column number using a //line directive can cause
8integer overflow even in small source files.
9
10Limit line and column numbers in //line directives to 2^30-1, which
11is small enough to avoid int32 overflow on all reasonbly-sized files.
12
13For #59180
14Fixes CVE-2023-24537
15
16Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1802456
17Reviewed-by: Julie Qiu <julieqiu@google.com>
18Reviewed-by: Roland Shoemaker <bracewell@google.com>
19Run-TryBot: Damien Neil <dneil@google.com>
20Change-Id: I149bf34deca532af7994203fa1e6aca3c890ea14
21Reviewed-on: https://go-review.googlesource.com/c/go/+/482078
22Reviewed-by: Matthew Dempsky <mdempsky@google.com>
23TryBot-Bypass: Michael Knyszek <mknyszek@google.com>
24Run-TryBot: Michael Knyszek <mknyszek@google.com>
25Auto-Submit: Michael Knyszek <mknyszek@google.com>
26
27CVE: CVE-2023-24537
28Upstream-Status: Backport
29Signed-off-by: Ross Burton <ross.burton@arm.com>
30---
31 src/go/parser/parser_test.go | 16 ++++++++++++++++
32 src/go/scanner/scanner.go | 7 +++++--
33 2 files changed, 21 insertions(+), 2 deletions(-)
34
35diff --git a/src/go/parser/parser_test.go b/src/go/parser/parser_test.go
36index 153562df75068..22b11a0cc4535 100644
37--- a/src/go/parser/parser_test.go
38+++ b/src/go/parser/parser_test.go
39@@ -764,3 +764,19 @@ func TestRangePos(t *testing.T) {
40 })
41 }
42 }
43+
44+// TestIssue59180 tests that line number overflow doesn't cause an infinite loop.
45+func TestIssue59180(t *testing.T) {
46+ testcases := []string{
47+ "package p\n//line :9223372036854775806\n\n//",
48+ "package p\n//line :1:9223372036854775806\n\n//",
49+ "package p\n//line file:9223372036854775806\n\n//",
50+ }
51+
52+ for _, src := range testcases {
53+ _, err := ParseFile(token.NewFileSet(), "", src, ParseComments)
54+ if err == nil {
55+ t.Errorf("ParseFile(%s) succeeded unexpectedly", src)
56+ }
57+ }
58+}
59diff --git a/src/go/scanner/scanner.go b/src/go/scanner/scanner.go
60index 16958d22ce299..0cd9f5901d0bb 100644
61--- a/src/go/scanner/scanner.go
62+++ b/src/go/scanner/scanner.go
63@@ -253,13 +253,16 @@ func (s *Scanner) updateLineInfo(next, offs int, text []byte) {
64 return
65 }
66
67+ // Put a cap on the maximum size of line and column numbers.
68+ // 30 bits allows for some additional space before wrapping an int32.
69+ const maxLineCol = 1<<30 - 1
70 var line, col int
71 i2, n2, ok2 := trailingDigits(text[:i-1])
72 if ok2 {
73 //line filename:line:col
74 i, i2 = i2, i
75 line, col = n2, n
76- if col == 0 {
77+ if col == 0 || col > maxLineCol {
78 s.error(offs+i2, "invalid column number: "+string(text[i2:]))
79 return
80 }
81@@ -269,7 +272,7 @@ func (s *Scanner) updateLineInfo(next, offs int, text []byte) {
82 line = n
83 }
84
85- if line == 0 {
86+ if line == 0 || line > maxLineCol {
87 s.error(offs+i, "invalid line number: "+string(text[i:]))
88 return
89 }