summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHuzaifa Sidhpurwala <huzaifas@redhat.com>2013-12-08 17:33:15 -0800
committerdormando <dormando@rydia.net>2013-12-08 17:39:17 -0800
commit6695ccbc525c36d693aaa3e8337b36aa0c784424 (patch)
tree1060c244019a39f5ea9de4958c4676ba2161bfd6
parent8ae10eba01e3cf65a106b568698f439c4f54efbd (diff)
downloadmemcached-6695ccbc525c36d693aaa3e8337b36aa0c784424.tar.gz
Fix segfault on specially crafted packet.
-rw-r--r--memcached.c10
-rw-r--r--t/issue_192.t20
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");
+
+
+