From 34b6c26def5d780e956c2fc40b53adca2793ceb7 Mon Sep 17 00:00:00 2001 From: Clinton Thomas <1033162+KernelClint@users.noreply.github.com> Date: Tue, 1 Sep 2026 13:29:01 -0400 Subject: [PATCH 1/2] contrib/bgp: clear the temporary NLRI bound after a failed parse AI-Assisted: yes (GPT-5.6-Cyber) --- scapy/contrib/bgp.py | 8 +++++--- test/contrib/bgp.uts | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/scapy/contrib/bgp.py b/scapy/contrib/bgp.py index 2f5965a4e0a..1182f9f9e26 100644 --- a/scapy/contrib/bgp.py +++ b/scapy/contrib/bgp.py @@ -298,9 +298,11 @@ def getfield(self, pkt, s): detect_add_path_prefix46(remain, self.max_bit_length) ] self.next_cls_cb = lambda *args: cls - res = super(BGPNLRIPacketListField, self).getfield(pkt, s) - if self.no_length: - self.length_from = None + try: + res = super(BGPNLRIPacketListField, self).getfield(pkt, s) + finally: + if self.no_length: + self.length_from = None return res diff --git a/test/contrib/bgp.uts b/test/contrib/bgp.uts index 3d8e30f2431..4c20640d042 100644 --- a/test/contrib/bgp.uts +++ b/test/contrib/bgp.uts @@ -711,6 +711,25 @@ assert m.getlayer(BGPUpdate, 2).nlri[0].sprintf("%prefix%") == "10.233.0.22/32" p = BGP(raw(BGPHeader()/BGPUpdate())) assert BGPHeader in p and BGPUpdate in p += BGPUpdate - NLRI bounds do not survive a failed parse +def make_update(nlri): + marker = b"\xff" * 16 + return marker + struct.pack("!HBHH", 23 + len(nlri), 2, 0, 0) + nlri + +field = next(field for field in BGPUpdate.fields_desc if field.name == "nlri") +old_max_count = field.max_count +field.max_count = 1 +try: + keepalive = b"\xff" * 16 + struct.pack("!HB", 19, 4) + BGP(make_update(b"\x01\x00" * 2) + keepalive) + assert field.length_from is None + victim = BGP(make_update(b"\x20\x00\x00\x00\x00")) + assert len(victim[BGPUpdate].nlri) == 1 + assert Raw not in victim[BGPUpdate] +finally: + field.max_count = old_max_count + field.length_from = None + ########## BGPNotification Class ################################### + BGPNotification class tests From 283ea16154bc8c6adac2f4c5e947e73cfa6847dc Mon Sep 17 00:00:00 2001 From: Clinton Thomas <1033162+KernelClint@users.noreply.github.com> Date: Tue, 1 Sep 2026 14:07:55 -0400 Subject: [PATCH 2/2] contrib/bgp: keep the new test working under the debug dissector 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) --- test/contrib/bgp.uts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/contrib/bgp.uts b/test/contrib/bgp.uts index 4c20640d042..60159ccaf78 100644 --- a/test/contrib/bgp.uts +++ b/test/contrib/bgp.uts @@ -721,7 +721,10 @@ old_max_count = field.max_count field.max_count = 1 try: keepalive = b"\xff" * 16 + struct.pack("!HB", 19, 4) - BGP(make_update(b"\x01\x00" * 2) + keepalive) + # This update is meant to exceed the item limit and fail to dissect, so the + # debug dissector must not turn that into a raised exception here. + with no_debug_dissector(): + BGP(make_update(b"\x01\x00" * 2) + keepalive) assert field.length_from is None victim = BGP(make_update(b"\x20\x00\x00\x00\x00")) assert len(victim[BGPUpdate].nlri) == 1