Fix pprof validation: nil period_type and off-by-one string-table bounds#6376
Merged
Merged
Conversation
ValidatePprofProfile runs on the WriteRaw ingest path, so it sees attacker-influenced pprof bytes. Two crashes are reachable there. First, period_type is an optional field and comes across as a nil *ValueType when omitted. Every other pointer in the validator is nil-checked, but the period_type branch dereferences p.PeriodType directly, so a profile that simply leaves it out panics inside the validator. Guard it like the rest. Second, the string-table index checks use > len(StringTable). String indices are 0-based, so the only valid values are 0..len-1 and an index equal to len passes the check but is one past the end. Downstream code (MetaFromPprof, LabelsFromSample) then indexes it and panics. Switch the eleven 0-based string-index checks to >=. The 1-based id checks (mapping/function/location) are left as > since len is a valid id there. Adds a table-driven test covering an omitted period_type and an index equal to the string-table length for both the sample-type and period-type paths. Signed-off-by: Arpit Jain <arpitjain099@gmail.com>
brancz
approved these changes
Jul 20, 2026
Member
|
Thank you very much! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
While reading the pprof ingest path I hit two panics in ValidatePprofProfile (pkg/normalizer/validate.go). This validator runs on the WriteRaw gRPC ingest that every agent uses to push profiles, so the profile bytes are attacker-influenced, and both cases crash the validator (or the code just past it) rather than returning an error.
The first is a nil pointer deref. period_type is optional, so a profile that omits it arrives with a nil PeriodType. The rest of the function nil-checks its pointer fields, but the period_type branch dereferences p.PeriodType.Type directly, so merely leaving the field out panics inside the validator. I wrapped those two checks in a nil guard like everything else.
The second is an off-by-one in the string-table bounds checks. They use
> len(StringTable), but string indices are 0-based, so the valid range is 0..len-1. An index exactly equal to len slips through the check and is one past the end, and downstream code (MetaFromPprof, LabelsFromSample) then indexes it and panics with index out of range. I changed the eleven 0-based string-index checks to>=. I left the mapping/function/location id checks as>on purpose, since those ids are 1-based and len is a valid id.Added a table-driven test in the normalizer package: an omitted period_type, and an index equal to the string-table length on both the sample-type and period-type paths, plus a valid control. The bad cases panic (or are wrongly accepted) before the change and return a clean error or validate fine after it.
go test ./pkg/normalizer/...passes.Happy to sign the CLA. Let me know if you would rather split the two fixes or send this against a release branch.