aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-kafka.c
diff options
context:
space:
mode:
authorJohn Thacker <johnthacker@gmail.com>2023-05-28 07:14:52 -0400
committerJohn Thacker <johnthacker@gmail.com>2023-05-28 07:14:52 -0400
commitb673bc022aa28c2c381cb96cae09357bd27eb0df (patch)
tree8d67516a07d1ad4c33f842b2d38455ca4a65ceec /epan/dissectors/packet-kafka.c
parent91cbf179bf890413bb6ff3152c163cd6a3fa0d37 (diff)
kafka: Don't use after free
Neither tvb_new_child_real_data() nor tvb_composite_append() copy the real data buffer that they're given. So we can't free a decompressed buffer after making it a tvb. We can realloc if the output size is smaller. Fix #19105
Diffstat (limited to 'epan/dissectors/packet-kafka.c')
-rw-r--r--epan/dissectors/packet-kafka.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/epan/dissectors/packet-kafka.c b/epan/dissectors/packet-kafka.c
index 20eb978f70..455f344433 100644
--- a/epan/dissectors/packet-kafka.c
+++ b/epan/dissectors/packet-kafka.c
@@ -1673,7 +1673,6 @@ decompress_lz4(tvbuff_t *tvb, packet_info *pinfo, int offset, guint32 length, tv
dst_size = (size_t)lz4_info.contentSize;
}
- decompressed_buffer = wmem_alloc(pinfo->pool, dst_size);
size_t out_size;
int count = 0;
@@ -1683,12 +1682,16 @@ decompress_lz4(tvbuff_t *tvb, packet_info *pinfo, int offset, guint32 length, tv
goto end;
}
+ decompressed_buffer = wmem_alloc(pinfo->pool, dst_size);
out_size = dst_size;
rc = LZ4F_decompress(lz4_ctxt, decompressed_buffer, &out_size,
&data[src_offset], &src_size, NULL);
if (LZ4F_isError(rc)) {
goto end;
}
+ if (out_size != dst_size) {
+ decompressed_buffer = (guint8 *)wmem_realloc(pinfo->pool, decompressed_buffer, out_size);
+ }
if (out_size == 0) {
goto end;
}
@@ -1730,7 +1733,7 @@ static gboolean
decompress_snappy(tvbuff_t *tvb, packet_info *pinfo, int offset, guint32 length, tvbuff_t **decompressed_tvb, int *decompressed_offset)
{
guint8 *data = (guint8*)tvb_memdup(pinfo->pool, tvb, offset, length);
- size_t uncompressed_size;
+ size_t uncompressed_size, out_size;
snappy_status rc = SNAPPY_OK;
tvbuff_t *composite_tvb = NULL;
gboolean ret = FALSE;
@@ -1767,18 +1770,21 @@ decompress_snappy(tvbuff_t *tvb, packet_info *pinfo, int offset, guint32 length,
goto end;
}
guint8 *decompressed_buffer = (guint8*)wmem_alloc(pinfo->pool, uncompressed_size);
- rc = snappy_uncompress(&data[pos], chunk_size, decompressed_buffer, &uncompressed_size);
+ out_size = uncompressed_size;
+ rc = snappy_uncompress(&data[pos], chunk_size, decompressed_buffer, &out_size);
if (rc != SNAPPY_OK) {
goto end;
}
+ if (out_size != uncompressed_size) {
+ decompressed_buffer = (guint8 *)wmem_realloc(pinfo->pool, decompressed_buffer, out_size);
+ }
if (!composite_tvb) {
composite_tvb = tvb_new_composite();
}
tvb_composite_append(composite_tvb,
- tvb_new_child_real_data(tvb, decompressed_buffer, (guint)uncompressed_size, (gint)uncompressed_size));
+ tvb_new_child_real_data(tvb, decompressed_buffer, (guint)out_size, (gint)out_size));
pos += chunk_size;
- wmem_free(pinfo->pool, decompressed_buffer);
count++;
DISSECTOR_ASSERT_HINT(count < MAX_LOOP_ITERATIONS, "MAX_LOOP_ITERATIONS exceeded");
}
@@ -1793,12 +1799,16 @@ decompress_snappy(tvbuff_t *tvb, packet_info *pinfo, int offset, guint32 length,
guint8 *decompressed_buffer = (guint8*)wmem_alloc(pinfo->pool, uncompressed_size);
- rc = snappy_uncompress(data, length, decompressed_buffer, &uncompressed_size);
+ out_size = uncompressed_size;
+ rc = snappy_uncompress(data, length, decompressed_buffer, &out_size);
if (rc != SNAPPY_OK) {
goto end;
}
+ if (out_size != uncompressed_size) {
+ decompressed_buffer = (guint8 *)wmem_realloc(pinfo->pool, decompressed_buffer, out_size);
+ }
- *decompressed_tvb = tvb_new_child_real_data(tvb, decompressed_buffer, (guint)uncompressed_size, (gint)uncompressed_size);
+ *decompressed_tvb = tvb_new_child_real_data(tvb, decompressed_buffer, (guint)out_size, (gint)out_size);
*decompressed_offset = 0;
}