diff options
author | Huzaifa Sidhpurwala <huzaifas@redhat.com> | 2013-12-08 17:33:15 -0800 |
---|---|---|
committer | dormando <dormando@rydia.net> | 2013-12-08 17:39:17 -0800 |
commit | 6695ccbc525c36d693aaa3e8337b36aa0c784424 (patch) | |
tree | 1060c244019a39f5ea9de4958c4676ba2161bfd6 | |
parent | 8ae10eba01e3cf65a106b568698f439c4f54efbd (diff) | |
download | memcached-6695ccbc525c36d693aaa3e8337b36aa0c784424.tar.gz |
Fix segfault on specially crafted packet.
-rw-r--r-- | memcached.c | 10 | ||||
-rw-r--r-- | t/issue_192.t | 20 |
2 files changed, 30 insertions, 0 deletions
diff --git a/memcached.c b/memcached.c index b6ed7c9..f3b9939 100644 --- a/memcached.c +++ b/memcached.c @@ -3872,6 +3872,16 @@ static void drive_machine(conn *c) { complete_nread(c); break; } + + /* Check if rbytes < 0, to prevent crash */ + if (c->rlbytes < 0) { + if (settings.verbose) { + fprintf(stderr, "Invalid rlbytes to read: len %d\n", c->rlbytes); + } + conn_set_state(c, conn_closing); + break; + } + /* first check if we have leftovers in the conn_read buffer */ if (c->rbytes > 0) { int tocopy = c->rbytes > c->rlbytes ? c->rlbytes : c->rbytes; diff --git a/t/issue_192.t b/t/issue_192.t new file mode 100644 index 0000000..c58e206 --- /dev/null +++ b/t/issue_192.t @@ -0,0 +1,20 @@ +#!/usr/bin/perl + +use strict; +use Test::More tests => 2; +use FindBin qw($Bin); +use lib "$Bin/lib"; +use MemcachedTest; + +my $server = new_memcached(); +my $sock = $server->sock; + +ok($server->new_sock, "opened new socket"); + +print $sock "\x80\x12\x00\x01\x08\x00\x00\x00\xff\xff\xff\xe8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; + +sleep 0.5; +ok($server->new_sock, "failed to open new socket"); + + + |