Page 1 of 1

Memory clobbering problems in zm_jpeg.c?

Posted: Fri Jan 02, 2004 2:02 am
by snakebyte
example:

Line 46:

mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;

cinfo->dest is a pointer to a jpeg_destination_mgr struct.
dest is a pointer to a mem_destination_mgr struct.

mem_dest_ptr contains a jpeg_destination_mgr struct as its first member.

this means that after the assignment done above, the first four bytes of dest will both point to the beginning of a mem_destination_mgr struct as well as point to the jpeg_destionation_mgr struct.

Now lets step back a bit:

at some point cinfo->dest was allocated enough memory for a jpeg_destionation_mgr. Lets just say for sake of argument this size is 24 bytes. So somewhere in phyiscal memory there is a 24 byte block of memory. Lets say it starts at 0x100. that means that 0x100 through 0x118 belongs to cinfo->dest. In particular, this means that 0x100 is the location for the first member, 0x104 is the location for the second member, etc...until the last member has an address of 0x114.

Since we're dealing with pointers to structs, this also means that cinfo->dest's value is 0x100.

now, lets say for arguments sake that mem_destionation_mgr has a size of 36 bytes (24 being the first member which is the jpeg_destionation_mgr).

so after:

mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;

dest also has a value of 0x100.

At first this seems great.... mem_dest_ptr's first member which is also a jpeg_destination_mgr would get all of its values automatically assigned. But what about the rest of the members of mem_destination_mgr?

Remember that each member is given a physical location in memory starting at 0x100. Remember also that the last member of jpeg_destination_mgr is 0x114. But what about the extra member of mem_destionation_mgr? all of a sudden you've got those extra members using physical memory in 0x118, 0x11C, etc... In otherwords a 24 block of memory that was originally allocated, is now being used by a struct that needs 36. This means that those extra members are going to clobber what ever was allocated after that original jpeg_destination_mgr struct.

This problem also happens on lines 85, 108, 140, 172, 218, 256, and 318.

I'll post a diff fix once I finish.

Re: Memory clobbering problems in zm_jpeg.c?

Posted: Fri Jan 02, 2004 11:58 am
by zoneminder
Hi Ian,

Thanks for the in depth analysis, it's always good to have someone scrutinising the code.

In this case, unless I misunderstood, I think you might have missed an important bit of code. Where you say,

> at some point cinfo->dest was allocated enough memory for a
> jpeg_destionation_mgr.

The code in question is

<i>
if (cinfo->dest == NULL) { /* first time for this JPEG object? */
cinfo->dest = (struct jpeg_destination_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(mem_destination_mgr));
}
</i>

where the size of the memory allocated is specified by

<i>SIZEOF(mem_destination_mgr)</i>

which means that in fact the allocation is correct for the destination manager and it is only coerced into being a vanilla jpeg_dest_mgr pointer, which is still valid as the initial common parts of the structures are the same.

The memory destination manager code was based on that given in jdatadst.c and jdatasrc.c in the libjpeg distribution which are examples of alternative destination and source managers and which does almost exactly the same thing as zm_jpeg.c does.

As I said above, it's possible I've misunderstood something of your analysis and if thats's the case get right back!

Cheers,

Phil,

Re: Memory clobbering problems in zm_jpeg.c?

Posted: Fri Jan 02, 2004 9:42 pm
by snakebyte
Ahhh.. there it is... the more I looked at the code the more I thought that you must be correctly allocating the larger size, but I couldn't find where that was being done. That's a cool way to do non-oo inheritance. Thanks for the clarification.