Fix for bug 633247
authorBrian Aker <brian@tangent.org>
Thu, 10 Feb 2011 18:43:18 +0000 (10:43 -0800)
committerBrian Aker <brian@tangent.org>
Thu, 10 Feb 2011 18:43:18 +0000 (10:43 -0800)
ChangeLog
libmemcached/auto.c
libmemcached/connect.c
libmemcached/delete.c
libmemcached/dump.c
libmemcached/flush.c
libmemcached/hosts.c
libmemcached/stats.c
libmemcached/storage.c
libmemcached/verbosity.c

index f2e3f580fcf760ca717e51992304612633bd6264..ca2fe28149188ecd350c8e41a1550c3647aa5421 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+  * Bug lp:633247
+
+
 0.45 Tue Feb  8 16:02:06 PST 2011
   * Add support for systemtap
 
index ce2d02611db1a796c0b3346bbf064b2e2b144bbd..a221144f06a75851e39d2779a1c4cad1ddf09d4e 100644 (file)
@@ -18,7 +18,6 @@ static memcached_return_t text_incr_decr(memcached_st *ptr,
                                          uint64_t offset,
                                          uint64_t *value)
 {
-  size_t send_length;
   memcached_return_t rc;
   char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
   uint32_t server_key;
@@ -34,16 +33,17 @@ static memcached_return_t text_incr_decr(memcached_st *ptr,
   server_key= memcached_generate_hash_with_redistribution(ptr, master_key, master_key_length);
   instance= memcached_server_instance_fetch(ptr, server_key);
 
-  send_length= (size_t)snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
-                                "%s %.*s%.*s %" PRIu64 "%s\r\n", verb,
-                                (int)ptr->prefix_key_length,
-                                ptr->prefix_key,
-                                (int)key_length, key,
-                                offset, no_reply ? " noreply" : "");
-  unlikely (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE)
+  int send_length;
+  send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
+                        "%s %.*s%.*s %" PRIu64 "%s\r\n", verb,
+                        (int)ptr->prefix_key_length,
+                        ptr->prefix_key,
+                        (int)key_length, key,
+                        offset, no_reply ? " noreply" : "");
+  if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || send_length < 0)
     return MEMCACHED_WRITE_FAILURE;
 
-  rc= memcached_do(instance, buffer, send_length, true);
+  rc= memcached_do(instance, buffer, (size_t)send_length, true);
   if (no_reply || rc != MEMCACHED_SUCCESS)
     return rc;
 
index c4b263e1fe2fadcd8f917aa223b81e17146cf418..75d174b459e3418839a251a9dd2fa14483088d19 100644 (file)
@@ -95,7 +95,9 @@ static memcached_return_t set_hostinfo(memcached_server_st *server)
   char str_port[NI_MAXSERV];
   uint32_t counter= 5;
 
-  snprintf(str_port, NI_MAXSERV, "%u", (uint32_t)server->port);
+  int length= snprintf(str_port, NI_MAXSERV, "%u", (uint32_t)server->port);
+  if (length >= NI_MAXSERV || length < 0)
+    return MEMCACHED_FAILURE;
 
   memset(&hints, 0, sizeof(hints));
 
index 84a34271b0c01cb779a6c4f1c8c03c20e99c2ad0..ef1fa6da328e499e94d931e608f88db2ac6e5c81 100644 (file)
@@ -20,7 +20,6 @@ memcached_return_t memcached_delete_by_key(memcached_st *ptr,
                                            time_t expiration)
 {
   bool to_write;
-  size_t send_length;
   memcached_return_t rc;
   char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
   uint32_t server_key;
@@ -56,6 +55,8 @@ memcached_return_t memcached_delete_by_key(memcached_st *ptr,
   }
   else
   {
+    int send_length;
+
     unlikely (expiration)
     {
        if ((instance->major_version == 1 &&
@@ -89,25 +90,25 @@ memcached_return_t memcached_delete_by_key(memcached_st *ptr,
                 no_reply= false;
              }
           }
-          send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
-                                         "delete %.*s%.*s %u%s\r\n",
-                                         (int)ptr->prefix_key_length,
-                                         ptr->prefix_key,
-                                         (int) key_length, key,
-                                         (uint32_t)expiration,
-                                         no_reply ? " noreply" :"" );
+          send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
+                                "delete %.*s%.*s %u%s\r\n",
+                                (int)ptr->prefix_key_length,
+                                ptr->prefix_key,
+                                (int) key_length, key,
+                                (uint32_t)expiration,
+                                no_reply ? " noreply" :"" );
        }
     }
     else
     {
-      send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
-                                     "delete %.*s%.*s%s\r\n",
-                                     (int)ptr->prefix_key_length,
-                                     ptr->prefix_key,
-                                     (int)key_length, key, no_reply ? " noreply" :"");
+      send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
+                            "delete %.*s%.*s%s\r\n",
+                            (int)ptr->prefix_key_length,
+                            ptr->prefix_key,
+                            (int)key_length, key, no_reply ? " noreply" :"");
     }
 
