kafka: lz4: free the composite tvb only once

Try to clean up the composite tvb handling during lz4 decompression.

If we detect an error straight away before doing any lz4 decompression, we
don't allocate a composite tvb at all. The comments in the tvb code say
explicitly that we must not call tvb_new_composite() without adding at
least one piece of data.

If we start decompressing and run into problems after creating the
composite tvb and linking it to the packet's main tvb, we must not free
the composite tvb manually. The epan library will do this for us when
dissection of the packet is finished.

While at it, make sure that we always finalize the composite tvb if we
allocated it and added data to it.

Bug: 16672
Change-Id: I3e3fb303a823640d7707277a109019fc3aad22f2
Reviewed-on: https://code.wireshark.org/review/37696
Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Martin Kaiser 2020-07-04 15:50:17 +02:00 committed by Anders Broman
parent 23aa1ed679
commit 79576219c9
1 changed files with 12 additions and 9 deletions

View File

@ -1305,7 +1305,7 @@ decompress_lz4(tvbuff_t *tvb, packet_info *pinfo, int offset, guint32 length, tv
LZ4F_errorCode_t rc = 0;
size_t src_offset = 0, src_size = 0, dst_size = 0;
guchar *decompressed_buffer = NULL;
tvbuff_t *composite_tvb = tvb_new_composite();
tvbuff_t *composite_tvb = NULL;
int ret = 0;
@ -1369,22 +1369,25 @@ decompress_lz4(tvbuff_t *tvb, packet_info *pinfo, int offset, guint32 length, tv
if (dst_size == 0) {
goto end;
}
if (!composite_tvb) {
composite_tvb = tvb_new_composite();
}
tvb_composite_append(composite_tvb,
tvb_new_child_real_data(tvb, (guint8*)decompressed_buffer, (guint)dst_size, (gint)dst_size));
src_offset += src_size; // bump up the offset for the next iteration
} while (rc > 0);
tvb_composite_finalize(composite_tvb);
*decompressed_tvb = composite_tvb;
*decompressed_offset = 0;
composite_tvb = NULL;
ret = 1;
end:
LZ4F_freeDecompressionContext(lz4_ctxt);
if (composite_tvb != NULL) {
tvb_free_chain(composite_tvb);
if (composite_tvb) {
tvb_composite_finalize(composite_tvb);
}
if (ret == 0) {
LZ4F_freeDecompressionContext(lz4_ctxt);
if (ret == 1) {
*decompressed_tvb = composite_tvb;
*decompressed_offset = 0;
}
else {
col_append_str(pinfo->cinfo, COL_INFO, " [lz4 decompression failed]");
}
return ret;