From 1c5dea03fd77a12341688b41e8b63e1c358a2ad6 Mon Sep 17 00:00:00 2001 From: Mark Atwood Date: Sat, 22 Sep 2007 15:09:03 -0700 Subject: [PATCH] add error checking, for command overflow, and short writes --- lib/memcached_auto.c | 9 ++++++--- lib/memcached_delete.c | 9 +++++++-- lib/memcached_flush.c | 10 ++++++++-- lib/memcached_get.c | 13 +++++++++---- lib/memcached_stats.c | 10 ++++++++-- lib/memcached_storage.c | 2 ++ lib/memcached_verbosity.c | 8 ++++++-- 7 files changed, 46 insertions(+), 15 deletions(-) diff --git a/lib/memcached_auto.c b/lib/memcached_auto.c index 7122dc90..86ee7669 100644 --- a/lib/memcached_auto.c +++ b/lib/memcached_auto.c @@ -6,7 +6,7 @@ static memcached_return memcached_auto(memcached_st *ptr, unsigned int offset, unsigned int *value) { - size_t send_length; + size_t send_length, sent_length; memcached_return rc; char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; unsigned int server_key; @@ -22,8 +22,11 @@ static memcached_return memcached_auto(memcached_st *ptr, "%s %.*s %u\r\n", verb, (int)key_length, key, offset); - - if ((write(ptr->hosts[server_key].fd, buffer, send_length) == -1)) + if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) + return MEMCACHED_WRITE_FAILURE; + if ((sent_length= write(ptr->hosts[server_key].fd, buffer, send_length) == -1)) + return MEMCACHED_WRITE_FAILURE; + if (sent_length != send_length) return MEMCACHED_WRITE_FAILURE; memset(buffer, 0, MEMCACHED_DEFAULT_COMMAND_SIZE); diff --git a/lib/memcached_delete.c b/lib/memcached_delete.c index d24c0f82..11b22ece 100644 --- a/lib/memcached_delete.c +++ b/lib/memcached_delete.c @@ -3,7 +3,7 @@ memcached_return memcached_delete(memcached_st *ptr, char *key, size_t key_length, time_t expiration) { - size_t send_length; + size_t send_length, sent_length; memcached_return rc; char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; unsigned int server_key; @@ -23,7 +23,12 @@ memcached_return memcached_delete(memcached_st *ptr, char *key, size_t key_lengt send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, "delete %.*s\r\n", (int)key_length, key); - if ((write(ptr->hosts[server_key].fd, buffer, send_length) == -1)) + if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) + return MEMCACHED_WRITE_FAILURE; + + if ((sent_length = write(ptr->hosts[server_key].fd, buffer, send_length) == -1)) + return MEMCACHED_WRITE_FAILURE; + if (sent_length != send_length) return MEMCACHED_WRITE_FAILURE; return memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, server_key); diff --git a/lib/memcached_flush.c b/lib/memcached_flush.c index 8c51cdf1..4ca73e30 100644 --- a/lib/memcached_flush.c +++ b/lib/memcached_flush.c @@ -3,7 +3,7 @@ memcached_return memcached_flush(memcached_st *ptr, time_t expiration) { unsigned int x; - size_t send_length; + size_t send_length, sent_length; memcached_return rc; char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; @@ -20,7 +20,13 @@ memcached_return memcached_flush(memcached_st *ptr, time_t expiration) else send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, "flush_all\r\n"); - if ((write(ptr->hosts[x].fd, buffer, send_length) == -1)) + + if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) + return MEMCACHED_WRITE_FAILURE; + + if ((sent_length= write(ptr->hosts[x].fd, buffer, send_length) == -1)) + return MEMCACHED_WRITE_FAILURE; + if (sent_length != send_length) return MEMCACHED_WRITE_FAILURE; rc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, x); diff --git a/lib/memcached_get.c b/lib/memcached_get.c index a1885450..9eb60e26 100644 --- a/lib/memcached_get.c +++ b/lib/memcached_get.c @@ -5,7 +5,7 @@ char *memcached_get(memcached_st *ptr, char *key, size_t key_length, uint16_t *flags, memcached_return *error) { - size_t send_length; + size_t send_length, sent_length; char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; char *string_ptr; unsigned int server_key; @@ -20,14 +20,19 @@ char *memcached_get(memcached_st *ptr, char *key, size_t key_length, send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, "get %.*s\r\n", (int)key_length, key); - if (*error != MEMCACHED_SUCCESS) - return NULL; - if ((write(ptr->hosts[server_key].fd, buffer, send_length) == -1)) + if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) + return MEMCACHED_WRITE_FAILURE; + + if ((sent_length = write(ptr->hosts[server_key].fd, buffer, send_length) == -1)) { *error= MEMCACHED_WRITE_FAILURE; return NULL; } + if (sent_length != send_length) { + *error= MEMCACHED_WRITE_FAILURE; + return NULL; + } memset(buffer, 0, MEMCACHED_DEFAULT_COMMAND_SIZE); *error= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, server_key); diff --git a/lib/memcached_stats.c b/lib/memcached_stats.c index d7f948fa..8a05dfd9 100644 --- a/lib/memcached_stats.c +++ b/lib/memcached_stats.c @@ -122,7 +122,7 @@ static memcached_return memcached_stats_fetch(memcached_st *ptr, { memcached_return rc; char buffer[HUGE_STRING_LEN]; - size_t send_length; + size_t send_length, sent_length; rc= memcached_connect(ptr); @@ -136,12 +136,18 @@ static memcached_return memcached_stats_fetch(memcached_st *ptr, send_length= snprintf(buffer, HUGE_STRING_LEN, "stats\r\n"); - if ((write(ptr->hosts[server_key].fd, buffer, send_length) == -1)) + if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) + return MEMCACHED_WRITE_FAILURE; + + if ((sent_length= write(ptr->hosts[server_key].fd, buffer, send_length) == -1)) { fprintf(stderr, "failed on stats\n"); return MEMCACHED_WRITE_FAILURE; } + if (sent_length != send_length) + return MEMCACHED_WRITE_FAILURE; + rc= memcached_response(ptr, buffer, HUGE_STRING_LEN, 0); diff --git a/lib/memcached_storage.c b/lib/memcached_storage.c index 484341c8..21dc0934 100644 --- a/lib/memcached_storage.c +++ b/lib/memcached_storage.c @@ -35,6 +35,8 @@ static memcached_return memcached_send(memcached_st *ptr, "%s %.*s %x %llu %zu\r\n", verb, (int)key_length, key, flags, (unsigned long long)expiration, value_length); + if (write_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) + return MEMCACHED_WRITE_FAILURE; if ((sent_length= write(ptr->hosts[server_key].fd, buffer, write_length)) == -1) return MEMCACHED_WRITE_FAILURE; assert(write_length == sent_length); diff --git a/lib/memcached_verbosity.c b/lib/memcached_verbosity.c index 506dbb07..ecea6f22 100644 --- a/lib/memcached_verbosity.c +++ b/lib/memcached_verbosity.c @@ -3,7 +3,7 @@ memcached_return memcached_verbosity(memcached_st *ptr, unsigned int verbosity) { unsigned int x; - size_t send_length; + size_t send_length, sent_length; memcached_return rc; char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; @@ -14,12 +14,16 @@ memcached_return memcached_verbosity(memcached_st *ptr, unsigned int verbosity) send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, "verbosity %u\r\n", verbosity); + if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE) + return MEMCACHED_WRITE_FAILURE; for (x= 0; x < ptr->number_of_hosts; x++) { memcached_return rc; - if ((write(ptr->hosts[x].fd, buffer, send_length) == -1)) + if ((sent_length= write(ptr->hosts[x].fd, buffer, send_length) == -1)) + return MEMCACHED_WRITE_FAILURE; + if (sent_length != send_length) return MEMCACHED_WRITE_FAILURE; rc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, x); -- 2.30.2