Skip to content

Commit 0b50c25

Browse files
committed
internal/vulncheck: add position for sinks in findings' trace
The sink is the vulnerable function. Before, we wouldn't show anything as we are only showing positions of calls. Now, we include the position where the vulnerable symbol is defined. This will not have effect on default text output. It will though on -show traces output. The main beneficiary of this change are integration points that will now be able to jump to the definition of the vulnerable symbol. Change-Id: Ie156bf5d05dc1c743f118f4d14dba6e2c263549b Reviewed-on: https://go-review.googlesource.com/c/vuln/+/559275 Reviewed-by: Maceo Thompson <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Run-TryBot: Zvonimir Pavlinovic <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent f50d9a6 commit 0b50c25

File tree

8 files changed

+85
-27
lines changed

8 files changed

+85
-27
lines changed

cmd/govulncheck/testdata/testfiles/source-call/source_call_json.ct

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,13 @@ $ govulncheck -C ${moddir}/vuln -json ./...
249249
"version": "v1.6.5",
250250
"package": "github.com/tidwall/gjson",
251251
"function": "Get",
252-
"receiver": "Result"
252+
"receiver": "Result",
253+
"position": {
254+
"filename": ".../gjson.go",
255+
"offset": 5744,
256+
"line": 296,
257+
"column": 17
258+
}
253259
},
254260
{
255261
"module": "golang.org/vuln",
@@ -364,7 +370,13 @@ $ govulncheck -C ${moddir}/vuln -json ./...
364370
"module": "golang.org/x/text",
365371
"version": "v0.3.0",
366372
"package": "golang.org/x/text/language",
367-
"function": "Parse"
373+
"function": "Parse",
374+
"position": {
375+
"filename": ".../parse.go",
376+
"offset": 5808,
377+
"line": 228,
378+
"column": 6
379+
}
368380
},
369381
{
370382
"module": "golang.org/vuln",
@@ -478,7 +490,13 @@ $ govulncheck -C ${moddir}/vuln -json ./...
478490
"version": "v1.6.5",
479491
"package": "github.com/tidwall/gjson",
480492
"function": "ForEach",
481-
"receiver": "Result"
493+
"receiver": "Result",
494+
"position": {
495+
"filename": ".../gjson.go",
496+
"offset": 4415,
497+
"line": 220,
498+
"column": 17
499+
}
482500
},
483501
{
484502
"module": "github.com/tidwall/gjson",

cmd/govulncheck/testdata/testfiles/source-call/source_call_text.ct

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ Vulnerability #1: GO-2021-0265
6161
Example traces found:
6262
#1: for function github.com/tidwall/gjson.Result.Get
6363
.../vuln.go:14:20: golang.org/vuln.main
64-
github.com/tidwall/gjson.Result.Get
64+
.../gjson.go:296:17: github.com/tidwall/gjson.Result.Get
6565

6666
Vulnerability #2: GO-2021-0113
6767
Due to improper index calculation, an incorrectly formatted language tag can
@@ -75,7 +75,7 @@ Vulnerability #2: GO-2021-0113
7575
Example traces found:
7676
#1: for function golang.org/x/text/language.Parse
7777
.../vuln.go:13:16: golang.org/vuln.main
78-
golang.org/x/text/language.Parse
78+
.../parse.go:228:6: golang.org/x/text/language.Parse
7979

8080
Vulnerability #3: GO-2021-0054
8181
Due to improper bounds checking, maliciously crafted JSON objects can cause
@@ -92,7 +92,7 @@ Vulnerability #3: GO-2021-0054
9292
.../gjson.go:1881:36: github.com/tidwall/gjson.Get
9393
.../gjson.go:2587:21: github.com/tidwall/gjson.execModifier
9494
.../gjson.go:2631:21: github.com/tidwall/gjson.modPretty
95-
github.com/tidwall/gjson.Result.ForEach
95+
.../gjson.go:220:17: github.com/tidwall/gjson.Result.ForEach
9696

9797
Your code is affected by 3 vulnerabilities from 2 modules.
9898
This scan also found 0 vulnerabilities in packages you import and 2

cmd/govulncheck/testdata/testfiles/source-call/source_multientry_json.ct

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,13 @@ $ govulncheck -json -C ${moddir}/multientry .
240240
"module": "golang.org/x/text",
241241
"version": "v0.3.5",
242242
"package": "golang.org/x/text/language",
243-
"function": "MustParse"
243+
"function": "MustParse",
244+
"position": {
245+
"filename": ".../tags.go",
246+
"offset": 427,
247+
"line": 13,
248+
"column": 6
249+
}
244250
},
245251
{
246252
"module": "golang.org/multientry",
@@ -287,7 +293,13 @@ $ govulncheck -json -C ${moddir}/multientry .
287293
"module": "golang.org/x/text",
288294
"version": "v0.3.5",
289295
"package": "golang.org/x/text/language",
290-
"function": "Parse"
296+
"function": "Parse",
297+
"position": {
298+
"filename": ".../parse.go",
299+
"offset": 1121,
300+
"line": 33,
301+
"column": 6
302+
}
291303
},
292304
{
293305
"module": "golang.org/multientry",

cmd/govulncheck/testdata/testfiles/source-call/source_multientry_text.ct

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ Vulnerability #1: GO-2021-0113
4545
.../main.go:26:3: golang.org/multientry.main
4646
.../main.go:48:8: golang.org/multientry.D
4747
.../main.go:99:20: golang.org/multientry.foobar
48-
golang.org/x/text/language.MustParse
48+
.../tags.go:13:6: golang.org/x/text/language.MustParse
4949
#2: for function golang.org/x/text/language.Parse
5050
.../main.go:22:3: golang.org/multientry.main
5151
.../main.go:44:23: golang.org/multientry.C
52-
golang.org/x/text/language.Parse
52+
.../parse.go:33:6: golang.org/x/text/language.Parse
5353

5454
=== Package Results ===
5555

cmd/govulncheck/testdata/testfiles/source-call/source_stdlib_text.ct

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Vulnerability #1: GO-2022-0969
3939
Example traces found:
4040
#1: for function net/http.ListenAndServe
4141
.../stdlib.go:17:31: golang.org/stdlib.main
42-
net/http.ListenAndServe
42+
.../server.go:3439:6: net/http.ListenAndServe
4343

4444
Your code is affected by 1 vulnerability from the Go standard library.
4545
This scan found no other vulnerabilities in packages you import or modules you

cmd/govulncheck/testdata/testfiles/source-call/source_subdir_text.ct

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Vulnerability #1: GO-2021-0113
4242
Example traces found:
4343
#1: for function golang.org/x/text/language.Parse
4444
.../subdir.go:8:16: golang.org/vuln/subdir.Foo
45-
golang.org/x/text/language.Parse
45+
.../parse.go:228:6: golang.org/x/text/language.Parse
4646

4747
Your code is affected by 1 vulnerability from 1 module.
4848
This scan also found 0 vulnerabilities in packages you import and 2

cmd/govulncheck/testdata/testfiles/source-call/source_vendored_json.ct

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,13 @@ $ govulncheck -C ${moddir}/vendored -json ./...
249249
"version": "v1.6.5",
250250
"package": "github.com/tidwall/gjson",
251251
"function": "Get",
252-
"receiver": "Result"
252+
"receiver": "Result",
253+
"position": {
254+
"filename": ".../gjson.go",
255+
"offset": 81,
256+
"line": 7,
257+
"column": 15
258+
}
253259
},
254260
{
255261
"module": "private.com/privateuser/fakemod",
@@ -376,7 +382,13 @@ $ govulncheck -C ${moddir}/vendored -json ./...
376382
"module": "golang.org/x/text",
377383
"version": "v0.3.0",
378384
"package": "golang.org/x/text/language",
379-
"function": "Parse"
385+
"function": "Parse",
386+
"position": {
387+
"filename": ".../language.go",
388+
"offset": 53,
389+
"line": 5,
390+
"column": 6
391+
}
380392
},
381393
{
382394
"module": "golang.org/vendored",

internal/vulncheck/emit.go

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package vulncheck
66

77
import (
8+
"go/token"
89
"sort"
910

1011
"golang.org/x/tools/go/packages"
@@ -76,39 +77,54 @@ func emitCallFindings(handler govulncheck.Handler, callstacks map[*Vuln]CallStac
7677
if err := handler.Finding(&govulncheck.Finding{
7778
OSV: vuln.OSV.ID,
7879
FixedVersion: fixed,
79-
Trace: tracefromEntries(stack),
80+
Trace: traceFromEntries(stack),
8081
}); err != nil {
8182
return err
8283
}
8384
}
8485
return nil
8586
}
8687

87-
// tracefromEntries creates a sequence of
88+
// traceFromEntries creates a sequence of
8889
// frames from vcs. Position of a Frame is the
8990
// call position of the corresponding stack entry.
90-
func tracefromEntries(vcs CallStack) []*govulncheck.Frame {
91+
func traceFromEntries(vcs CallStack) []*govulncheck.Frame {
9192
var frames []*govulncheck.Frame
9293
for i := len(vcs) - 1; i >= 0; i-- {
9394
e := vcs[i]
9495
fr := frameFromPackage(e.Function.Package)
9596
fr.Function = e.Function.Name
9697
fr.Receiver = e.Function.Receiver()
97-
if e.Call == nil || e.Call.Pos == nil {
98-
fr.Position = nil
99-
} else {
100-
fr.Position = &govulncheck.Position{
101-
Filename: e.Call.Pos.Filename,
102-
Offset: e.Call.Pos.Offset,
103-
Line: e.Call.Pos.Line,
104-
Column: e.Call.Pos.Column,
105-
}
106-
}
98+
isSink := i == (len(vcs) - 1)
99+
fr.Position = posFromStackEntry(e, isSink)
107100
frames = append(frames, fr)
108101
}
109102
return frames
110103
}
111104

105+
func posFromStackEntry(e StackEntry, sink bool) *govulncheck.Position {
106+
var p *token.Position
107+
if sink && e.Function != nil && e.Function.Pos != nil {
108+
// For sinks, i.e., vulns we take the position
109+
// of the symbol.
110+
p = e.Function.Pos
111+
} else if e.Call != nil && e.Call.Pos != nil {
112+
// Otherwise, we take the position of
113+
// the call statement.
114+
p = e.Call.Pos
115+
}
116+
117+
if p == nil {
118+
return nil
119+
}
120+
return &govulncheck.Position{
121+
Filename: p.Filename,
122+
Offset: p.Offset,
123+
Line: p.Line,
124+
Column: p.Column,
125+
}
126+
}
127+
112128
func frameFromPackage(pkg *packages.Package) *govulncheck.Frame {
113129
fr := &govulncheck.Frame{}
114130
if pkg != nil {

0 commit comments

Comments
 (0)