Skip to content

bgpd: fix off-by-one error in FlowSpec operator array bounds check - #21054

Merged
ton31337 merged 1 commit into
FRRouting:masterfrom
Jafaral:flowspec-fix
Mar 10, 2026
Merged

bgpd: fix off-by-one error in FlowSpec operator array bounds check#21054
ton31337 merged 1 commit into
FRRouting:masterfrom
Jafaral:flowspec-fix

Conversation

@Jafaral

@Jafaral Jafaral commented Mar 9, 2026

Copy link
Copy Markdown
Member

Change loop > BGP_PBR_MATCH_VAL_MAX to loop >= BGP_PBR_MATCH_VAL_MAX in bgp_flowspec_op_decode() and bgp_flowspec_bitmask_decode() to prevent writing one element past the end of the mval[] array when more than 5 chained operators are present in a FlowSpec component.

@greptile-apps

greptile-apps Bot commented Mar 9, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes an off-by-one buffer overflow in bgp_flowspec_op_decode() and bgp_flowspec_bitmask_decode() in bgpd/bgp_flowspec_util.c. The mval[] arrays have exactly BGP_PBR_MATCH_VAL_MAX (5) elements (valid indices 0–4), but the old loop > BGP_PBR_MATCH_VAL_MAX guard only triggered at loop == 6, allowing a write to mval[5] β€” one element past the end β€” when a FlowSpec component carried 6 or more chained operators. The fix tightens the check to loop >= BGP_PBR_MATCH_VAL_MAX, which correctly blocks at loop == 5.

Key changes:

  • bgp_flowspec_op_decode(): condition changed from loop > BGP_PBR_MATCH_VAL_MAX to loop >= BGP_PBR_MATCH_VAL_MAX, and a missing return offset; is added β€” previously the function set *error = -2 but did not return, letting the loop body execute again (the write was only incidentally prevented by a secondary if (*error == -2) break; guard inside BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE).
  • bgp_flowspec_bitmask_decode(): same condition tightened; a return offset; was already present here, so this is a pure fencepost fix.

Both changes are minimal, correct, and consistent with how the arrays are declared (struct bgp_pbr_match_val field[BGP_PBR_MATCH_VAL_MAX] throughout bgp_pbr.h).

Confidence Score: 5/5

  • This PR is safe to merge β€” it is a focused, well-scoped security/correctness fix with no regressions introduced.
  • The change is minimal (two condition tweaks and one missing return statement), directly addresses a real heap/stack buffer-overflow reachable from malformed BGP FlowSpec NLRI data, and matches the declared array sizes (BGP_PBR_MATCH_VAL_MAX == 5). No new logic paths are introduced and the error contract (*error = -2, early return) was already established in bgp_flowspec_bitmask_decode.
  • No files require special attention beyond the reviewed fix.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["Enter decode loop β€” loop = 0"] --> B{"loop >= BGP_PBR_MATCH_VAL_MAX ?"}
    B -- Yes --> C["*error = -2\nreturn offset β€” array full"]
    B -- No --> D{"offset >= max_len ?"}
    D -- Yes --> E["*error = -1\nbreak β€” truncated input"]
    D -- No --> F["Parse operator byte\ncompute value_size"]
    F --> G{"BGP_FLOWSPEC_CONVERT\n_TO_NON_OPAQUE ?"}
    G -- Yes --> H["Write to mval, mval++"]
    G -- No --> I["String / validate path"]
    H --> J["offset += value_size\nloop++"]
    I --> J
    J --> K{"op[0] == 0 AND\noffset < max_len-1 ?"}
    K -- "Yes, more operators" --> B
    K -- "No, end-of-list" --> L["*error = loop\nreturn offset"]
Loading

Last reviewed commit: 0e6882b

Change loop > BGP_PBR_MATCH_VAL_MAX to loop >= BGP_PBR_MATCH_VAL_MAX
in bgp_flowspec_op_decode() and bgp_flowspec_bitmask_decode() to
prevent writing one element past the end of the mval[] array when
more than 5 chained operators are present in a FlowSpec component.

Reported-by: Jiahao Lei
Signed-off-by: Jafar Al-Gharaibeh <jafar@atcorp.com>
@Jafaral

Jafaral commented Mar 9, 2026

Copy link
Copy Markdown
Member Author

@greptile review

@Jafaral

Jafaral commented Mar 10, 2026

Copy link
Copy Markdown
Member Author

@Mergifyio backport stable/10.6 stable/10.5 stable/10.4 stable/10.3 stable/10.2 stable/10.1 stable/10.0

@mergify

mergify Bot commented Mar 10, 2026

Copy link
Copy Markdown

backport stable/10.6 stable/10.5 stable/10.4 stable/10.3 stable/10.2 stable/10.1 stable/10.0

βœ… Backports have been created

Details

@ton31337 ton31337 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ton31337
ton31337 merged commit 3063564 into FRRouting:master Mar 10, 2026
20 checks passed
donaldsharp added a commit that referenced this pull request Mar 10, 2026
bgpd: fix off-by-one error in FlowSpec operator array bounds check (backport #21054)
donaldsharp added a commit that referenced this pull request Mar 10, 2026
bgpd: fix off-by-one error in FlowSpec operator array bounds check (backport #21054)
donaldsharp added a commit that referenced this pull request Mar 10, 2026
bgpd: fix off-by-one error in FlowSpec operator array bounds check (backport #21054)
donaldsharp added a commit that referenced this pull request Mar 10, 2026
bgpd: fix off-by-one error in FlowSpec operator array bounds check (backport #21054)
donaldsharp added a commit that referenced this pull request Mar 10, 2026
bgpd: fix off-by-one error in FlowSpec operator array bounds check (backport #21054)
donaldsharp added a commit that referenced this pull request Mar 10, 2026
bgpd: fix off-by-one error in FlowSpec operator array bounds check (backport #21054)
donaldsharp added a commit that referenced this pull request Mar 10, 2026
bgpd: fix off-by-one error in FlowSpec operator array bounds check (backport #21054)
@mattiaswal mattiaswal mentioned this pull request Mar 18, 2026
17 tasks
bmwiedemann pushed a commit to bmwiedemann/openSUSE that referenced this pull request May 8, 2026
https://build.opensuse.org/request/show/1351832
by user mtomaschewski + dimstar_suse
- Update to frr-10.6.1 (https://frrouting.org/release/10.6.1/)
  providing several bug fixes. Already the previous update to
  frr-10.6.0 includes security fixes for the following Denial
  of Service (DoS) vulnerabilities:
  - ospfd: harden TE/SR TLV iteration against malformed lengths
    (bsc#1263859,CVE-2026-28532,gh#FRRouting/frr#21002)
  - bgpd: fix off-by-one error in FlowSpec operator array bounds check
    (bsc#1263863,CVE-2026-37457,gh#FRRouting/frr#21054)
  - bgpd: Validate MP_REACH_NLRI attribute against incorrect next-hop
    (bsc#1263974,CVE-2026-37458,gh#FRRouting/frr#21075)
  - bgpd: Check if the NHC length is enough to fill TLV value + TLV header
    (bsc#1264051,CVE-2026-37459,gh#FRRouting/frr#21074)
@Jafaral
Jafaral deleted the flowspec-fix branch May 29, 2026 17:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants