[libvirt] [PATCH v2] esx: Extend esxVI_CURL_Download for partial downloads
Matthias Bolte
matthias.bolte at googlemail.com
Mon Jul 9 17:24:59 UTC 2012
2012/7/8 Doug Goldstein <cardoe at gentoo.org>:
> On Sun, Jul 8, 2012 at 5:44 AM, Matthias Bolte
> <matthias.bolte at googlemail.com> wrote:
>> Also ensure that the virBuffer used to store the downloaded data
>> does not overflow.
>> ---
>>
>> v2:
>> - Ensure that the used virBuffer dos not overflow.
>>
>> src/esx/esx_driver.c | 2 +-
>> src/esx/esx_vi.c | 62 +++++++++++++++++++++++++++++++++++++++++++------
>> src/esx/esx_vi.h | 3 +-
>> 3 files changed, 57 insertions(+), 10 deletions(-)
>> -esxVI_CURL_WriteBuffer(char *data, size_t size, size_t nmemb, void *buffer)
>> +esxVI_CURL_WriteBuffer(char *data, size_t size, size_t nmemb, void *userdata)
>> {
>> + virBufferPtr buffer = userdata;
>> +
>> if (buffer != NULL) {
>> - virBufferAdd((virBufferPtr) buffer, data, size * nmemb);
>> + /*
>> + * Using a virBuffer to store the download data limits the downloadable
>> + * size. This is no problem as esxVI_CURL_Download and esxVI_CURL_Perform
>> + * are meant to download small things such as VMX files, VMDK metadata
>> + * files and SOAP responses.
>> + */
>> + if (virBufferUse(buffer) > UINT32_MAX / 2) {
>> + return 0;
>> + }
>
> This could never be true since the type would have already resulted in
> an overflow and therefore would be less than UINT32_MAX / 2 (which is
> equivalent to INT32_MAX).
That's not true, virBufferUse returns unsigned int. Also virBuffer
stores it's size internally as unsigned int. I just looked it up
again. But then there is a bug in virBufferGrow that uses an
intermediate int variable to store the new size. This limits a
virBuffer to hold at most 2GB. Also virBuffer doesn't do any overflow
checks internally.
> Something like the below would ensure that
> you are always within the bounds of your type :
>
> if ((size * nmemb) <= (INT32_MAX - virBufferUse(buffer)) {
> virBufferAdd(...)
> return size * nmemb;
> }
Therefore this isn't safe either. virBufferAdd can grow the buffer
beyond the required size, for INT32_MAX it'll probably overflow. I'll
use INT32_MAX / 2 as the limit here, because now I assume that a
virBuffer can safely hold at most INT32_MAX / 2. This is the same
pattern as with UINT32_MAX / 2 where I assumed a virBuffer would be
unsigned int clean in it's internals.
>> @@ -365,9 +379,33 @@ esxVI_CURL_Download(esxVI_CURL *curl, const char *url, char **content)
>> return -1;
>> }
>>
>> + if (length != NULL && *length > 0) {
>> + /*
>> + * Using a virBuffer to store the download data limits the downloadable
>> + * size. This is no problem as esxVI_CURL_Download is meant to download
>> + * small things such as VMX of VMDK metadata files.
>> + */
>> + if (*length > UINT32_MAX / 2) {
>
> Use INT32_MAX
I'll use INT32_MAX / 2 for the reason explain above.
--
Matthias Bolte
http://photron.blogspot.com
More information about the libvir-list
mailing list