Skip to content

contrib/bgp: clear the temporary NLRI bound after a failed parse - #5130

Open
KernelClint wants to merge 2 commits into
secdev:masterfrom
KernelClint:bgp-clear-nlri-bound
Open

contrib/bgp: clear the temporary NLRI bound after a failed parse#5130
KernelClint wants to merge 2 commits into
secdev:masterfrom
KernelClint:bgp-clear-nlri-bound

Conversation

@KernelClint

Copy link
Copy Markdown
Contributor

A BGP update carries a list of advertised routes. To parse it, Scapy needs to know where the list
ends, so
scapy/contrib/bgp.py:288-304
installs a temporary length_from on the field, calls the generic list parser, and clears the
callback after that call returns.

The field belongs to the class, not to the packet being parsed. If the list exceeds Scapy's
configured item limit, scapy/fields.py:1850-1855 raises MaximumItemsCount and the clearing line
never runs. The stale bound stays installed, and the next BGP update — a separate, valid one — is
cut short at it. That update parses without error and comes back with routes missing and the
remainder as trailing Raw.

The change clears the callback whether the parse succeeded or not:

         try:
             ret = super(BGPNLRIPacketListField, self).getfield(pkt, s)
-        BGPNLRIPacketListField.length_from = None
-        return ret
+        finally:
+            BGPNLRIPacketListField.length_from = None
+        return ret

The added regression parses an over-limit update, then a valid one, and asserts the valid update
keeps all of its routes. Without the source change the BGP suite reports 157 passed and 1 failed;
with it, 158 passed and 0 failed.

Performance was measured on one computer, before and after the fix: parsing a valid NLRI field took
5,772.1 ns before and 5,741.4 ns after. Repeat runs of this test moved by about 8%, which is wide
enough that only a large change would show — this is not one.

@codecov

codecov Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.64%. Comparing base (b3bbcc8) to head (283ea16).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #5130   +/-   ##
=======================================
  Coverage   80.63%   80.64%           
=======================================
  Files         390      390           
  Lines       96936    96937    +1     
=======================================
+ Hits        78168    78172    +4     
+ Misses      18768    18765    -3     
Files with missing lines Coverage Δ
scapy/contrib/bgp.py 91.77% <100.00%> (+0.01%) ⬆️

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

The test deliberately makes an over-limit update fail to dissect. With
conf.debug_dissector on, as CI runs it, that failure is re-raised and the test
never reaches its assertions.

AI-Assisted: yes (GPT-5.6-Cyber)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant