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 bi...@apache.org on 2020/09/04 02:17:08 UTC

[axis-axis2-c-core] branch master updated: Fix 1-byte buffer overwrites due to null-termination

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 7de8363  Fix 1-byte buffer overwrites due to null-termination
7de8363 is described below

commit 7de836303e80dcd2cdeb675be3bf66c2290776d2
Author: Bill Blough <bi...@apache.org>
AuthorDate: Thu Sep 3 22:14:01 2020 -0400

    Fix 1-byte buffer overwrites due to null-termination
    
    Add axutil_stream_set_buffer_end_null function to allow memory
    reallocation if needed when null-terminating a basic stream.
    
    Fixes: AXIS2C-1600
---
 axiom/src/om/om_data_source.c                      |  4 +---
 .../transport/http/common/simple_http_svr_conn.c   |  2 +-
 test/core/transport/http/test_http_transport.cc    | 21 +++++++++++++++++
 util/include/axutil_stream.h                       | 10 ++++++++
 util/src/stream.c                                  | 27 ++++++++++++++++++++++
 5 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/axiom/src/om/om_data_source.c b/axiom/src/om/om_data_source.c
index 3959e49..4f6db77 100644
--- a/axiom/src/om/om_data_source.c
+++ b/axiom/src/om/om_data_source.c
@@ -108,16 +108,14 @@ axiom_data_source_serialize(
 {
     int status = AXIS2_SUCCESS;
     axis2_char_t *data = NULL;
-    unsigned int data_len = 0;
 
     AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
     AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE);
 
+    axutil_stream_set_buffer_end_null(data_source->stream, env);
     data = axutil_stream_get_buffer(data_source->stream, env);
-    data_len = axutil_stream_get_len(data_source->stream, env);
     if(data)
     {
-        data[data_len] = '\0';
         status = axiom_output_write(om_output, env, AXIOM_DATA_SOURCE, 1, data);
     }
     return status;
diff --git a/src/core/transport/http/common/simple_http_svr_conn.c b/src/core/transport/http/common/simple_http_svr_conn.c
index 958be28..4aa71e6 100644
--- a/src/core/transport/http/common/simple_http_svr_conn.c
+++ b/src/core/transport/http/common/simple_http_svr_conn.c
@@ -282,9 +282,9 @@ axis2_simple_http_svr_conn_write_response(
     if(response_stream)
     {
         body_size = axutil_stream_get_len(response_stream, env);
+        axutil_stream_set_buffer_end_null(response_stream, env);
         response_body = axutil_stream_get_buffer(response_stream, env);
         axutil_stream_flush_buffer(response_stream, env);
-        response_body[body_size] = AXIS2_ESC_NULL;
     }
 
     if(body_size <= 0 && !binary_content)
diff --git a/test/core/transport/http/test_http_transport.cc b/test/core/transport/http/test_http_transport.cc
index 86d1b2f..17ee4a0 100644
--- a/test/core/transport/http/test_http_transport.cc
+++ b/test/core/transport/http/test_http_transport.cc
@@ -32,6 +32,7 @@
 #include <axis2_json_writer.h>
 #include <axis2_json_reader.h>
 #endif
+#include <axis2_simple_http_svr_conn.h>
 
 #include "../../../cutest/include/cut_http_server.h"
 
@@ -450,3 +451,23 @@ TEST_F(TestHTTPTransport, test_json)
 }
 #endif
 
+
+TEST_F(TestHTTPTransport, test_AXIS2C_1600)
+{
+    axis2_simple_http_svr_conn_t* conn = axis2_simple_http_svr_conn_create(
+            m_env, -1);
+
+    axis2_http_simple_response_t* resp = axis2_http_simple_response_create(
+            m_env, NULL, NULL, 0, NULL);
+    axis2_char_t body[AXIS2_STREAM_DEFAULT_BUF_SIZE+1];
+    memset(body, 'A', AXIS2_STREAM_DEFAULT_BUF_SIZE+1);
+    body[AXIS2_STREAM_DEFAULT_BUF_SIZE] = '\0';
+
+    axis2_http_simple_response_set_status_line(resp, m_env, "1.1", 200, "OK");
+    axis2_http_simple_response_set_body_string(resp, m_env, body);
+
+    axis2_simple_http_svr_conn_write_response(conn, m_env, resp);
+
+    axis2_http_simple_response_free(resp, m_env);
+    axis2_simple_http_svr_conn_free(conn, m_env);
+}
diff --git a/util/include/axutil_stream.h b/util/include/axutil_stream.h
index a506811..92c9c17 100644
--- a/util/include/axutil_stream.h
+++ b/util/include/axutil_stream.h
@@ -283,6 +283,16 @@ extern "C"
         const axutil_stream_t * stream,
         const axutil_env_t * env);
 
+    /**
+     * Appends a null terminator to the buffer, allocating additional memory
+     * if necessary.
+     * @return Length of the buffer plus null terminator, or -1 on error
+     */
+    AXIS2_EXTERN int AXIS2_CALL
+        axutil_stream_set_buffer_end_null(
+                axutil_stream_t *stream,
+                axutil_env_t *env);
+
     AXIS2_EXTERN axis2_status_t AXIS2_CALL
     axutil_stream_flush_buffer(
         axutil_stream_t * stream,
diff --git a/util/src/stream.c b/util/src/stream.c
index bdc4e03..8f3d986 100644
--- a/util/src/stream.c
+++ b/util/src/stream.c
@@ -377,6 +377,33 @@ axutil_stream_get_buffer(
     return stream->buffer;
 }
 
+AXIS2_EXTERN int AXIS2_CALL
+axutil_stream_set_buffer_end_null(
+    axutil_stream_t *stream,
+    axutil_env_t *env)
+{
+    if (!stream || !env) return -1;
+
+    if (stream->len + 1 >= stream->max_len) {
+
+        axis2_char_t *tmp = (axis2_char_t *)AXIS2_MALLOC(env->allocator,
+                sizeof(axis2_char_t) * (stream->len + 1));
+        if(!tmp)
+        {
+            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+            return -1;
+        }
+        stream->max_len = stream->len + 1;
+        memcpy(tmp, stream->buffer_head, sizeof(axis2_char_t) * stream->len);
+        AXIS2_FREE(env->allocator, stream->buffer_head);
+        stream->buffer = tmp;
+        stream->buffer_head = tmp;
+    }
+    *(stream->buffer_head + stream->len) = '\0';
+    return stream->len + 1;
+
+}
+
 AXIS2_EXTERN axis2_status_t AXIS2_CALL
 axutil_stream_flush_buffer(
     axutil_stream_t *stream,