From a37baeb81b87779c7de9ec9c573deae00a0c18b5 Mon Sep 17 00:00:00 2001 From: Tomasz Grabiec Date: Fri, 13 Feb 2015 15:26:20 +0100 Subject: [PATCH] transport: server: Guard against buffer overrun when parsing CQL3 frame --- transport/server.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/transport/server.cc b/transport/server.cc index bcd71fde4d..03aa01b421 100644 --- a/transport/server.cc +++ b/transport/server.cc @@ -12,6 +12,7 @@ #include "net/byteorder.hh" #include "cql3/CqlParser.hpp" +#include "transport/protocol_exception.hh" #include #include @@ -163,6 +164,12 @@ private: future<> write_supported(int16_t stream); future<> write_response(shared_ptr response); + void check_room(temporary_buffer& buf, size_t n) { + if (buf.size() < n) { + throw transport::protocol_exception("truncated frame"); + } + } + int8_t read_byte(temporary_buffer& buf); int32_t read_int(temporary_buffer& buf); int64_t read_long(temporary_buffer& buf); @@ -430,6 +437,7 @@ future<> cql_server::connection::write_response(shared_ptr int8_t cql_server::connection::read_byte(temporary_buffer& buf) { + check_room(buf, 1); int8_t n = buf[0]; buf.trim_front(1); return n; @@ -437,6 +445,7 @@ int8_t cql_server::connection::read_byte(temporary_buffer& buf) int32_t cql_server::connection::read_int(temporary_buffer& buf) { + check_room(buf, sizeof(int32_t)); auto p = reinterpret_cast(buf.begin()); uint32_t n = (static_cast(p[0]) << 24) | (static_cast(p[1]) << 16) @@ -448,6 +457,7 @@ int32_t cql_server::connection::read_int(temporary_buffer& buf) int64_t cql_server::connection::read_long(temporary_buffer& buf) { + check_room(buf, sizeof(int64_t)); auto p = reinterpret_cast(buf.begin()); uint64_t n = (static_cast(p[0]) << 56) | (static_cast(p[1]) << 48) @@ -463,6 +473,7 @@ int64_t cql_server::connection::read_long(temporary_buffer& buf) int16_t cql_server::connection::read_short(temporary_buffer& buf) { + check_room(buf, sizeof(uint16_t)); auto p = reinterpret_cast(buf.begin()); uint16_t n = (static_cast(p[0]) << 8) | (static_cast(p[1])); @@ -473,6 +484,7 @@ int16_t cql_server::connection::read_short(temporary_buffer& buf) sstring cql_server::connection::read_string(temporary_buffer& buf) { auto n = read_short(buf); + check_room(buf, n); sstring s{buf.begin(), static_cast(n)}; assert(n >= 0); buf.trim_front(n); @@ -482,6 +494,7 @@ sstring cql_server::connection::read_string(temporary_buffer& buf) sstring cql_server::connection::read_long_string(temporary_buffer& buf) { auto n = read_int(buf); + check_room(buf, n); sstring s{buf.begin(), static_cast(n)}; buf.trim_front(n); return s;