-    if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE)
+    if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || send_length < 0)
     {
       rc= MEMCACHED_WRITE_FAILURE;
       goto error;
@@ -121,7 +122,7 @@ memcached_return_t memcached_delete_by_key(memcached_st *ptr,
         memcached_io_write(instance, NULL, 0, true);
     }
 
-    rc= memcached_do(instance, buffer, send_length, to_write);
+    rc= memcached_do(instance, buffer, (size_t)send_length, to_write);
   }
 
   if (rc != MEMCACHED_SUCCESS)
index a0d62df0e806ffb237a8b84b8761c920eeaea7ca..9ec2dab5982ebbf46bce70dcbc8fa797dc198b48 100644 (file)
@@ -11,7 +11,6 @@ static memcached_return_t ascii_dump(memcached_st *ptr, memcached_dump_fn *callb
 {
   memcached_return_t rc= MEMCACHED_SUCCESS;
   char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
-  size_t send_length;
   uint32_t server_key;
   uint32_t x;
 
@@ -26,10 +25,16 @@ static memcached_return_t ascii_dump(memcached_st *ptr, memcached_dump_fn *callb
     /* 256 I BELIEVE is the upper limit of slabs */
     for (x= 0; x < 256; x++)
     {
-      send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
-                                     "stats cachedump %u 0 0\r\n", x);
+      int send_length;
+      send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
+                            "stats cachedump %u 0 0\r\n", x);
 
-      rc= memcached_do(instance, buffer, send_length, true);
+      if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || send_length < 0)
+      {
+        return MEMCACHED_FAILURE;
+      }
+
+      rc= memcached_do(instance, buffer, (size_t)send_length, true);
 
       unlikely (rc != MEMCACHED_SUCCESS)
         goto error;
index 425d4576b8abeae82685d9b4f9b2b4ac90e970ca..5aaffa561851394ac6f4d9baea96b661f3da4736 100644 (file)
@@ -21,29 +21,37 @@ memcached_return_t memcached_flush(memcached_st *ptr, time_t expiration)
 static memcached_return_t memcached_flush_textual(memcached_st *ptr, 
                                                   time_t expiration)
 {
-  unsigned int x;
-  size_t send_length;
-  memcached_return_t rc;
-  char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
-
   unlikely (memcached_server_count(ptr) == 0)
     return MEMCACHED_NO_SERVERS;
 
-  for (x= 0; x < memcached_server_count(ptr); x++)
+  for (unsigned int x= 0; x < memcached_server_count(ptr); x++)
   {
+    memcached_return_t rc;
+    char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
+
     bool no_reply= ptr->flags.no_reply;
     memcached_server_write_instance_st instance=
       memcached_server_instance_fetch(ptr, x);
 
+    int send_length;
     if (expiration)
-      send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, 
-                                     "flush_all %llu%s\r\n",
-                                     (unsigned long long)expiration, no_reply ? " noreply" : "");
+    {
+      send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, 
+                            "flush_all %llu%s\r\n",
+                            (unsigned long long)expiration, no_reply ? " noreply" : "");
+    }
     else
-      send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, 
-                                     "flush_all%s\r\n", no_reply ? " noreply" : "");
+    {
+      send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, 
+                            "flush_all%s\r\n", no_reply ? " noreply" : "");
+    }
+
+    if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || send_length < 0)
+    {
+      return MEMCACHED_FAILURE;
+    }
 
-    rc= memcached_do(instance, buffer, send_length, true);
+    rc= memcached_do(instance, buffer, (size_t)send_length, true);
 
     if (rc == MEMCACHED_SUCCESS && !no_reply)
       (void)memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
