Skip to content

mime: bound Curl_mime_duppart() recursion depth - #23023

Closed
filtede98 wants to merge 2 commits into
curl:masterfrom
filtede98:fix-mime-duppart-recursion
Closed

filtede98 wants to merge 2 commits into
curl:masterfrom
filtede98:fix-mime-duppart-recursion

Conversation

@filtede98

Copy link
Copy Markdown
Contributor

Summary

When cloning an easy handle containing a multipart MIME structure via curl_easy_duphandle(), dupset() invokes Curl_mime_duppart(), which recursively traverses and duplicates subparts. Previously, this recursive duplication had no call depth bound. An application handling deeply nested MIME trees could trigger unbounded recursion, leading to stack exhaustion (CWE-674) and process termination.

This PR bounds recursion in mime_duppart() to MAX_MIME_LEVELS (40), returning CURLE_TOO_LARGE when exceeded, matching the depth limit and failure behavior introduced in commit c427e91 for mime_prepare_headers().

Changes

  • In lib/mime.c:
    • Introduce static CURLcode mime_duppart(..., size_t call_depth) with a check against MAX_MIME_LEVELS.
    • Propagate call_depth when recursively duplicating MIMEKIND_MULTIPART subparts.
    • Implement Curl_mime_duppart() as a wrapper passing initial depth 0, preserving the internal API signature.
  • In tests/libtest/lib3596.c:
    • Extend test 3596 to assert that curl_easy_duphandle() safely fails (returns NULL) on deeply nested MIME trees before and after curl_easy_perform().

Verification

  • Ran perl scripts/checksrc.pl on both modified files (lib/mime.c and tests/libtest/lib3596.c) with zero warnings.

Curl_mime_duppart() duplicates multipart structures recursively when
cloning an easy handle via curl_easy_duphandle(). Previously, this
traversal did not enforce a recursion limit, allowing an excessively
deep MIME tree to cause unbounded recursion and stack exhaustion.

Bound recursion in mime_duppart() to MAX_MIME_LEVELS, returning
CURLE_TOO_LARGE when exceeded, following the precedent set for
mime_prepare_headers() in c427e91.

Extended test 3596 to verify that curl_easy_duphandle() safely fails for
deeply nested MIME trees.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Rollback after exceeding the depth limit can invoke copied user free callbacks and leave the original MIME tree referencing freed resources.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 High severity

Open (1)
What changed in this PR

Bounds MIME duplication recursion to prevent stack exhaustion during easy-handle cloning.

Changes:

  • Enforces MAX_MIME_LEVELS during MIME duplication.
  • Tests deeply nested duplication before and after transfer.
File Description
lib/​mime.c Adds bounded recursive MIME duplication.
tests/​libtest/​lib3596.c Adds deep-nesting duplication checks.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread lib/mime.c
Preflight the source MIME tree depth before allocating or duplicating
any parts or copying user callbacks. If the tree exceeds MAX_MIME_LEVELS,
fail immediately with CURLE_TOO_LARGE.

This ensures error rollback never invokes copied user free callbacks on
sibling parts before an over-deep branch, preventing premature release
or double-free of user callback resources.

Extended test 3596 with a callback sibling part to verify that free
callbacks are preserved and not invoked during failed duphandle rollback.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟢 Approval recommended

The recursion bound is consistent with header preparation and the regression test covers safe failure without premature callbacks.

Review effort: Balanced
Findings: None

Resolved since last review (1)

@bagder bagder closed this in 4c67658 Sep 22, 2026
@bagder

bagder commented Sep 22, 2026

Copy link
Copy Markdown
Member

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

3 participants