bfdd: harden packet validation and reflector handling (backport #21105)#21255
bfdd: harden packet validation and reflector handling (backport #21105)#21255donaldsharp merged 7 commits intoFRRouting:stable/10.6from
Conversation
|
@greptile review backport |
|
@Mergifyio backport stable/10.5 stable/10.4 stable/10.3 stable/10.2 |
✅ Backports have been createdDetails
Cherry-pick of aa52430 has failed: Cherry-pick of f508822 has failed: Cherry-pick of d2645ab has failed: To fix up this pull request, you can check it out locally. See documentation: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally
Cherry-pick of aa52430 has failed: Cherry-pick of f508822 has failed: Cherry-pick of d2645ab has failed: To fix up this pull request, you can check it out locally. See documentation: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally
Cherry-pick of aa52430 has failed: Cherry-pick of f508822 has failed: Cherry-pick of d2645ab has failed: To fix up this pull request, you can check it out locally. See documentation: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally
Cherry-pick of aa52430 has failed: Cherry-pick of f508822 has failed: Cherry-pick of d2645ab has failed: To fix up this pull request, you can check it out locally. See documentation: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally |
Greptile SummaryThis PR backports security and correctness hardening for BFD packet handling from #21105 into Key changes:
Confidence Score: 4/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A([bfd_recv_cb]) --> B{mlen < 0?}
B -- yes --> Z1([return])
B -- no --> C{mlen < BFD_PKT_LEN?}
C -- yes --> Z2([return])
C -- no --> D["Parse cp = (bfd_pkt*)msgbuf"]
D --> E[ptm_bfd_sess_find]
E --> F{bfd == NULL?}
F -- yes --> Z3([return: no session])
F -- no --> G{TTL valid?}
G -- no --> Z4([return])
G -- yes --> H{Version / detect_mult / len / M-bit / my_discr valid?}
H -- no --> Z5([return])
H -- yes --> I{VRF match?}
I -- no --> Z6([return])
I -- yes --> J[bfd_check_auth]
J --> K{Auth OK?}
K -- no --> Z7([return])
K -- yes --> L[ptm_bfd_snd / state machine]
subgraph "Echo IPv6 Reflector path (bp_bfd_echo_in)"
M([bp_bfd_echo_in]) --> N{rlen < 0?}
N -- yes --> Z8([return -1])
N -- no --> O{rlen < bfd_offset+sizeof bep?}
O -- yes --> Z9([return -1])
O -- no --> P["bep = msgbuf + bfd_offset"]
P --> Q{TTL==255 && bg_echov6?}
Q -- yes --> R[bfd_key_lookup]
R --> S{Session found?}
S -- no --> Z10([return -1: drop unknown source])
S -- yes --> T{bep->len valid?}
T -- no --> Z11([return -1])
T -- yes --> U["bp_udp_send (bep->len bytes)"]
Q -- no --> V[Read my_discr / process echo]
end
Prompt To Fix All With AIThis is a comment left during a code review.
Path: bfdd/bfd_packet.c
Line: 841-853
Comment:
**Typo in comments ("finshed")**
Three of the four `switch` case comments still use the original misspelling `"To be finshed."` while the `BFD_AUTH_NULL` case was corrected to `"To be finished."` — a good opportunity to fix the remaining ones for consistency.
```suggestion
case BFD_AUTH_SIMPLE:
/* RFC5880 6.7: To be finished. */
return false;
case BFD_AUTH_CRYPTOGRAPHIC:
/* RFC5880 6.7: To be finished. */
return false;
default:
/* RFC5880 6.7: To be finished. */
return false;
```
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: bfdd/bfd_packet.c
Line: 933-941
Comment:
**Session lookup before TTL and full packet validation**
Session lookup (`ptm_bfd_sess_find`) has been moved earlier — before the TTL check and before the version/detect_mult/len/M-bit/my_discr validation. In the old code the session was only resolved after the packet passed all RFC 5880 §6.8.6 checks.
The practical consequence is that malformed or TTL-violated packets now perform a hash/key lookup instead of being dropped immediately. For most deployments this is negligible, but it also means that an on-path attacker who knows a peer address can cause a session lookup (and indirectly confirm session existence via timing) with a badly-formed packet, whereas before the packet would have been rejected at the version or TTL check first.
Notably `my_discr == 0` is still validated *after* the lookup: if the session is found (line 935) but the packet later fails the `my_discr` guard (line ~990), the packet is discarded, but the session was already touched. This is benign today because neither the session state nor statistics are updated until after all checks pass, but it is a change in the ordering contract that future contributors should be aware of.
If the primary motivation for moving the lookup earlier is to allow `rx_bad_ctrl_pkt` to be charged against the matched session, a comment explaining the rationale would help reviewers understand the intentional trade-off.
How can I resolve this? If you propose a fix, please make it concise.Last reviewed commit: "bfdd: cap IPv6 echo ..." |
|
@greptile review |
Check recv length before casting/parsing the control packet so short or error reads cannot drive discriminator/session lookup with uninitialized data. Keep debug visibility for short and non-positive reads while dropping early. Signed-off-by: Jafar Al-Gharaibeh <jafar@atcorp.com>
Restructure bfd_check_auth() so A-bit packets are length-validated before reading auth fields, and keep explicit RFC 5880 auth-type switch branches for future implementation. Signed-off-by: Jafar Al-Gharaibeh <jafar@atcorp.com>
Only reflect IPv6 echo packets when the source/local tuple maps to an existing BFD session, preventing unauthenticated reflection of arbitrary on-link packets. Signed-off-by: Jafar Al-Gharaibeh <jafar@atcorp.com>
Validate TTL, version, and declared packet length before reflecting SBFD init packets, and only reflect cp->len bytes. Add debug logs for early packet drops. Signed-off-by: Jafar Al-Gharaibeh <jafar@atcorp.com>
Use logical AND when filtering EAGAIN/EWOULDBLOCK/EINTR in bfd_recv_ipv4_fp(), bfd_recv_ipv4(), and bfd_recv_ipv6() so only real socket errors are logged. Signed-off-by: Jafar Al-Gharaibeh <jafar@atcorp.com>
Validate echo packet length using bfd_offset + sizeof(*bep) so forwarding-plane packets are not parsed past received data. Signed-off-by: Jafar Al-Gharaibeh <jafar@atcorp.com>
Validate IPv6 echo payload length and reflect only bep->len bytes instead of raw receive length to avoid oversized reflection payloads. Signed-off-by: Jafar Al-Gharaibeh <jafar@atcorp.com>
|
@greptile review |
No description provided.