You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-commits@axis.apache.org by ro...@apache.org on 2026/01/17 18:38:45 UTC

(axis-axis2-c-core) 01/04: Fix segfault in libcurl sender due to invalid free (AXIS2C-1622)

This is an automated email from the ASF dual-hosted git repository.

robertlazarski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/axis-axis2-c-core.git

commit b00294023abcb6df6a0877b11f93d7e3e44a9157
Author: Robert Lazarski <ro...@gmail.com>
AuthorDate: Sat Jan 17 07:12:27 2026 -1000

    Fix segfault in libcurl sender due to invalid free (AXIS2C-1622)
    
    The axis2_libcurl_send() function unconditionally freed content_type
    before getting the response content type. However, content_type may
    point to memory we don't own in several cases:
    
    - MTOM: axiom_output_get_content_type() returns internal pointer
    - REST with user content type: points to property value
    - Constant strings: AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML etc.
    
    Added content_type_allocated flag to track ownership and only free
    when we actually allocated the memory. This fixes the crash:
      munmap_chunk(): invalid pointer
    
    Co-Authored-By: Claude Opus 4.5 <no...@anthropic.com>
---
 src/core/transport/http/sender/libcurl/axis2_libcurl.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/src/core/transport/http/sender/libcurl/axis2_libcurl.c b/src/core/transport/http/sender/libcurl/axis2_libcurl.c
index 3a556acec..e85e988cb 100644
--- a/src/core/transport/http/sender/libcurl/axis2_libcurl.c
+++ b/src/core/transport/http/sender/libcurl/axis2_libcurl.c
@@ -118,6 +118,7 @@ axis2_libcurl_send(
     unsigned int buffer_size = 0;
     int content_length = -1;
     axis2_char_t *content_type = NULL;
+    axis2_bool_t content_type_allocated = AXIS2_FALSE; /* AXIS2C-1622: track ownership */
     /*axis2_char_t *content_len = AXIS2_HTTP_HEADER_CONTENT_LENGTH_; */
     const axis2_char_t *char_set_enc = NULL;
     axis2_char_t *content = AXIS2_HTTP_HEADER_CONTENT_TYPE_;
@@ -325,6 +326,8 @@ axis2_libcurl_send(
                 content_type =
                 (axis2_char_t *) axiom_output_get_content_type(om_output,
                     env);
+                /* AXIS2C-1622: content_type from axiom_output is NOT allocated,
+                 * only mark as allocated if we create new strings below */
                 if (AXIS2_TRUE != axis2_msg_ctx_get_is_soap_11(msg_ctx, env))
                 {
                     if (axutil_strcmp(soap_action, ""))
@@ -345,6 +348,7 @@ axis2_libcurl_send(
                             AXIS2_ESC_DOUBLE_QUOTE_STR);
                         AXIS2_FREE (env->allocator, content_type);
                         content_type = temp_content_type;
+                        content_type_allocated = AXIS2_TRUE;
                     }
                 }
             }
@@ -359,6 +363,7 @@ axis2_libcurl_send(
                 axutil_stracat(env, content_type, char_set_enc);
                 AXIS2_FREE(env->allocator, content_type);
                 content_type = temp_content_type;
+                content_type_allocated = AXIS2_TRUE;
             }
             else
             {
@@ -387,6 +392,7 @@ axis2_libcurl_send(
                     AXIS2_SEMI_COLON_STR);
                 AXIS2_FREE(env->allocator, content_type);
                 content_type = temp_content_type;
+                content_type_allocated = AXIS2_TRUE;
             }
         }
         else if (is_soap)
@@ -425,10 +431,12 @@ axis2_libcurl_send(
             if (content_type_value)
             {
                 content_type = content_type_value;
+                /* AXIS2C-1622: content_type_value is from property, NOT allocated by us */
             }
             else
             {
                 content_type = axutil_strdup(env,AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML);
+                content_type_allocated = AXIS2_TRUE;
             }
 
         }
@@ -579,7 +587,13 @@ axis2_libcurl_send(
     }
 
     axis2_msg_ctx_set_status_code (msg_ctx, env, status_code);
-    AXIS2_FREE(data->env->allocator, content_type);
+    /* AXIS2C-1622: Only free content_type if we allocated it.
+     * In some cases (MTOM, REST with user content type) it points to
+     * external memory that we must not free. */
+    if (content_type_allocated)
+    {
+        AXIS2_FREE(data->env->allocator, content_type);
+    }
     content_type = axis2_libcurl_get_content_type(data, env);
 
     if (content_type)