new file mode 100644
@@ -0,0 +1,203 @@
+From d7546809d5bd548b69ec49fca26565c8f6f0d344 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <daniel@haxx.se>
+Date: Sun, 13 Sep 2026 00:06:44 +0200
+Subject: [PATCH] mime: do curl_mime_free() non-recursively
+
+Verify with test 3595: deeply nested curl_mime_free()
+
+Closes #22927
+
+CVE: CVE-2026-92391
+Upstream-Status: Backport [https://github.com/curl/curl/commit/d7546809d5bd548b69ec49fca26565c8f6f0d344]
+
+Backport Changes:
+- Register test3595 and lib3595.c in the older grouped TESTCASES and
+ TESTS_C lists instead of upstream's one-entry-per-line layout.
+
+Signed-off-by: Darsh Kelaiya <dkelaiya@cisco.com>
+---
+ lib/mime.c | 28 +++++++++++----
+ tests/data/Makefile.am | 2 +-
+ tests/data/test3595 | 21 ++++++++++++
+ tests/libtest/Makefile.inc | 3 +-
+ tests/libtest/lib3595.c | 70 ++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 116 insertions(+), 8 deletions(-)
+ create mode 100644 tests/data/test3595
+ create mode 100644 tests/libtest/lib3595.c
+
+diff --git a/lib/mime.c b/lib/mime.c
+index 37ea514..3da989b 100644
+--- a/lib/mime.c
++++ b/lib/mime.c
+@@ -1078,20 +1078,36 @@ void Curl_mime_cleanpart(curl_mimepart *part)
+ }
+ }
+
+-/* Recursively delete a mime handle and its parts. */
++/* Non-recursively delete a mime handle and its parts. */
+ void curl_mime_free(curl_mime *mime)
+ {
+ curl_mimepart *part;
+
+- if(mime) {
+- mime_subparts_unbind(mime); /* Be sure it is not referenced anymore. */
+- while(mime->firstpart) {
+- part = mime->firstpart;
++ if(!mime)
++ return;
++
++ mime_subparts_unbind(mime); /* Be sure it is not referenced anymore. */
++
++ while(mime) {
++ part = mime->firstpart;
++ if(part) {
+ mime->firstpart = part->nextpart;
++ if(part->kind == MIMEKIND_MULTIPART && part->arg &&
++ part->freefunc == mime_subparts_free) {
++ curl_mime *subparts = (curl_mime *)part->arg;
++ part->freefunc = NULL;
++ cleanup_part_content(part);
++ subparts->parent = mime->parent;
++ mime->parent = (curl_mimepart *)subparts;
++ }
+ Curl_mime_cleanpart(part);
+ curlx_free(part);
+ }
+- curlx_free(mime);
++ else {
++ curl_mime *parent = (curl_mime *)mime->parent;
++ curlx_free(mime);
++ mime = parent;
++ }
+ }
+ }
+
+diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
+index 7a9b8d0..933c3c7 100644
+--- a/tests/data/Makefile.am
++++ b/tests/data/Makefile.am
+@@ -287,7 +287,7 @@ test3209 test3210 test3211 test3212 test3213 test3214 test3215 test3216 \
+ \
+ test3303 test3304 \
+ \
+-test3500 \
++test3500 test3595 \
+ \
+ test4000 test4001
+
+diff --git a/tests/data/test3595 b/tests/data/test3595
+new file mode 100644
+index 0000000..b2b1dd2
+--- /dev/null
++++ b/tests/data/test3595
+@@ -0,0 +1,21 @@
++<?xml version="1.0" encoding="US-ASCII"?>
++<testcase>
++<info>
++<keywords>
++mime
++</keywords>
++</info>
++
++# Client-side
++<client>
++<tool>
++lib%TESTNUMBER
++</tool>
++<name>
++curl_mime_free
++</name>
++</client>
++
++<verify>
++</verify>
++</testcase>
+diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc
+index d7af26f..e494189 100644
+--- a/tests/libtest/Makefile.inc
++++ b/tests/libtest/Makefile.inc
+@@ -118,4 +118,5 @@ TESTS_C = \
+ lib2700.c \
+ lib3010.c lib3025.c lib3026.c lib3027.c lib3033.c lib3034.c \
+ lib3100.c lib3101.c lib3102.c lib3103.c lib3104.c lib3105.c \
+- lib3207.c lib3208.c
++ lib3207.c lib3208.c \
++ lib3595.c
+diff --git a/tests/libtest/lib3595.c b/tests/libtest/lib3595.c
+new file mode 100644
+index 0000000..1f343f5
+--- /dev/null
++++ b/tests/libtest/lib3595.c
+@@ -0,0 +1,70 @@
++/***************************************************************************
++ * _ _ ____ _
++ * Project ___| | | | _ \| |
++ * / __| | | | |_) | |
++ * | (__| |_| | _ <| |___
++ * \___|\___/|_| \_\_____|
++ *
++ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
++ *
++ * This software is licensed as described in the file COPYING, which
++ * you should have received as part of this distribution. The terms
++ * are also available at https://curl.se/docs/copyright.html.
++ *
++ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
++ * copies of the Software, and permit persons to whom the Software is
++ * furnished to do so, under the terms of the COPYING file.
++ *
++ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
++ * KIND, either express or implied.
++ *
++ * SPDX-License-Identifier: curl
++ *
++ ***************************************************************************/
++#include "unitcheck.h"
++
++static CURLcode test_lib3595(const char *arg)
++{
++ UNITTEST_BEGIN_SIMPLE
++
++#if !defined(CURL_DISABLE_MIME) && \
++ (!defined(CURL_DISABLE_HTTP) || \
++ !defined(CURL_DISABLE_SMTP) || \
++ !defined(CURL_DISABLE_IMAP))
++
++ curl_mime *root = NULL;
++ curl_mime *current = NULL;
++ curl_mime *sub = NULL;
++ curl_mimepart *part = NULL;
++ int i;
++
++ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
++ curl_mfprintf(stderr, "curl_global_init() failed\n");
++ return TEST_ERR_MAJOR_BAD;
++ }
++
++ /* Create a deeply nested mime structure to verify that non-recursive
++ curl_mime_free works properly. */
++ (void)arg;
++ root = curl_mime_init(NULL);
++ fail_unless(root != NULL, "curl_mime_init root failed");
++ current = root;
++
++ for(i = 0; i < 50; i++) {
++ part = curl_mime_addpart(current);
++ fail_unless(part != NULL, "curl_mime_addpart failed");
++ sub = curl_mime_init(NULL);
++ fail_unless(sub != NULL, "curl_mime_init sub failed");
++ curl_mime_subparts(part, sub);
++ current = sub;
++ }
++
++ /* Free deep structure */
++ curl_mime_free(root);
++ curl_global_cleanup();
++#else
++ (void)arg;
++#endif
++
++ UNITTEST_END_SIMPLE
++}
+--
+2.35.6
@@ -60,6 +60,7 @@ SRC_URI = "https://curl.se/download/${BP}.tar.xz \
file://CVE-2026-92389.patch \
file://CVE-2026-87865_p1.patch \
file://CVE-2026-87865_p2.patch \
+ file://CVE-2026-92391.patch \
"
SRC_URI:append:class-nativesdk = " \