index 4018a2581d7846865378e583b7b0eca997fadb8e..ec12c92f9813e048d9aacf887611945b7497f7ce 100644 (file)
@@ -206,15 +206,20 @@ static memcached_return_t update_continuum(memcached_st *ptr)
            pointer_index++)
       {
         char sort_host[MEMCACHED_MAX_HOST_SORT_LENGTH]= "";
-        size_t sort_host_length;
+        int sort_host_length;
 
         // Spymemcached ketema key format is: hostname/ip:port-index
         // If hostname is not available then: /ip:port-index
-        sort_host_length= (size_t) snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH,
-                                            "/%s:%u-%u",
-                                            list[host_index].hostname,
-                                            (uint32_t)list[host_index].port,
-                                            pointer_index);
+        sort_host_length= snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH,
+                                   "/%s:%u-%u",
+                                   list[host_index].hostname,
+                                   (uint32_t)list[host_index].port,
+                                   pointer_index);
+
+        if (sort_host_length >= MEMCACHED_MAX_HOST_SORT_LENGTH || sort_host_length < 0)
+        {
+          return MEMCACHED_FAILURE;
+        }
 #ifdef DEBUG
         printf("update_continuum: key is %s\n", sort_host);
 #endif
@@ -225,14 +230,14 @@ static memcached_return_t update_continuum(memcached_st *ptr)
         {
           for (uint32_t x= 0; x < pointer_per_hash; x++)
           {
-             value= ketama_server_hash(sort_host, sort_host_length, x);
+             value= ketama_server_hash(sort_host, (size_t)sort_host_length, x);
              ptr->continuum[continuum_index].index= host_index;
              ptr->continuum[continuum_index++].value= value;
           }
         }
         else
         {
-          value= hashkit_digest(&ptr->distribution_hashkit, sort_host, sort_host_length);
+          value= hashkit_digest(&ptr->distribution_hashkit, sort_host, (size_t)sort_host_length);
           ptr->continuum[continuum_index].index= host_index;
           ptr->continuum[continuum_index++].value= value;
         }
@@ -245,22 +250,27 @@ static memcached_return_t update_continuum(memcached_st *ptr)
            pointer_index++)
       {
         char sort_host[MEMCACHED_MAX_HOST_SORT_LENGTH]= "";
-        size_t sort_host_length;
+        int sort_host_length;
 
         if (list[host_index].port == MEMCACHED_DEFAULT_PORT)
         {
-          sort_host_length= (size_t) snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH,
-                                              "%s-%u",
-                                              list[host_index].hostname,
-                                              pointer_index - 1);
+          sort_host_length= snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH,
+                                     "%s-%u",
+                                     list[host_index].hostname,
+                                     pointer_index - 1);
         }
         else
         {
-          sort_host_length= (size_t) snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH,
-                                              "%s:%u-%u",
-                                              list[host_index].hostname,
-                                              (uint32_t)list[host_index].port,
-                                              pointer_index - 1);
+          sort_host_length= snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH,
+                                     "%s:%u-%u",
+                                     list[host_index].hostname,
+                                     (uint32_t)list[host_index].port,
+                                     pointer_index - 1);
+        }
+
+        if (sort_host_length >= MEMCACHED_MAX_HOST_SORT_LENGTH || sort_host_length < 0)
+        {
+          return MEMCACHED_FAILURE;
         }
 
         WATCHPOINT_ASSERT(sort_host_length);
@@ -269,14 +279,14 @@ static memcached_return_t update_continuum(memcached_st *ptr)
         {
           for (uint32_t x = 0; x < pointer_per_hash; x++)
           {
-             value= ketama_server_hash(sort_host, sort_host_length, x);
+             value= ketama_server_hash(sort_host, (size_t)sort_host_length, x);
              ptr->continuum[continuum_index].index= host_index;
              ptr->continuum[continuum_index++].value= value;
           }
         }
         else
         {
-          value= hashkit_digest(&ptr->distribution_hashkit, sort_host, sort_host_length);
+          value= hashkit_digest(&ptr->distribution_hashkit, sort_host, (size_t)sort_host_length);
           ptr->continuum[continuum_index].index= host_index;
           ptr->continuum[continuum_index++].value= value;
         }
index 0c52d97a6b4fbe8c9f1b6367dcca796b8b7c2a16..ab005f49bb578a70e81fe0aead6e672a3fd12daf 100644 (file)
@@ -227,6 +227,12 @@ char *memcached_stat_get_value(const memcached_st *ptr, memcached_stat_st *memc_
     return NULL;
   }
 
+  if (length >= SMALL_STRING_LEN || length < 0)
+  {
+    *error= MEMCACHED_FAILURE;
+    return NULL;
+  }
+
   ret= libmemcached_malloc(ptr, (size_t) (length + 1));
   memcpy(ret, buffer, (size_t) length);
   ret[length]= '\0';
