summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/go/go-1.14/CVE-2021-38297.patch
blob: 24ceabf8083d33a6fe7f135ef60b50fb3ed4493c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
From 4548fcc8dfd933c237f29bba6f90040a85922564 Mon Sep 17 00:00:00 2001
From: Michael Knyszek <mknyszek@google.com>
Date: Thu, 2 Sep 2021 16:51:59 -0400
Subject: [PATCH] [release-branch.go1.16] misc/wasm, cmd/link: do not let
 command line args overwrite global data

On Wasm, wasm_exec.js puts command line arguments at the beginning
of the linear memory (following the "zero page"). Currently there
is no limit for this, and a very long command line can overwrite
the program's data section. Prevent this by limiting the command
line to 4096 bytes, and in the linker ensuring the data section
starts at a high enough address (8192).

(Arguably our address assignment on Wasm is a bit confusing. This
is the minimum fix I can come up with.)

Thanks to Ben Lubar for reporting this issue.

Change by Cherry Mui <cherryyz@google.com>.

For #48797
Fixes #48799
Fixes CVE-2021-38297

Change-Id: I0f50fbb2a5b6d0d047e3c134a88988d9133e4ab3
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1205933
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/354591
Trust: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>

CVE: CVE-2021-38297

Upstream-Status: Backport:
https://github.com/golang/go/commit/4548fcc8dfd933c237f29bba6f90040a85922564

Inline of ctxt.isWAsm followin this implemetation:
https://github.com/golang/go/blob/4548fcc8dfd933c237f29bba6f90040a85922564/src/cmd/link/internal/ld/target.go#L127

Signed-off-by: Davide Gardenal <davide.gardenal@huawei.com>
---
 misc/wasm/wasm_exec.js           |  7 +++++++
 src/cmd/link/internal/ld/data.go | 11 ++++++++++-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/misc/wasm/wasm_exec.js b/misc/wasm/wasm_exec.js
index 82041e6bb901..a0a264278b1b 100644
--- a/misc/wasm/wasm_exec.js
+++ b/misc/wasm/wasm_exec.js
@@ -564,6 +564,13 @@
 				offset += 8;
 			});
 
+			// The linker guarantees global data starts from at least wasmMinDataAddr.
+			// Keep in sync with cmd/link/internal/ld/data.go:wasmMinDataAddr.
+			const wasmMinDataAddr = 4096 + 4096;
+			if (offset >= wasmMinDataAddr) {
+				throw new Error("command line too long");
+			}
+
 			this._inst.exports.run(argc, argv);
 			if (this.exited) {
 				this._resolveExitPromise();
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
index 52035e96301c..54a1d188cdb9 100644
--- a/src/cmd/link/internal/ld/data.go
+++ b/src/cmd/link/internal/ld/data.go
@@ -2330,6 +2330,11 @@ func assignAddress(ctxt *Link, sect *sym.Section, n int, s loader.Sym, va uint64
 	return sect, n, va
 }
 
+// On Wasm, we reserve 4096 bytes for zero page, then 4096 bytes for wasm_exec.js
+// to store command line args. Data sections starts from at least address 8192.
+// Keep in sync with wasm_exec.js.
+const wasmMinDataAddr = 4096 + 4096
+
 // address assigns virtual addresses to all segments and sections and
 // returns all segments in file order.
 func (ctxt *Link) address() []*sym.Segment {
@@ -2339,10 +2344,14 @@ func (ctxt *Link) address() []*sym.Segment {
 	order = append(order, &Segtext)
 	Segtext.Rwx = 05
 	Segtext.Vaddr = va
-	for _, s := range Segtext.Sections {
+	for i, s := range Segtext.Sections {
 		va = uint64(Rnd(int64(va), int64(s.Align)))
 		s.Vaddr = va
 		va += s.Length
+
+		if ctxt.Arch.Family == sys.Wasm && i == 0 && va < wasmMinDataAddr {
+			va = wasmMinDataAddr
+		}
 	}
 
 	Segtext.Length = va - uint64(*FlagTextAddr)