buildid

command
v0.0.0-...-cf68f1b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 3, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package main implements the GNU build-ID tool used by the Bazel `content_build_id` rule (see defs.bzl).

Why this exists

rules_go links every Go binary with `-buildid=redacted` for reproducibility, and since Go 1.24 the Go linker derives the ELF `.note.gnu.build-id` note from that Go build ID by default (`-B gobuildid`). A constant input yields a constant note, so every aether Go binary ever built carried the same GNU build-ID (498919aff001d8366249403a2544fba2d833084f) no matter what code was in it (issue #651). Profilers that join samples to symbols purely by build-ID — the Pyroscope eBPF symbolizer does — then silently symbolize one binary against another binary's offsets.

The first fix (#652) rewrote the note to the release commit SHA. That traded one collision for another: a commit produces *seven* released ELFs, so all seven ended up sharing a single ID (issue #653). A GNU build-ID identifies a *linked object*, not a source revision.

What this tool writes

The ID is derived from the binary's own bytes, which is what `ld --build-id=sha1` does natively and what the custom Envoy now gets from the linker:

build_id = SHA-1( image bytes, with the 20-byte build-ID descriptor
                  field replaced by 20 zero bytes )

Zeroing the descriptor before hashing is what makes the value well defined: the descriptor is the one field the hash is about to overwrite, so excluding it removes the circular dependency. Three properties follow, and all three are covered by unit tests:

  • deterministic — the same image bytes always yield the same ID, so the ID is remote-cache-friendly and reproducible;
  • idempotent — writing the ID changes only the descriptor, which the hash ignores, so re-running the tool on an already-written binary computes and writes exactly the same 20 bytes;
  • collision-free in practice — two ELFs that differ anywhere outside the descriptor get different IDs, which is precisely the #653 requirement.

Nothing else in the image moves: the descriptor is exactly 20 bytes wide, the same width as a SHA-1 digest, so the note is patched in place.

Release traceability does not live in this note. It lives in the `--stamp` x_defs version information and in the image tags; the ELF note is the symbolizer's key and nothing else.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL