When a Valid-Looking Babel Packet Is Wrong
The Babel case in SPAR’s paper is useful because it turns an abstract semantic gap into a diagnosis: an RFC requires a relationship between fields, while an implementation accepts a packet that violates it. This chapter follows that mismatch from the normative rule to the parser decision and then to the reported routing consequences. The aim is not to reproduce an exploit, but to show how a targeted invalid packet can establish a conformance problem and where the available evidence stops.
The symptom is acceptance, not a crash
The relevant Babel defect does not begin with a spectacular failure. It begins with a packet that can be laid out and read. The fields have recognizable positions. Their values fit into their allocated widths. A conventional parser can move through the message without running out of bytes or encountering an impossible primitive type.
The problem appears when those values are considered together. In a Babel Update message, AE identifies an address encoding, while Plen, Omitted, and Prefix determine how an advertised network prefix is represented. RFC 8966 states that when AE equals 3, Omitted must be zero. The condition is a rule about a combination, not a range that belongs to one field.
A useful diagnostic question is therefore not “can the parser read this message?” but “does the parser reject a message whose fields contradict the protocol’s stated relationship?” That question separates a structural symptom from a semantic cause. If the parser accepts a message with AE = 3 and a nonzero Omitted, the acceptance is evidence that the dependency was not enforced somewhere in the implementation path.
The USENIX paper presents precisely this omission in a Babel implementation from FRRouting. Its correction adds the missing check. The paper uses the example to show why a formal format that records cross-field constraints can expose a bug that ordinary format descriptions leave invisible: a negative packet can be valid enough to reach the relevant logic while being invalid in exactly one meaningful way.
Reconstructing the mismatch
Start with the rule, not with the implementation. The RFC supplies a condition that can be stated plainly:
- The Update’s address-encoding value selects how the address-related data is interpreted.
- In the
AE = 3case, the omitted-byte count must be zero. - The Prefix field’s size is tied to the prefix length and the omitted-byte count.
The first statement gives the parser a mode. The second limits a value in that mode. The third connects the values to the amount of data consumed. Together they form a small contract. A packet that violates the second condition is not merely “unusual”; it asks the implementation to interpret an address representation that the RFC declares invalid.
The test that exposes the omission can be described without raw bytes. Construct an otherwise coherent Update candidate, choose the special address-encoding case, and set Omitted to a nonzero value. The surrounding fields should remain consistent enough that the test reaches the relevant validation decision. The point is to negate one semantic condition, not to combine arbitrary truncation, random lengths, and unrelated malformed values.
That distinction is important for diagnosis. If a test changes many things at once, a rejection has several possible causes. The parser might reject the length, the type, the address representation, or the omitted count. The result would show that the input is not accepted, but not which rule caused the decision. A targeted negative packet narrows the interpretation: the expected outcome is rejection because the selected relationship is false.
Holding the surrounding structure steady also makes the comparison more informative. The test is not trying to prove that the parser accepts every well-formed Update, or that one invalid combination is the only way to reach the relevant code. It isolates a question about one contract: when the selected encoding case is used, does the implementation enforce the corresponding omitted-byte condition? A positive case establishes the nearby behavior that should remain valid; a negative case changes the relationship and leaves the rest of the format as stable as the model allows. The contrast gives the finding a causal shape instead of a vague association with malformed input.
This way of thinking is useful beyond the particular Babel fields. When a count controls a later array, a semantic test can keep the count and array relationship valid, then challenge the exact boundary being checked. When a flag changes the meaning of a suffix, a test can preserve the flag’s local validity while asking whether the suffix follows the selected interpretation. In each case, the test is a small experiment on a protocol contract. Its value comes from the claim it isolates, not from the sheer oddness of the bytes.
The FRRouting implementation described by the paper did not perform that relationship check. It could therefore accept the candidate even though the RFC-derived format said it was invalid. In the language of conformance testing, the expected behavior and observed behavior diverged. The disagreement is the finding’s core—not a claim that every implementation path, deployment, or malformed packet has the same effect.
The sequence shows why the RFC and the implementation occupy different roles. The RFC supplies the expected condition. The test instantiates that condition as a packet. The parser produces an observation. Routing behavior is a downstream consequence that must be investigated separately; it is not automatically proven by parser acceptance.
From address computation to routing consequences
Why can one omitted validation check matter after parsing? Because the fields are not passive labels. Babel uses the address-encoding mode, prefix length, omitted-byte count, and prefix data to construct an address representation. If an invalid combination is accepted, the implementation may compute an address that does not correspond to a valid encoding under the protocol’s rules.
The paper reports that this can cause routers to forward along suboptimal or congested paths and can even enable a traffic-based denial-of-service condition. The causal chain is the important part: a field relationship affects address computation; address computation influences the routing information being built or used; routing consequences can follow without a memory-safety failure in the parser.
This should not be inflated into a claim that every accepted invalid Update necessarily produces a particular network outcome. The paper’s motivating example establishes the missing check and describes the security significance of the resulting incorrect computation. It does not provide a universal theorem about all topologies, configurations, or implementations. The practical effect depends on what the implementation does with the derived information and how that information participates in routing.
That qualification is part of good diagnosis. A parser-level finding, a wrong internal address, a changed route, and an operational outage are different observations. They may be causally connected, but they should not be collapsed into one label. The evidence is strongest at the point directly tested: the implementation accepts a combination that the RFC-derived rule forbids. The downstream risk is reported and technically plausible, but its exact manifestation is context-dependent.
The case also shows why semantic testing can reveal failures that a crash-only workflow would undercount. A process can remain alive while accepting a packet that should have been rejected. The relevant oracle is conformance to the protocol invariant, not merely process survival. Once the expected invariant is explicit, acceptance itself becomes a meaningful signal.
Why distinct Babel findings must remain distinct
The paper reports more than one Babel issue in FRRouting. Its table lists 13 Babel findings in that implementation, including the missing AE = 3, Omitted = 0 check, Router-ID checks, reserved-bit rejection, zero-interval validation, mandatory-bit handling, and sub-TLV handling. These findings share a broad theme—implementation behavior does not fully enforce protocol rules—but they are not one defect repeated thirteen times.
The distinction matters for both engineering and evidence. The AE/Omitted issue concerns address encoding and prefix construction. A Router-ID issue concerns a different relationship involving a Router-ID flag, AE, and a segment of the Prefix; the paper says that missing validation can permit a reserved all-zero or all-one identifier to be constructed. Reserved bits and sub-TLV behavior involve still other rules. A test that demonstrates one omission does not establish that the implementation handles the others correctly.
Combining them into “the parser is insecure” would erase the useful mechanism. Separate findings tell maintainers what contract to enforce, tell testers what negative case to generate, and tell readers which consequence is connected to which rule. This is exactly the discipline that semantics-aware fuzzing needs: preserve the identity of each constraint instead of treating all rejection behavior as an undifferentiated notion of malformed input.
The broader result is still significant. Across FRRouting and Holo, the paper reports 24 zero-day vulnerabilities found using SPAR-generated specifications and positive/negative packets. It says the findings were acknowledged and confirmed by the relevant development teams. But the count is an outcome of the reported evaluation, not a vulnerability rate for routing software. Nor does it mean that every semantic mismatch is exploitable. The value of the count is that it demonstrates the method’s ability to turn format relationships into implementation findings in the systems that were tested.
What the case establishes—and what it does not
The evidence supports a focused conclusion. RFC 8966 defines a cross-field condition for Babel’s Update encoding. The paper identifies a FRRouting implementation that omitted the corresponding check. A targeted packet that violates the condition can therefore expose a conformance gap even when the packet remains structurally readable. The paper connects that gap to possible incorrect address computation and routing harm, and reports that the finding was confirmed or fixed by developers.
The evidence does not support several stronger conclusions. It does not show that the public paper contains a complete executable description of every Babel state or deployment choice. It does not establish that the format model covers every behavior of every Babel implementation. It does not supply the specific crash inputs or exploit primitives for unresolved issues, and the paper says those details were withheld as part of its disclosure approach.
There are also alternative explanations that a careful testing workflow must be able to separate. If a parser rejects a supposed positive packet, the formalization may be wrong, the RFC context may be incomplete, or the implementation may enforce an additional behavior not captured by the model. If it accepts a negative packet, the parser may be missing the check, but the negative packet may also violate an unstated implementation-specific rule or rely on an incorrect interpretation of the RFC. The packet is evidence of a disagreement; it is not, by itself, a complete root-cause report.
That is why the paper’s method pairs the format with a reference parser and returns to the relevant RFC text when a mismatch appears. The opposing artifact helps localize the disagreement, while the source text provides a basis for deciding whether a constraint should be added, removed, or qualified. The Babel defect is easy to explain after the condition has been made explicit. Without that condition, the same parser behavior could look like an arbitrary acceptance decision.
The practical lesson is a disciplined one: first state the contract, then construct the smallest test that challenges it, then distinguish parser observation from system consequence. This approach does not make security claims larger than the evidence. It makes the claim more useful by tying it to a named relationship between fields.
The contract becomes the unit of comparison
The Babel example leaves us with a concrete test oracle. For the selected Update relationship, a valid packet should satisfy the condition and a targeted invalid packet should not be accepted as a valid message. The formal format describes that expectation; a reference parser provides an executable interpretation; a deployed parser provides the implementation behavior under scrutiny.
The next difficulty is architectural rather than conceptual. A real RFC contains many fields, conditional layouts, and cross-references. A real parser has many paths. If each possible path and every combination of violated constraints required a separate, unrestricted reasoning step, the method would become too expensive to use. SPAR’s next task is therefore to make this comparison loop manageable while keeping each semantic disagreement attached to the evidence that can resolve it.