Skip to content

Commit

Permalink
Fix memory corruption issue with bad item lengths
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
dormando authored and Trond Norbye committed Aug 26, 2009
1 parent 18e75bd commit 483e82a
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 5 deletions.
15 changes: 10 additions & 5 deletions memcached.c
Original file line number Diff line number Diff line change
Expand Up @@ -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? */
Expand Down
22 changes: 22 additions & 0 deletions t/issue_70.t
Original file line number Diff line number Diff line change
@@ -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");

0 comments on commit 483e82a

Please sign in to comment.