Hello BIRD maintainers, I would like to report a possible issue in BIRD. ### Summary BIRD appears to accept a BGP UPDATE containing `AS4_AGGREGATOR` with AS number 0 from a non-AS4 peer. When the same UPDATE also contains `AGGREGATOR` with `AS_TRANS`, BIRD's AS4 transition processing converts the `AS4_AGGREGATOR` value into the effective `AGGREGATOR` attribute. In dynamic testing, BIRD installed the route with: ```text BGP.aggregator: 192.0.2.9 AS0 ``` and then exported the route to a downstream non-AS4 peer with: ```text AGGREGATOR flags=0xc0 as=0 addr=192.0.2.9 ``` I am reporting this as an RFC 7607 conformance / input-validation issue, not as a high-impact security vulnerability. ### Expected Behavior RFC 7607 Section 2 says that a BGP speaker MUST NOT originate or propagate a route with AS number zero in the `AS_PATH`, `AS4_PATH`, `AGGREGATOR`, or `AS4_AGGREGATOR` attributes. An UPDATE containing AS 0 in `AS4_AGGREGATOR` should cause the `AS4_AGGREGATOR` attribute to be considered malformed under RFC 7607 and handled according to RFC 6793. In other words, the attribute should be discarded and the UPDATE may continue to be processed. However, the `AS4_AGGREGATOR` value must not become the effective `AGGREGATOR` attribute, and BIRD must not install or export the route with `AGGREGATOR AS=0`. ### Actual Behavior BIRD continues processing the UPDATE, but the malformed `AS4_AGGREGATOR` value becomes the effective `AGGREGATOR` attribute. The route is installed with `BGP.aggregator: 192.0.2.9 AS0`, and BIRD exports an `AGGREGATOR` attribute whose AS field is 0. ### Steps to Reproduce 1. Start BIRD with a dynamic BGP listener: ```bird router id 127.0.0.1; protocol device { } protocol bgp as4agg_as0 { local 127.0.0.1 port 11918 as 65001; neighbor range 127.0.0.0/8 external; dynamic name "poc"; multihop; ipv4 { import all; export all; }; } ``` 2. Connect an upstream peer from `127.0.0.2`, AS 65002, without advertising AS4 capability. 3. Send an UPDATE for `203.0.113.0/24` containing: ```text ORIGIN = IGP AS_PATH = 65002 NEXT_HOP = 127.0.0.2 AGGREGATOR = AS_TRANS / 192.0.2.9 AS4_AGGREGATOR = AS 0 / 192.0.2.9 ``` 4. Query the local RIB: ```text birdc show route 203.0.113.0/24 all ``` 5. Connect a downstream peer from `127.0.0.3`, AS 65003, also without AS4 capability, and inspect the UPDATE exported by BIRD. ### Dynamic Verification This was reproduced against: ```text BIRD version 2.19.0+branch.master.880200b1f94c ``` Local RIB: ```text 203.0.113.0/24 unreachable [poc1 ... from 127.0.0.2] * (100) [AS65002i] Type: BGP univ BGP.origin: IGP BGP.as_path: 65002 BGP.next_hop: 127.0.0.2 BGP.local_pref: 100 BGP.aggregator: 192.0.2.9 AS0 ``` Downstream export: ```text [+] Exported AGGREGATOR flags=0xc0 as=0 addr=192.0.2.9 VERDICT: NON_COMPLIANT_REPRODUCED_ACCEPTED_AND_PROPAGATED ``` ### Source Analysis `AS4_AGGREGATOR` decoding checks whether the session is already AS4-capable and whether the attribute length is 8, but it does not check whether the AS field is 0: ```c static void bgp_decode_as4_aggregator(...) { if (s->as4_session) DISCARD(NEW_BGP, "AS4_AGGREGATOR"); if (len != 8) DISCARD(BAD_LENGTH, "AS4_AGGREGATOR", len); bgp_set_attr_data(to, s->pool, BA_AS4_AGGREGATOR, flags, data, len); } ``` During AS4 transition processing, if both `AGGREGATOR` and `AS4_AGGREGATOR` are present and `AGGREGATOR` has `AS_TRANS`, BIRD uses `AS4_AGGREGATOR` as the effective `AGGREGATOR`: ```c if (a2 && a4) { u32 a2_asn = get_u32(a2->u.ptr->data); if (a2_asn != AS_TRANS) return; /* Use AS4_AGGREGATOR instead of AGGREGATOR */ a2->u.ptr = a4->u.ptr; } ``` There appears to be no AS 0 validation on either `AGGREGATOR` or `AS4_AGGREGATOR`. ### Comparison FRR checks AS 0 for both `AGGREGATOR` and `AS4_AGGREGATOR`. If the AS is 0, FRR logs the condition and does not mark the attribute as present for propagation. ### Impact The practical impact is interoperability and malformed route propagation. BIRD may propagate a route with invalid AS 0 aggregator metadata, which can cause downstream implementations with stricter RFC 7607 handling to reject, withdraw, or otherwise handle the route inconsistently. This does not directly imply route hijacking. `AGGREGATOR` is not the primary AS loop detection input; `AS_PATH` and `AS4_PATH` are. ### Suggested Fix Direction Add AS 0 validation for `AGGREGATOR` and `AS4_AGGREGATOR` during decode or before AS4 transition reconstruction. In particular, an `AS4_AGGREGATOR` whose first four bytes decode to ASN 0 should not be allowed to become the effective `AGGREGATOR` attribute or be propagated downstream.