[PATCHES] MSZIP support for cabinet files
Jeremy Allison
jra at samba.org
Wed Jul 12 23:22:02 UTC 2017
On Mon, Jul 03, 2017 at 07:11:07PM +0200, Aurélien Aptel via samba-technical wrote:
> After more careful reading I think code will fail early already, I've
> switched some variables to size_t for counts and offsets just in case.
>
> In the pull function I've added more remaining byte checks for when we
> are raw-pulling CFDATAs.
>
> I've also changed the magic 15 constant to MAX_WBITS, like it was
> changed in other code paths.
>
> Feel free to squash if you think it's appropriate. I'm attaching the
> whole thing again with my last 3 commits appended.
Getting better. This part concerns me:
+ * similarly, we don't know the compressed
+ * size yet, remember offset, write zeros,
+ * fill out later
+ */
+ compressed_offset = ndr->offset;
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, 0));
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->cbUncomp));
+
+
+ switch (cab_ctype) {
+ case CF_COMPRESS_NONE:
+ /* just copy the data */
+ NDR_CHECK(ndr_push_bytes(ndr, r->ab.data, r->ab.length));
+ compressed_length = r->cbUncomp;
+
+ break;
+
We write a 16-bit value: r->cbUncomp, then write out
r->ab.length bytes and set compressed_length = r->cbUncomp - a totally
different (and client supplied I think) field.
What if they don't match ? The other case statement uses the
offset from struct ndr_push * after the push has been done.
Can we do the same in the uncompressed case too ? Or maybe
abort if r->cbUncomp != r->ab.length in the uncompressed
case (as they should be the same).
Inside:
+static enum ndr_err_code ndr_push_compression_mszip_cab_chunk(struct ndr_push *ndrpush,
+ struct ndr_pull *ndrpull,
+ struct ndr_compression_state *state)
+{
+ DATA_BLOB comp_chunk;
+ uint32_t comp_chunk_size;
+ DATA_BLOB plain_chunk;
+ uint32_t plain_chunk_size;
+ uint32_t plain_chunk_offset;
+ uint32_t max_plain_size = 0x00008000;
+ /*
+ * The maximum compressed size of each MSZIP block is 32k + 12 bytes
+ * header size.
+ */
+ uint32_t max_comp_size = 0x00008000 + 12;
+ int z_ret;
+ z_stream *z;
+
+ plain_chunk_size = MIN(max_plain_size, ndrpull->data_size - ndrpull->offset);
Can you add a check that 'ndrpull->data_size > ndrpull->offset'.
I know this will never happen, but I really hate seeing raw
unchecked arithmetic on values in marshalling/unmarshalling code.
It makes me nervous :-). I need to feel calm when reading this
code :-).
Also here:
+ comp_chunk_size = 2 + z->total_out;
Jeremy.
More information about the samba-technical
mailing list