@@ -329,7 +335,7 @@ static memcached_return_t ascii_stats_fetch(memcached_stat_st *memc_stat,
 {
   memcached_return_t rc;
   char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
-  size_t send_length;
+  int send_length;
 
   if (args)
     send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
@@ -338,10 +344,10 @@ static memcached_return_t ascii_stats_fetch(memcached_stat_st *memc_stat,
     send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
                                    "stats\r\n");
 
-  if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE)
+  if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || send_length < 0)
     return MEMCACHED_WRITE_FAILURE;
 
-  rc= memcached_do(instance, buffer, send_length, true);
+  rc= memcached_do(instance, buffer, (size_t)send_length, true);
   if (rc != MEMCACHED_SUCCESS)
     goto error;
 
index 25aaba303ead7fd0c367a84e1c049454e4b1f13b..782a3766790177b76867da59157d5e065e59a355 100644 (file)
@@ -104,15 +104,24 @@ static inline memcached_return_t memcached_send(memcached_st *ptr,
 
     if (cas)
     {
-      write_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
-                                      "%s %.*s%.*s %u %llu %zu %llu%s\r\n",
-                                      storage_op_string(verb),
-                                      (int)ptr->prefix_key_length,
-                                      ptr->prefix_key,
-                                      (int)key_length, key, flags,
-                                      (unsigned long long)expiration, value_length,
-                                      (unsigned long long)cas,
-                                      (ptr->flags.no_reply) ? " noreply" : "");
+      int check_length;
+      check_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
+                                    "%s %.*s%.*s %u %llu %zu %llu%s\r\n",
+                                    storage_op_string(verb),
+                                    (int)ptr->prefix_key_length,
+                                    ptr->prefix_key,
+                                    (int)key_length, key, flags,
+                                    (unsigned long long)expiration, value_length,
+                                    (unsigned long long)cas,
+                                    (ptr->flags.no_reply) ? " noreply" : "");
+      if (check_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || check_length < 0)
+      {
+        rc= MEMCACHED_WRITE_FAILURE;
+        memcached_io_reset(instance);
+
+        return rc;
+      }
+      write_length= check_length;
     }
     else
     {
@@ -133,11 +142,22 @@ static inline memcached_return_t memcached_send(memcached_st *ptr,
       buffer_ptr++;
 
       write_length= (size_t)(buffer_ptr - buffer);
-      write_length+= (size_t) snprintf(buffer_ptr, MEMCACHED_DEFAULT_COMMAND_SIZE,
-                                       "%u %llu %zu%s\r\n",
-                                       flags,
-                                       (unsigned long long)expiration, value_length,
-                                       ptr->flags.no_reply ? " noreply" : "");
+      int check_length;
+      check_length= snprintf(buffer_ptr, MEMCACHED_DEFAULT_COMMAND_SIZE -(size_t)(buffer_ptr - buffer),
+                                    "%u %llu %zu%s\r\n",
+                                    flags,
+                                    (unsigned long long)expiration, value_length,
+                                    ptr->flags.no_reply ? " noreply" : "");
+      if ((size_t)check_length >= MEMCACHED_DEFAULT_COMMAND_SIZE -(size_t)(buffer_ptr - buffer) || check_length < 0)
+      {
+        rc= MEMCACHED_WRITE_FAILURE;
+        memcached_io_reset(instance);
+
+        return rc;
+      }
+
+      write_length+= (size_t)check_length;
+      WATCHPOINT_ASSERT(write_length < MEMCACHED_DEFAULT_COMMAND_SIZE);
     }
 
     if (ptr->flags.use_udp && ptr->flags.buffer_requests)
index fba00144aa46a4004a1c6cfd2f1720c43b2bd4c5..d09035140d5b7b4ce9e7d935353f47175cea904e 100644 (file)
@@ -41,17 +41,17 @@ static memcached_return_t _set_verbosity(const memcached_st *ptr __attribute__((
 
 memcached_return_t memcached_verbosity(memcached_st *ptr, uint32_t verbosity)
 {
-  size_t send_length;
+  int send_length;
   memcached_server_fn callbacks[1];
 
   char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
 
-  send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, 
+  send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, 
                                  "verbosity %u\r\n", verbosity);
-  unlikely (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE)
+  if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || send_length < 0)
     return MEMCACHED_WRITE_FAILURE;
 
-  struct context_st context = { .length= send_length, .buffer= buffer };
+  struct context_st context = { .length= (size_t)send_length, .buffer= buffer };
 
   callbacks[0]= _set_verbosity;