diff options
author | Marcus Meissner <marcus@jet.franken.de> | 2015-12-21 14:25:23 +0100 |
---|---|---|
committer | Marcus Meissner <marcus@jet.franken.de> | 2015-12-21 14:25:23 +0100 |
commit | 020964a20534e908b2d04a8e5bef8e6aafe338db (patch) | |
tree | 08bbc9d42ee9c8fc276a46013aa9534304f74ddb | |
parent | 1246cad6b917f1c686ce3ca5b9509d55e95265c2 (diff) | |
download | libgphoto2-020964a20534e908b2d04a8e5bef8e6aafe338db.tar.gz |
check total datasize during uint16 unpacking
-rw-r--r-- | camlibs/ptp2/ptp-pack.c | 11 | ||||
-rw-r--r-- | camlibs/ptp2/ptp.c | 25 |
2 files changed, 24 insertions, 12 deletions
diff --git a/camlibs/ptp2/ptp-pack.c b/camlibs/ptp2/ptp-pack.c index 1894aed4d..7b5d37470 100644 --- a/camlibs/ptp2/ptp-pack.c +++ b/camlibs/ptp2/ptp-pack.c @@ -299,7 +299,7 @@ ptp_pack_uint32_t_array(PTPParams *params, uint32_t *array, uint32_t arraylen, u } static inline uint32_t -ptp_unpack_uint16_t_array(PTPParams *params, unsigned char* data, uint16_t offset, uint16_t **array) +ptp_unpack_uint16_t_array(PTPParams *params, unsigned char* data, unsigned int offset, unsigned int datalen, uint16_t **array) { uint32_t n, i=0; @@ -309,6 +309,10 @@ ptp_unpack_uint16_t_array(PTPParams *params, unsigned char* data, uint16_t offse return 0; if (!n) return 0; + if (offset + sizeof(uint32_t) > datalen) + return 0; + if (offset + sizeof(uint32_t)*(n+1) > datalen) + return 0; *array = malloc (n*sizeof(uint16_t)); for (i=0;i<n;i++) (*array)[i]=dtoh16a(&data[offset+(sizeof(uint16_t)*(i+2))]); @@ -345,23 +349,28 @@ ptp_unpack_DI (PTPParams *params, unsigned char* data, PTPDeviceInfo *di, unsign dtoh16a(&data[PTP_di_FunctionalMode+totallen]); di->OperationsSupported_len = ptp_unpack_uint16_t_array(params, data, PTP_di_OperationsSupported+totallen, + datalen, &di->OperationsSupported); totallen=totallen+di->OperationsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); di->EventsSupported_len = ptp_unpack_uint16_t_array(params, data, PTP_di_OperationsSupported+totallen, + datalen, &di->EventsSupported); totallen=totallen+di->EventsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); di->DevicePropertiesSupported_len = ptp_unpack_uint16_t_array(params, data, PTP_di_OperationsSupported+totallen, + datalen, &di->DevicePropertiesSupported); totallen=totallen+di->DevicePropertiesSupported_len*sizeof(uint16_t)+sizeof(uint32_t); di->CaptureFormats_len = ptp_unpack_uint16_t_array(params, data, PTP_di_OperationsSupported+totallen, + datalen, &di->CaptureFormats); totallen=totallen+di->CaptureFormats_len*sizeof(uint16_t)+sizeof(uint32_t); di->ImageFormats_len = ptp_unpack_uint16_t_array(params, data, PTP_di_OperationsSupported+totallen, + datalen, &di->ImageFormats); totallen=totallen+di->ImageFormats_len*sizeof(uint16_t)+sizeof(uint32_t); di->Manufacturer = ptp_unpack_string(params, data, diff --git a/camlibs/ptp2/ptp.c b/camlibs/ptp2/ptp.c index 00877c887..4ceb5da40 100644 --- a/camlibs/ptp2/ptp.c +++ b/camlibs/ptp2/ptp.c @@ -2596,10 +2596,11 @@ ptp_canon_getchanges (PTPParams* params, uint16_t** props, uint32_t* propnum) { PTPContainer ptp; unsigned char *data; + unsigned int size; PTP_CNT_INIT(ptp, PTP_OC_CANON_GetChanges); - CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, NULL)); - *propnum=ptp_unpack_uint16_t_array(params,data,0,props); + CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size)); + *propnum=ptp_unpack_uint16_t_array(params,data,0,size,props); free(data); return PTP_RC_OK; } @@ -2778,10 +2779,10 @@ ptp_sony_get_vendorpropcodes (PTPParams* params, uint16_t **props, unsigned int return PTP_RC_OK; } - psize1 = ptp_unpack_uint16_t_array(params,xdata+2,0,&props1); + psize1 = ptp_unpack_uint16_t_array (params, xdata+2, 0, xsize, &props1); ptp_debug (params, "xsize %d, got size %d\n", xsize, psize1*2 + 2 + 4); if (psize1*2 + 2 + 4 < xsize) { - psize2 = ptp_unpack_uint16_t_array(params,xdata+2+psize1*2+4,0,&props2); + psize2 = ptp_unpack_uint16_t_array(params,xdata+2+psize1*2+4, 0, xsize, &props2); } *size = psize1+psize2; *props = malloc((psize1+psize2)*sizeof(uint16_t)); @@ -3079,13 +3080,14 @@ uint16_t ptp_nikon_get_vendorpropcodes (PTPParams* params, uint16_t **props, unsigned int *size) { PTPContainer ptp; - unsigned char *data; + unsigned char *data = NULL; + unsigned int xsize = 0; *props = NULL; *size = 0; PTP_CNT_INIT(ptp, PTP_OC_NIKON_GetVendorPropCodes); - CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, NULL)); - *size = ptp_unpack_uint16_t_array(params,data,0,props); + CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &xsize)); + *size = ptp_unpack_uint16_t_array(params,data,0,xsize,props); free (data); return PTP_RC_OK; } @@ -3442,11 +3444,12 @@ ptp_mtp_getobjectpropssupported (PTPParams* params, uint16_t ofc, uint32_t *propnum, uint16_t **props ) { PTPContainer ptp; - unsigned char *data; + unsigned char *data = NULL; + unsigned int xsize = 0; PTP_CNT_INIT(ptp, PTP_OC_MTP_GetObjectPropsSupported, ofc); - CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, NULL)); - *propnum=ptp_unpack_uint16_t_array(params,data,0,props); + CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &xsize)); + *propnum=ptp_unpack_uint16_t_array (params, data, 0, xsize, props); free(data); return PTP_RC_OK; } @@ -3554,7 +3557,7 @@ ptp_mtp_getobjectreferences (PTPParams* params, uint32_t handle, uint32_t** ohAr *arraylen = 0; *ohArray = NULL; } else { - *arraylen = ptp_unpack_uint32_t_array(params, data , 0, ohArray); + *arraylen = ptp_unpack_uint32_t_array(params, data , 0, size, ohArray); } free(data); return PTP_RC_OK; |