diff options
author | dormando <dormando@rydia.net> | 2009-08-26 02:36:14 -0700 |
---|---|---|
committer | Trond Norbye <Trond.Norbye@sun.com> | 2009-08-26 11:51:06 +0200 |
commit | 483e82adc89c984cbe040857d9cf43fc725883cd (patch) | |
tree | 41d96327e1c0109536d16397d5aba02f5dcd7e66 | |
parent | 18e75bdc19992c846f96f688297ca9904de37379 (diff) | |
download | memcached-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.c | 15 | ||||
-rw-r--r-- | t/issue_70.t | 22 |
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"); |