[libgdata] core: Fix a data corruption bug in GDataBuffer
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgdata] core: Fix a data corruption bug in GDataBuffer
- Date: Sat, 9 Aug 2014 17:33:04 +0000 (UTC)
commit 3809b38e6651ab6b533feea9cff0b95a0ccede95
Author: Philip Withnall <philip tecnocode co uk>
Date: Sat Aug 9 17:51:42 2014 +0100
core: Fix a data corruption bug in GDataBuffer
In some situations, the buffer was reading off the end of a chunk and
into undefined memory. Spotted by asan.
e.g. Take a GDataBuffer with two chunks:
• Chunk 1, length 8192
• Chunk 2, length 699
and with head_read_offset = 8187 from a previous read. There are thus
704 bytes unread in the buffer.
If a read of 8192 bytes is performed, 5 bytes should come from chunk 1
and the remaining 699 from chunk 2. length_remaining was being
(correctly) set to 704, but then the while loop was not being entered,
as 704 is not greater than or equal to 8192 (the length of chunk 1). The
code was then falling into the G_LIKELY case below, and attempting to
read 704 bytes from offset 8187 of chunk 1 — overreading by 699 bytes
off the end of the chunk, and never getting the 699 bytes from chunk 2.
This can be fixed by correctly taking the head_read_offset into account
for the while condition.
gdata/gdata-buffer.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
---
diff --git a/gdata/gdata-buffer.c b/gdata/gdata-buffer.c
index 7b5c2fc..e7b4699 100644
--- a/gdata/gdata-buffer.c
+++ b/gdata/gdata-buffer.c
@@ -268,7 +268,7 @@ gdata_buffer_pop_data (GDataBuffer *self, guint8 *data, gsize length_requested,
/* We can't assume we'll have enough data, since we may have reached EOF */
chunk = self->head;
- while (chunk != NULL && length_remaining >= chunk->length) {
+ while (chunk != NULL && self->head_read_offset + length_remaining >= chunk->length) {
GDataBufferChunk *next_chunk;
gsize chunk_length = chunk->length - self->head_read_offset;
@@ -292,6 +292,7 @@ gdata_buffer_pop_data (GDataBuffer *self, guint8 *data, gsize length_requested,
* been corrupted somewhere). */
if (G_LIKELY (length_remaining > 0)) {
g_assert (chunk != NULL);
+ g_assert_cmpuint (length_remaining, <=, chunk->length);
/* Copy the requested data to the output */
if (data != NULL) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]