summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Meissner <marcus@jet.franken.de>2015-12-21 14:25:23 +0100
committerMarcus Meissner <marcus@jet.franken.de>2015-12-21 14:25:23 +0100
commit020964a20534e908b2d04a8e5bef8e6aafe338db (patch)
tree08bbc9d42ee9c8fc276a46013aa9534304f74ddb
parent1246cad6b917f1c686ce3ca5b9509d55e95265c2 (diff)
downloadlibgphoto2-020964a20534e908b2d04a8e5bef8e6aafe338db.tar.gz
check total datasize during uint16 unpacking
-rw-r--r--camlibs/ptp2/ptp-pack.c11
-rw-r--r--camlibs/ptp2/ptp.c25
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;