diff options
author | Alexey Kopytov <Alexey.Kopytov@Sun.com> | 2009-07-28 22:35:55 +0400 |
---|---|---|
committer | Alexey Kopytov <Alexey.Kopytov@Sun.com> | 2009-07-28 22:35:55 +0400 |
commit | baefaa1e58a3574c01f7a3df14db85a96f0e9c46 (patch) | |
tree | 41e344a26fef09a73c14db77856164b800cd4041 /sql/net_serv.cc | |
parent | 1a4bc9a1e429697f86f63f2599e49a4f2d29cd32 (diff) | |
download | mariadb-git-baefaa1e58a3574c01f7a3df14db85a96f0e9c46.tar.gz |
Bug #45031: invalid memory reads in my_real_read using protocol
compression
Since uint3korr() may read 4 bytes depending on build flags and
platform, allocate 1 extra "safety" byte in the network buffer
for cases when uint3korr() in my_real_read() is called to read
last 3 bytes in the buffer.
It is practically hard to construct a reliable and reasonably
small test case for this bug as that would require constructing
input stream such that a certain sequence of bytes in a
compressed packet happens to be the last 3 bytes of the network
buffer.
sql/net_serv.cc:
Allocate 1 extra "safety" byte in the network buffer for cases
when uint3korr() is used to read last 3 bytes in the buffer.
Diffstat (limited to 'sql/net_serv.cc')
-rw-r--r-- | sql/net_serv.cc | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 627a5fae5e3..fdabad6f569 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -188,10 +188,12 @@ my_bool net_realloc(NET *net, ulong length) pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1); /* We must allocate some extra bytes for the end 0 and to be able to - read big compressed blocks + read big compressed blocks + 1 safety byte since uint3korr() in + my_real_read() may actually read 4 bytes depending on build flags and + platform. */ if (!(buff=(uchar*) my_realloc((char*) net->buff, (uint32) pkt_length + - NET_HEADER_SIZE + COMP_HEADER_SIZE, + NET_HEADER_SIZE + COMP_HEADER_SIZE + 1, MYF(MY_WME)))) { net->error= 1; @@ -919,6 +921,13 @@ my_real_read(NET *net, ulong *complen) #ifdef HAVE_COMPRESS if (net->compress) { + /* + The following uint3korr() may read 4 bytes, so make sure we don't + read unallocated or uninitialized memory. The right-hand expression + must match the size of the buffer allocated in net_realloc(). + */ + DBUG_ASSERT(net->where_b + NET_HEADER_SIZE + sizeof(uint32) <= + net->max_packet + NET_HEADER_SIZE + COMP_HEADER_SIZE + 1); /* If the packet is compressed then complen > 0 and contains the number of bytes in the uncompressed packet |