summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2009-08-26 02:36:14 -0700
committerTrond Norbye <Trond.Norbye@sun.com>2009-08-26 11:51:06 +0200
commit483e82adc89c984cbe040857d9cf43fc725883cd (patch)
tree41d96327e1c0109536d16397d5aba02f5dcd7e66
parent18e75bdc19992c846f96f688297ca9904de37379 (diff)
downloadmemcached-1.4.1-rc1.tar.gz
Fix memory corruption issue with bad item lengths1.4.1-rc1
Partially fixed in 1.2.8, unfixed somewhere since, now fully fixed. Negative values allowed memory corruption, and high values also allowed corruption in swallow mode. Length is now guaranteed to be positive. Fixes issue 70.
-rw-r--r--memcached.c15
-rw-r--r--t/issue_70.t22
2 files changed, 32 insertions, 5 deletions
diff --git a/memcached.c b/memcached.c
index 59b4284..c074aa6 100644
--- a/memcached.c
+++ b/memcached.c
@@ -2493,27 +2493,32 @@ static void process_update_command(conn *c, token_t *tokens, const size_t ntoken
// does cas value exist?
if (handle_cas) {
- if (!safe_strtoull(tokens[5].value, &req_cas_id)
- || vlen < 0 ) {
+ if (!safe_strtoull(tokens[5].value, &req_cas_id)) {
out_string(c, "CLIENT_ERROR bad command line format");
return;
}
}
+ vlen += 2;
+ if (vlen < 0 || vlen - 2 < 0) {
+ out_string(c, "CLIENT_ERROR bad command line format");
+ return;
+ }
+
if (settings.detail_enabled) {
stats_prefix_record_set(key, nkey);
}
- it = item_alloc(key, nkey, flags, realtime(exptime), vlen+2);
+ it = item_alloc(key, nkey, flags, realtime(exptime), vlen);
if (it == 0) {
- if (! item_size_ok(nkey, flags, vlen + 2))
+ if (! item_size_ok(nkey, flags, vlen))
out_string(c, "SERVER_ERROR object too large for cache");
else
out_string(c, "SERVER_ERROR out of memory storing object");
/* swallow the data line */
c->write_and_go = conn_swallow;
- c->sbytes = vlen + 2;
+ c->sbytes = vlen;
/* Avoid stale data persisting in cache because we failed alloc.
* Unacceptable for SET. Anywhere else too? */
diff --git a/t/issue_70.t b/t/issue_70.t
new file mode 100644
index 0000000..95e39db
--- /dev/null
+++ b/t/issue_70.t
@@ -0,0 +1,22 @@
+#!/usr/bin/perl
+
+use strict;
+use Test::More tests => 4;
+use FindBin qw($Bin);
+use lib "$Bin/lib";
+use MemcachedTest;
+
+my $server = new_memcached();
+my $sock = $server->sock;
+
+print $sock "set issue70 0 0 0\r\n\r\n";
+is (scalar <$sock>, "STORED\r\n", "stored issue70");
+
+print $sock "set issue70 0 0 -1\r\n";
+is (scalar <$sock>, "CLIENT_ERROR bad command line format\r\n");
+
+print $sock "set issue70 0 0 4294967295\r\n";
+is (scalar <$sock>, "CLIENT_ERROR bad command line format\r\n");
+
+print $sock "set issue70 0 0 2147483647\r\nscoobyscoobydoo";
+is (scalar <$sock>, "CLIENT_ERROR bad command line format\r\n");