diff options
author | Nick Mathewson <nickm@torproject.org> | 2013-05-08 12:04:18 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2013-05-09 13:10:48 -0400 |
commit | 00e2310f12dfb91aca2949463b57bd6937f19166 (patch) | |
tree | 5ea0e332e40d233d798f17e48f18aceb4ebc4de6 /src | |
parent | 39ac1db60e8b920e1e6b07e08f7f3343960ece79 (diff) | |
download | tor-00e2310f12dfb91aca2949463b57bd6937f19166.tar.gz tor-00e2310f12dfb91aca2949463b57bd6937f19166.zip |
Don't run off the end of the array-of-freelists
This is a fix for bug 8844, where eugenis correctly notes that there's
a sentinel value at the end of the list-of-freelists that's never
actually checked. It's a bug since the first version of the chunked
buffer code back in 0.2.0.16-alpha.
This would probably be a crash bug if it ever happens, but nobody's
ever reported something like this, so I'm unsure whether it can occur.
It would require write_to_buf, write_to_buf_zlib, read_to_buf, or
read_to_buf_tls to get an input size of more than 32K. Still, it's a
good idea to fix this kind of thing!
Diffstat (limited to 'src')
-rw-r--r-- | src/or/buffers.c | 3 | ||||
-rw-r--r-- | src/test/test.c | 12 |
2 files changed, 14 insertions, 1 deletions
diff --git a/src/or/buffers.c b/src/or/buffers.c index ad5ab83e4f..9be0476f64 100644 --- a/src/or/buffers.c +++ b/src/or/buffers.c @@ -147,7 +147,8 @@ static INLINE chunk_freelist_t * get_freelist(size_t alloc) { int i; - for (i=0; freelists[i].alloc_size <= alloc; ++i) { + for (i=0; (freelists[i].alloc_size <= alloc && + freelists[i].alloc_size); ++i ) { if (freelists[i].alloc_size == alloc) { return &freelists[i]; } diff --git a/src/test/test.c b/src/test/test.c index ddfd6337bd..ae423948ec 100644 --- a/src/test/test.c +++ b/src/test/test.c @@ -802,6 +802,18 @@ test_buffers(void) buf_free(buf); buf = NULL; + /* Try adding a string too long for any freelist. */ + { + char *cp = tor_malloc_zero(65536); + buf = buf_new(); + write_to_buf(cp, 65536, buf); + tor_free(cp); + + tt_int_op(buf_datalen(buf), ==, 65536); + buf_free(buf); + buf = NULL; + } + done: if (buf) buf_free(buf); |