pathd: prevent stack buffer overflow in path_zebra_add_sr_policy()#22441
pathd: prevent stack buffer overflow in path_zebra_add_sr_policy()#22441guoguojia2021 wants to merge 1 commit into
Conversation
path_zebra_add_sr_policy() iterates over all segment entries in a segment list and writes each SID label into zp.segment_list.labels[], which is a fixed-size array of MPLS_MAX_LABELS (16) elements on the stack. There is no bounds check on label_num before the write. A segment list with more than 16 entries — which is legal per RFC 9256 — will write past the array boundary, corrupting adjacent stack memory. This includes the policy name buffer, local_label, and potentially the return address, leading to undefined behavior or exploitable code execution. The vulnerability is remotely triggerable: segment lists can be originated via PCEP (RFC 8231/8281) from an external PCE, or via BGP SR-TE policy SAFI (SAFI 73), neither of which require authentication beyond the peer/PCE session itself. Add a bounds check against MPLS_MAX_LABELS before each write. When the limit is exceeded, log a warning identifying the offending policy and truncate the segment list to the first 16 labels, preventing the overflow while still installing a functional (truncated) policy. Signed-off-by: guozhongfeng.gzf <guozhongfeng.gzf@alibaba-inc.com>
Greptile SummaryThis PR fixes a stack buffer overflow in
Confidence Score: 3/5The crash-causing overflow is prevented, but the truncation path still sends a partial label stack to Zebra, which can install forwarding state that misroutes or black-holes SR-TE traffic. The bounds check is arithmetically correct and stops the overflow, which is the main goal. The residual concern is that after truncation the code continues to call zebra_send_sr_policy with an incomplete segment list, potentially pushing broken forwarding state to the data plane for any policy whose configured segment list exceeds 16 entries. pathd/path_zebra.c — specifically the post-truncation flow that still invokes zebra_send_sr_policy. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[path_zebra_add_sr_policy called] --> B[Initialize zapi_sr_policy zp]
B --> C{RB_FOREACH segment}
C -->|next segment| D{label_num >= MPLS_MAX_LABELS?}
D -->|Yes| E[zlog_warn: truncating]
E --> F[break]
D -->|No| G[Write label to array and increment label_num]
G --> C
C -->|done| H[policy status = GOING_UP]
F --> H
H --> I[zebra_send_sr_policy SET]
I --> J{Was list truncated?}
J -->|No - full list sent| K[Zebra installs correct policy]
J -->|Yes - partial list sent| L[Zebra installs incomplete policy - potential misrouting]
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[path_zebra_add_sr_policy called] --> B[Initialize zapi_sr_policy zp]
B --> C{RB_FOREACH segment}
C -->|next segment| D{label_num >= MPLS_MAX_LABELS?}
D -->|Yes| E[zlog_warn: truncating]
E --> F[break]
D -->|No| G[Write label to array and increment label_num]
G --> C
C -->|done| H[policy status = GOING_UP]
F --> H
H --> I[zebra_send_sr_policy SET]
I --> J{Was list truncated?}
J -->|No - full list sent| K[Zebra installs correct policy]
J -->|Yes - partial list sent| L[Zebra installs incomplete policy - potential misrouting]
Prompt To Fix All With AIFix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
pathd/path_zebra.c:188-198
**Truncated policy sent to Zebra with incomplete segment list**
When the segment list exceeds `MPLS_MAX_LABELS`, this code truncates the label stack and still calls `zebra_send_sr_policy()` with only the first 16 labels. Sending an incomplete segment list to the forwarding plane installs an SR-TE policy with a shorter stack than what was signaled, which will misroute or black-hole traffic at the first transit node that expects the full label stack. The original policy intent is not achievable with a partial label stack, so it may be safer to abort the install entirely (log the warning, skip the `zebra_send_sr_policy` call, and return) rather than silently forwarding with a truncated path.
Reviews (1): Last reviewed commit: "pathd: prevent stack buffer overflow in ..." | Re-trigger Greptile |
| if (zp.segment_list.label_num >= MPLS_MAX_LABELS) { | ||
| zlog_warn("SR-TE policy %s: segment list exceeds MPLS_MAX_LABELS (%d), truncating", | ||
| policy->name, MPLS_MAX_LABELS); | ||
| break; | ||
| } | ||
| zp.segment_list.labels[zp.segment_list.label_num++] = | ||
| segment->sid_value; | ||
| } | ||
| policy->status = SRTE_POLICY_STATUS_GOING_UP; | ||
|
|
||
| (void)zebra_send_sr_policy(pathd_zclient, ZEBRA_SR_POLICY_SET, &zp); |
There was a problem hiding this comment.
Truncated policy sent to Zebra with incomplete segment list
When the segment list exceeds MPLS_MAX_LABELS, this code truncates the label stack and still calls zebra_send_sr_policy() with only the first 16 labels. Sending an incomplete segment list to the forwarding plane installs an SR-TE policy with a shorter stack than what was signaled, which will misroute or black-hole traffic at the first transit node that expects the full label stack. The original policy intent is not achievable with a partial label stack, so it may be safer to abort the install entirely (log the warning, skip the zebra_send_sr_policy call, and return) rather than silently forwarding with a truncated path.
Prompt To Fix With AI
This is a comment left during a code review.
Path: pathd/path_zebra.c
Line: 188-198
Comment:
**Truncated policy sent to Zebra with incomplete segment list**
When the segment list exceeds `MPLS_MAX_LABELS`, this code truncates the label stack and still calls `zebra_send_sr_policy()` with only the first 16 labels. Sending an incomplete segment list to the forwarding plane installs an SR-TE policy with a shorter stack than what was signaled, which will misroute or black-hole traffic at the first transit node that expects the full label stack. The original policy intent is not achievable with a partial label stack, so it may be safer to abort the install entirely (log the warning, skip the `zebra_send_sr_policy` call, and return) rather than silently forwarding with a truncated path.
How can I resolve this? If you propose a fix, please make it concise.
riw777
left a comment
There was a problem hiding this comment.
the one ai comment looks valid ?
path_zebra_add_sr_policy() iterates over all segment entries in a segment list and writes each SID label into zp.segment_list.labels[], which is a fixed-size array of MPLS_MAX_LABELS (16) elements on the stack. There is no bounds check on label_num before the write.