internal/report: add lint check for runtime symbols

Add a lint check that enforces that the "runtime" package
in the standard library never has any symbols.

Fixes golang/go#66143

Change-Id: I4db085a152ea87927bb850c4c0d704063510bbf1
Reviewed-on: https://go-review.googlesource.com/c/vulndb/+/569616
Reviewed-by: Zvonimir Pavlinovic <zpavlinovic@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/internal/report/lint.go b/internal/report/lint.go
index 38fad93..d66d05c 100644
--- a/internal/report/lint.go
+++ b/internal/report/lint.go
@@ -507,10 +507,15 @@
 			if !strings.HasPrefix(p.Package, m.Module) {
 				l.Error("module must be a prefix of package")
 			}
-		} else if strings.HasPrefix(p.Package, stdlib.ToolchainModulePath) {
+		} else {
+			if p.Package == "runtime" && len(p.Symbols) != 0 {
+				l.Errorf("runtime package must have no symbols (found %d)", len(p.Symbols))
+			}
 			// As a special case, check for "cmd/" packages that are
 			// mistakenly placed in the "std" module.
-			l.Error("must be in module cmd")
+			if strings.HasPrefix(p.Package, stdlib.ToolchainModulePath) {
+				l.Error("must be in module cmd")
+			}
 		}
 
 		if !m.IsFirstParty() {
diff --git a/internal/report/lint_test.go b/internal/report/lint_test.go
index 3af92bc..8392a35 100644
--- a/internal/report/lint_test.go
+++ b/internal/report/lint_test.go
@@ -419,6 +419,23 @@
 			wantNumLints: 1,
 		},
 		{
+			name: "runtime_package_with_symbols",
+			desc: "In standard library reports, the runtime package must not contain any symbols.",
+			report: validStdReport(func(r *Report) {
+				r.Modules = append(r.Modules,
+					&Module{
+						Module:       "std",
+						VulnerableAt: "1.0.0",
+						Packages: []*Package{{
+							Package: "runtime",
+							Symbols: []string{"foo"},
+						}},
+					},
+				)
+			}),
+			wantNumLints: 1,
+		},
+		{
 			name: "wrong_module_cmd",
 			desc: "Packages beginning with 'cmd' should be in the 'cmd' module.",
 			report: validStdReport(func(r *Report) {
diff --git a/internal/report/testdata/lint/TestLintOffline/runtime_package_with_symbols.txtar b/internal/report/testdata/lint/TestLintOffline/runtime_package_with_symbols.txtar
new file mode 100644
index 0000000..048a4dc
--- /dev/null
+++ b/internal/report/testdata/lint/TestLintOffline/runtime_package_with_symbols.txtar
@@ -0,0 +1,29 @@
+Copyright 2024 The Go Authors. All rights reserved.
+Use of this source code is governed by a BSD-style
+license that can be found in the LICENSE file.
+
+Test: TestLintOffline/runtime_package_with_symbols
+Description: In standard library reports, the runtime package must not contain any symbols.
+
+-- data/reports/GO-0000-0000.yaml --
+id: GO-0000-0000
+modules:
+    - module: std
+      vulnerable_at: 1.2.3
+      packages:
+        - package: net/http
+    - module: std
+      vulnerable_at: 1.0.0
+      packages:
+        - package: runtime
+          symbols:
+            - foo
+summary: A summary of the problem with net/http
+description: description
+references:
+    - fix: https://go.dev/cl/12345
+    - web: https://groups.google.com/g/golang-announce/c/12345
+    - report: https://go.dev/issue/12345
+
+-- golden --
+modules[1] "std": packages[0] "runtime": runtime package must have no symbols (found 1)