Documentation
¶
Overview ¶
Package callgraph is the deterministic call-graph domain model (Tier-2 shared foundation): a directed graph of function-call edges plus the entrypoints reachability is measured from, and the pure query primitives over it. It is the SEAM both Tier-2 consumers build on – reachability PROOF ("is this vulnerable symbol actually called?") and taint SAST ("does a source reach a sink?").
The model is deterministic and tool-agnostic: a builder adapter (Go SSA / govulncheck-class, shelled via argv) produces a Graph; the queries here are pure Go, so they are table-testable with no tool and a Tier-2 result is reproducible. Node identity is the same "importPath.Symbol" convention the OSV adapter emits for a vulnerability's affected symbols – so a reachability query can intersect call-graph nodes with a vuln's AffectedSymbols directly, with no translation.
SCOPE: this models REACHABILITY (does a call path exist). Taint analysis needs richer edges – which argument/return flows, and sanitizer nodes that break a path – so it layers its OWN edge-attribute + sanitizer model on top of this node-identity convention rather than stretching Edge with optional taint fields (which would degrade the reachability primitive). Edge here stays a plain call edge.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Edge ¶
Edge is one node's outgoing calls: Caller calls each symbol in Callees. Symbols are "importPath.Symbol" identities (e.g. "github.com/foo/bar.Vuln"), matching vulnerability AffectedSymbols.
type Graph ¶
type Graph struct {
Entrypoints []string
Edges []Edge
// Positions carries no json tag to match Entrypoints/Edges: the domain Graph is never marshaled
// directly — the synapse-callgraph wire type (taintcallgraph.wireGraph) owns serialization.
Positions map[string]string
// BlindConstructs names reachable-surface constructs the builder could NOT follow (reflection, cgo,
// go:linkname, unsafe function calls). It is analysis-WIDE: any not_reachable verdict derived from this
// graph is unsound while a blind construct is present, so a reachability consumer must refuse to suppress
// on it (EPIC #1042 #1065). Empty means the builder saw no such construct. Descriptive only: the
// adjacency/Reachable/PathTo queries never read it.
BlindConstructs []string
// BlindSymbols narrows a bounded opaque edge to the symbols it may reach. Unlike BlindConstructs, an
// entry here taints only that symbol's result, so an independently disjoint negative remains usable.
BlindSymbols map[string][]string
}
Graph is a deterministic call graph: the call Edges plus the Entrypoints reachability is measured from (a Go build's main + exported API). A builder adapter populates it; the query methods are pure.
Positions is an OPTIONAL side table: a first-party node's "importPath.Symbol" → its definition position as "relpath:line" (relative to the scan root, never an absolute host path). It exists so a taint SAST finding can cite a file:line for the sink-using function instead of only its symbol (def-use precision; a coarse, function-granular over-approximation — the function's definition line, not the exact sink call site). It is purely descriptive: the reachability queries (adjacency/Reachable/PathTo) never read it, so a builder that omits it (empty map) degrades gracefully to symbol-only locations. Only file PATHS + lines are carried here — never file CONTENTS (GR3).
func (Graph) PathTo ¶
PathTo returns a shortest call path from an entrypoint to target as [entrypoint,..., target] – the PROOF that target is reachable (an explainable "main → … → vulnFunc" chain). It returns nil when target is unreachable from every entrypoint (including when target is not in the graph). A single-element path means target is itself an entrypoint. BFS, so the path is shortest; cycle-safe. When several shortest paths exist, the one via the earliest entrypoint then earliest edge order wins – deterministic for a fixed Graph (golden tests + the human-facing reachability proof depend on this).
func (Graph) Reachable ¶
Reachable returns the set of symbols reachable from any entrypoint by following call edges forward (the entrypoints themselves are included). Cycle-safe. Build once, then test many candidate symbols against it – the shape it wants when filtering a vuln's AffectedSymbols to the reachable ones.