From: Marcus M. <mei...@su...> - 2017-03-16 15:01:06
|
Hi, Thanks for the report! I have added if (prop_count >= INT_MAX/sizeof(MTPProperties)) { ptp_debug (params ,"prop_count %d is too large", prop_count); return 0; } to the function. Ciao, Marcus On Thu, Mar 16, 2017 at 01:21:40PM +0800, wyk...@gm... wrote: > Hi,I find an interger overflow bug in libmtp: > > OverFlow Point: > static inline int ptp_unpack_OPL (PTPParams *params, unsigned char* data, MTPProperties **pprops, unsigned int len) > | > |->uint32_t prop_count = dtoh32a(data); //read an uint32_t number from data > //... > props = malloc(prop_count * sizeof(MTPProperties)); //prop_count can be very large, if multiplied by sizeof(MTPProperties), overflow occurs > //... > for (i = 0; i < prop_count; i++) { > props[i].ObjectHandle = dtoh32a(data); > data += sizeof(uint32_t); > len -= sizeof(uint32_t); > > props[i].property = dtoh16a(data); > data += sizeof(uint16_t); > len -= sizeof(uint16_t); > > props[i].datatype = dtoh16a(data); > data += sizeof(uint16_t); > len -= sizeof(uint16_t); > > Trigger: > In example/track.c file, from main function, will go to ptp_unpack_OPL function: > > int main (int argc, char **argv) > | > |->dump_tracks(device, storage->id, 0); > | > |->files = LIBMTP_Get_Files_And_Folders(device, storageid, leaf); > | > |->file = LIBMTP_Get_Filemetadata(device, currentHandles.Handler[i]); > | > |->ret = ptp_object_want(params, fileid, PTPOBJECT_OBJECTINFO_LOADED|PTPOBJECT_MTPPROPLIST_LOADED, &ob); > | > |->if (params->device_flags & DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST) { //Through a android phone device, this check may be goto fallback, but I think there will some other ways to bypass. > want &= ~PTPOBJECT_MTPPROPLIST_LOADED; > goto fallback; > } > //... > ret = ptp_mtp_getobjectproplist_single (params, handle, &props, &nrofprops); > | > |->CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size)); //get data by PTP_DP_GETDATA transaction, and data is from portable device such as phone, so it's content is controllable. > | > |->... > > *nrofprops = ptp_unpack_OPL(params, data, props, size); > | > |->uint32_t prop_count = dtoh32a(data); > //... > props = malloc(prop_count * sizeof(MTPProperties)); > for (i = 0; i < prop_count; i++) { //This for loop will copy data to props, will lead to out-of-bounds write > //... > > Crash log: > Attempting to connect device(s) > Device 0 (VID=18d1 and PID=4ee2) is a Google Inc (for LG Electronics/Samsung) Nexus 4/5/7/10 (MTP+ADB). > mtp-tracks: Successfully connected > Android device detected, assigning default bug flags > Friendly name: (NULL) > [*]dump_tracks > [*]LIBMTP_Get_Files_And_Folders > [*]LIBMTP_Get_Filemetadata > [*]function ptp_object_want > [*]ptp_mtp_getobjectproplist_single > [*]size:221 > 010000800100000001dc0600010001000100000002dc040001300100000003dc040000000100000004dc080000000000000000000100000007dcffff064d00750073006900630000000100000009dcffff103100390037003000310031003200330054003200320033003000310032000000010000000bdc0600000000000100000041dc0a00010000000100010000000000000000000100000044dcffff064d007500730069006300000001000000e0dcffff00010000004edcffff103100390036003900310032003300310054003100390030003000300030000000 > [*]prop_count:2147483649 > [*]sizeof(MTPProperties):24 > [*]loop > [*]len:217 > [*]len:205 > [*]len:195 > [*]len:185 > [*]len:169 > [*]len:148 > [*]len:107 > [*]len:95 > [*]len:71 > [*]len:50 > [*]len:41 > [*]len:0 > [*]LIBMTP_Get_Filemetadata > [*]function ptp_object_want > > Program received signal SIGSEGV, Segmentation fault. > 0x00007ffff75ac204 in ?? () from /lib/x86_64-linux-gnu/libusb-0.1.so.4 > (gdb) bt > #0 0x00007ffff75ac204 in ?? () from /lib/x86_64-linux-gnu/libusb-0.1.so.4 > #1 0x00007ffff7bac31d in ptp_write_func.isra.9 () from /home/ubuntu/Android/Fuzz/libmtp-1.1.12/src/.libs/libmtp.so.9 > #2 0x00007ffff7bad8dd in ptp_usb_sendreq () from /home/ubuntu/Android/Fuzz/libmtp-1.1.12/src/.libs/libmtp.so.9 > #3 0x00007ffff7b9cb17 in ptp_transaction_new () from /home/ubuntu/Android/Fuzz/libmtp-1.1.12/src/.libs/libmtp.so.9 > #4 0x00007ffff7b9cd08 in ptp_transaction () from /home/ubuntu/Android/Fuzz/libmtp-1.1.12/src/.libs/libmtp.so.9 > #5 0x00007ffff7b9ea09 in ptp_getobjectinfo () from /home/ubuntu/Android/Fuzz/libmtp-1.1.12/src/.libs/libmtp.so.9 > #6 0x00007ffff7baaca4 in ptp_object_want () from /home/ubuntu/Android/Fuzz/libmtp-1.1.12/src/.libs/libmtp.so.9 > #7 0x00007ffff7b93cd1 in LIBMTP_Get_Filemetadata () from /home/ubuntu/Android/Fuzz/libmtp-1.1.12/src/.libs/libmtp.so.9 > #8 0x00007ffff7b93f84 in LIBMTP_Get_Files_And_Folders () from /home/ubuntu/Android/Fuzz/libmtp-1.1.12/src/.libs/libmtp.so.9 > #9 0x00000000004010b9 in dump_tracks () at tracks.c:89 > #10 0x0000000000400ec4 in main () at tracks.c:185 > > Fix: > Add check in ptp_unpack_OPL function: > > + if (prop_count >= UINT_MAX/sizeof(MTPProperties)) > + return 0; > props = malloc(prop_count * sizeof(MTPProperties)); > > > > wyk...@gm... > ------------------------------------------------------------------------------ > Check out the vibrant tech community on one of the world's most > engaging tech sites, Slashdot.org! http://sdm.link/slashdot > _______________________________________________ > Libmtp-discuss mailing list > Lib...@li... > https://lists.sourceforge.net/lists/listinfo/libmtp-discuss |