From 23797120ffff5de35fc1a0572b78ddfcbba17b8d Mon Sep 17 00:00:00 2001 From: Jens Auer Date: Mon, 20 Jul 2015 22:22:13 +0200 Subject: [PATCH 1/2] Fixed #1477 corruption in "zero-copy" raw_decoder for payloads larger than 8192 bytes #1477 Fixed wrong message::init arguments. --- Makefile.am | 6 +- src/raw_decoder.cpp | 1 + tests/test_stream_exceeds_buffer.cpp | 83 ++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 tests/test_stream_exceeds_buffer.cpp diff --git a/Makefile.am b/Makefile.am index da9c2bad..eed71589 100644 --- a/Makefile.am +++ b/Makefile.am @@ -364,7 +364,8 @@ test_apps = \ tests/test_client_drop_more \ tests/test_thread_safe \ tests/test_socketopt_hwm \ - tests/test_heartbeats + tests/test_heartbeats \ + tests/test_stream_exceeds_buffer tests_test_system_SOURCES = tests/test_system.cpp tests_test_system_LDADD = src/libzmq.la @@ -569,6 +570,9 @@ tests_test_socketopt_hwm_LDADD = src/libzmq.la tests_test_heartbeats_SOURCES = tests/test_heartbeats.cpp tests_test_heartbeats_LDADD = src/libzmq.la +tests_test_stream_exceeds_buffer_SOURCES = tests/test_stream_exceeds_buffer.cpp +tests_test_stream_exceeds_buffer_LDADD = src/libzmq.la + if !ON_MINGW if !ON_CYGWIN test_apps += \ diff --git a/src/raw_decoder.cpp b/src/raw_decoder.cpp index ceffd383..125d9ba5 100644 --- a/src/raw_decoder.cpp +++ b/src/raw_decoder.cpp @@ -62,6 +62,7 @@ int zmq::raw_decoder_t::decode (const uint8_t *data_, size_t size_, { int rc = in_progress.init ((unsigned char*)data_, size_, shared_message_memory_allocator::call_dec_ref, + allocator.buffer(), allocator.create_refcnt() ); // if the buffer serves as memory for a zero-copy message, release it diff --git a/tests/test_stream_exceeds_buffer.cpp b/tests/test_stream_exceeds_buffer.cpp new file mode 100644 index 00000000..9d126088 --- /dev/null +++ b/tests/test_stream_exceeds_buffer.cpp @@ -0,0 +1,83 @@ +#include +#include +#include + +#include +#include + +#include + +int main() +{ + const int msgsize = 8193; + char sndbuf[msgsize] = "\xde\xad\xbe\xef"; + unsigned char rcvbuf[msgsize]; + + int server_sock = socket(AF_INET, SOCK_STREAM, 0); + assert(server_sock!=-1); + int enable = 1; + int rc = setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable)); + assert(rc!=-1); + + struct sockaddr_in saddr; + memset(&saddr, 0, sizeof(saddr)); + saddr.sin_family = AF_INET; + saddr.sin_addr.s_addr = INADDR_ANY; + saddr.sin_port = htons(12345); + + rc = bind(server_sock, (struct sockaddr *)&saddr, sizeof(saddr)); + assert(rc!=-1); + rc = listen(server_sock, 1); + assert(rc!=-1); + + void *zctx = zmq_ctx_new(); + assert(zctx); + void *zsock = zmq_socket(zctx, ZMQ_STREAM); + assert(zsock); + rc = zmq_connect(zsock, "tcp://127.0.0.1:12345"); + assert(rc!=-1); + + int client_sock = accept(server_sock, NULL, NULL); + assert(client_sock!=-1); + + rc = close(server_sock); + assert(rc!=-1); + + rc = send(client_sock, sndbuf, msgsize, 0); + assert(rc==msgsize); + + zmq_msg_t msg; + zmq_msg_init(&msg); + + int rcvbytes = 0; + while (rcvbytes==0) // skip connection notification, if any + { + rc = zmq_msg_recv(&msg, zsock, 0); // peerid + assert(rc!=-1); + assert(zmq_msg_more(&msg)); + rcvbytes = zmq_msg_recv(&msg, zsock, 0); + assert(rcvbytes!=-1); + assert(!zmq_msg_more(&msg)); + printf("got %d bytes\n", rcvbytes); + } + + // for this test, we only collect the first chunk + // since the corruption already occurs in the first chunk + memcpy(rcvbuf, zmq_msg_data(&msg), zmq_msg_size(&msg)); + + zmq_msg_close(&msg); + zmq_close(zsock); + close(client_sock); + + zmq_ctx_destroy(zctx); + + assert(rcvbytes >= 4); + printf("%x %x %x %x\n", rcvbuf[0], rcvbuf[1], rcvbuf[2], rcvbuf[3]); + + // notice that only the 1st byte gets corrupted + assert(rcvbuf[3]==0xef); + assert(rcvbuf[2]==0xbe); + assert(rcvbuf[1]==0xad); + assert(rcvbuf[0]==0xde); +} + From 6b9b13be6c298dd5064b133e2460e862ef4fd2d8 Mon Sep 17 00:00:00 2001 From: Jens Auer Date: Mon, 20 Jul 2015 22:34:22 +0200 Subject: [PATCH 2/2] Fixed whitespace error. --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index eed71589..c9889e9b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -365,7 +365,7 @@ test_apps = \ tests/test_thread_safe \ tests/test_socketopt_hwm \ tests/test_heartbeats \ - tests/test_stream_exceeds_buffer + tests/test_stream_exceeds_buffer tests_test_system_SOURCES = tests/test_system.cpp tests_test_system_LDADD = src/libzmq.la