Fix for possible memory overflow when fetching error messages.
authorBrian Aker <brian@tangent.org>
Wed, 21 Sep 2011 22:31:17 +0000 (15:31 -0700)
committerBrian Aker <brian@tangent.org>
Wed, 21 Sep 2011 22:31:17 +0000 (15:31 -0700)
libmemcached/options.cc
tests/mem_functions.cc

index cdaa520950a28e37ab1fc3690f61b0acf7ee1303..290cfc895b434c90868563ae37476237454dca84 100644 (file)
@@ -82,17 +82,26 @@ memcached_return_t libmemcached_check_configuration(const char *option_string, s
 {
   memcached_st memc, *memc_ptr;
 
-  if (error_buffer_size)
+  if (option_string == NULL or length == 0)
+  {
+    return MEMCACHED_INVALID_ARGUMENTS;
+  }
+
+  if (error_buffer and error_buffer_size)
+  {
     error_buffer[0]= 0;
+  }
 
   if (not (memc_ptr= memcached_create(&memc)))
+  {
     return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+  }
 
   memcached_return_t rc= memcached_parse_configuration(memc_ptr, option_string, length);
   if (memcached_failed(rc) and error_buffer and error_buffer_size)
   {
     strncpy(error_buffer, memcached_last_error_message(memc_ptr), error_buffer_size);
-    error_buffer[length -1]= 0;
+    error_buffer[error_buffer_size -1]= 0;
   }
 
   bool has_filename= memcached_behavior_get(memc_ptr, MEMCACHED_BEHAVIOR_LOAD_FROM_FILE);
@@ -102,9 +111,10 @@ memcached_return_t libmemcached_check_configuration(const char *option_string, s
     assert_msg(memcached_parse_filename_length(memc_ptr), "Invalid configuration file");
     rc= _parse_file_options(*memc_ptr, memc_ptr->configure.filename);
 
-    if (memcached_failed(rc) and error_buffer && error_buffer_size)
+    if (memcached_failed(rc) and error_buffer and error_buffer_size)
     {
       strncpy(error_buffer, memcached_last_error_message(memc_ptr), error_buffer_size);
+      error_buffer[error_buffer_size -1]= 0;
     }
   }
 
index bc54b6717a5db9f532d1f04a2a5ba911cd0f0e16..1c5f7d4f6bc7038c95341f0f879d2fe368b1ab1c 100644 (file)
@@ -5651,6 +5651,27 @@ static test_return_t regression_bug_490520(memcached_st *memc)
   return TEST_SUCCESS;
 }
 
+
+static test_return_t regression_bug_854604(memcached_st *)
+{
+  char buffer[1024];
+
+  test_compare(MEMCACHED_INVALID_ARGUMENTS, libmemcached_check_configuration(0, 0, buffer, 0));
+
+  test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 0));
+  
+  test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 1));
+  test_compare(buffer[0], 0);
+  
+  test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 10));
+  test_true(strlen(buffer));
+
+  test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, sizeof(buffer)));
+  test_true(strlen(buffer));
+  
+  return TEST_SUCCESS;
+}
+
 static void memcached_die(memcached_st* mc, memcached_return error, const char* what, uint32_t it)
 {
   fprintf(stderr, "Iteration #%u: ", it);
@@ -5961,6 +5982,7 @@ test_st regression_tests[]= {
   {"lp:71231153 poll()", true, (test_callback_fn*)regression_bug_71231153_poll },
   {"lp:655423", true, (test_callback_fn*)regression_bug_655423 },
   {"lp:490520", true, (test_callback_fn*)regression_bug_490520 },
+  {"lp:854604", true, (test_callback_fn*)regression_bug_854604 },
   {0, false, (test_callback_fn*)0}
 };