isisd: consume leftover bytes after FAD sub-sub-TLV loop - #21544
Conversation
Greptile SummaryThis PR adds a post-loop
Confidence Score: 3/5Not safe to merge as-is: the fix introduces a double-advance on the existing error-break path that can desync stream parsing. The intended fix (draining 1β2 leftover bytes) is correct, but the guard condition isisd/isis_tlvs.c β specifically the post-loop skip guard and its interaction with the error-break at line 5173. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["subsubtlvs_len = length - 4"] --> B{"subsubtlvs_len > 2?"}
B -- Yes --> C["read type + len (2 bytes)"]
C --> D{"subsubtlv_len >\nsubsubtlvs_len - 2?"}
D -- Yes --> E["stream_forward_getp(s, subsubtlvs_len - 2)\nlog error"]
E --> F["break\n(subsubtlvs_len unchanged, still > 2)"]
D -- No --> G["process sub-sub-TLV\nstream_forward_getp for payload"]
G --> H["subsubtlvs_len -= 2 + subsubtlv_len"]
H --> B
B -- No --> I{"subsubtlvs_len > 0?"}
F --> I
I -- "No (== 0)" --> K["done β"]
I -- "Yes (1 or 2)\nnormal exit" --> J["stream_forward_getp(s, subsubtlvs_len) β"]
I -- "Yes (> 2)\nerror-break path - BUG" --> L["stream_forward_getp(s, subsubtlvs_len)\ndouble-advance! β"]
J --> K
L --> M["stream desync - worse than original bug"]
Prompt To Fix All With AIThis is a comment left during a code review.
Path: isisd/isis_tlvs.c
Line: 5251-5252
Comment:
**Double-advance on error-break path**
When the inner validation check at line 5168 fires (`subsubtlv_len > subsubtlvs_len - 2`), the error handler reads 2 bytes (type + length) and then calls `stream_forward_getp(s, subsubtlvs_len - 2)`, consuming all remaining bytes of this sub-TLV. It then `break`s out of the while loop with `subsubtlvs_len` still holding its pre-break value (always > 2). The new guard `subsubtlvs_len > 0` is true, so `stream_forward_getp(s, subsubtlvs_len)` is called a second time, advancing the stream far past the sub-TLV boundary and causing exactly the kind of desync the fix intends to cure.
The skip should only apply when the loop exited normally (i.e. `subsubtlvs_len` drained to β€ 2), not when it `break`ed early:
```suggestion
if (subsubtlvs_len > 0 && subsubtlvs_len <= 2)
stream_forward_getp(s, subsubtlvs_len);
```
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "isisd: consume leftover bytes after FAD ..." | Re-trigger Greptile |
| if (subsubtlvs_len > 0) | ||
| stream_forward_getp(s, subsubtlvs_len); |
There was a problem hiding this comment.
Double-advance on error-break path
When the inner validation check at line 5168 fires (subsubtlv_len > subsubtlvs_len - 2), the error handler reads 2 bytes (type + length) and then calls stream_forward_getp(s, subsubtlvs_len - 2), consuming all remaining bytes of this sub-TLV. It then breaks out of the while loop with subsubtlvs_len still holding its pre-break value (always > 2). The new guard subsubtlvs_len > 0 is true, so stream_forward_getp(s, subsubtlvs_len) is called a second time, advancing the stream far past the sub-TLV boundary and causing exactly the kind of desync the fix intends to cure.
The skip should only apply when the loop exited normally (i.e. subsubtlvs_len drained to β€ 2), not when it breaked early:
| if (subsubtlvs_len > 0) | |
| stream_forward_getp(s, subsubtlvs_len); | |
| if (subsubtlvs_len > 0 && subsubtlvs_len <= 2) | |
| stream_forward_getp(s, subsubtlvs_len); |
Prompt To Fix With AI
This is a comment left during a code review.
Path: isisd/isis_tlvs.c
Line: 5251-5252
Comment:
**Double-advance on error-break path**
When the inner validation check at line 5168 fires (`subsubtlv_len > subsubtlvs_len - 2`), the error handler reads 2 bytes (type + length) and then calls `stream_forward_getp(s, subsubtlvs_len - 2)`, consuming all remaining bytes of this sub-TLV. It then `break`s out of the while loop with `subsubtlvs_len` still holding its pre-break value (always > 2). The new guard `subsubtlvs_len > 0` is true, so `stream_forward_getp(s, subsubtlvs_len)` is called a second time, advancing the stream far past the sub-TLV boundary and causing exactly the kind of desync the fix intends to cure.
The skip should only apply when the loop exited normally (i.e. `subsubtlvs_len` drained to β€ 2), not when it `break`ed early:
```suggestion
if (subsubtlvs_len > 0 && subsubtlvs_len <= 2)
stream_forward_getp(s, subsubtlvs_len);
```
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
this comment looks valid to me
|
Valid finding. Fixed the guard to only fire on normal loop exit (1-2 leftover bytes), not on the error-break path where bytes were already consumed. |
|
same commit issue here - please squash into the first, properly-formatted commit |
When the FAD sub-sub-TLV loop exits normally with 1-2 bytes remaining (too small for another header), the stream position falls out of sync with the declared subtlv length. Add a post-loop forward to consume the leftover bytes on normal exit only, not on the error-break path where the bytes were already consumed. Signed-off-by: Tristan Madani <tristan@live.fr>
6dd381c to
fbb31ae
Compare
|
CI:rerun |
|
@Mergifyio 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 createdDetails
|
isisd: consume leftover bytes after FAD sub-sub-TLV loop (backport #21544)
isisd: consume leftover bytes after FAD sub-sub-TLV loop (backport #21544)
isisd: consume leftover bytes after FAD sub-sub-TLV loop (backport #21544)
isisd: consume leftover bytes after FAD sub-sub-TLV loop (backport #21544)
isisd: consume leftover bytes after FAD sub-sub-TLV loop (backport #21544)
isisd: consume leftover bytes after FAD sub-sub-TLV loop (backport #21544)
isisd: consume leftover bytes after FAD sub-sub-TLV loop (backport #21544)
The Flex-Algorithm sub-sub-TLV loop condition is
while (subsubtlvs_len > 2), so when 1 or 2 bytes remain after the last iteration, they are not consumed. The stream position then falls behind the declared subtlv length, desynchronizing subsequent subtlv parsing in the outer loop.Skip any leftover bytes after the while loop exits.
Signed-off-by: Tristan Madani tristan@live.fr