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.

Reply via email to