From b398a9ab735ea63ffd17d7c063503521460ed83f Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Thu, 26 Oct 2017 11:51:03 +0200 Subject: irecv_send_buffer: Fix DFU file upload failure due to oversized last packet In DFU mode the last packet contains the checksum for the transferred data (and 12 additional bytes, total 16 bytes). If the last packet is larger than 2032 bytes we would send a packet that is larger than the packet size of 2048 bytes which would make the file upload fail. This is especially the case for the iOS 11.0.x iBSS for the iPhone 8. With this commit the size is checked and if it would be larger than the packet size, we split the data portion and the checksum into two separate packets. It might even be safe to always split the last packet into data and checksum, but until this is proven to work with all (especially older devices) we just split when we detect the oversized packet for now. --- src/libirecovery.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/libirecovery.c b/src/libirecovery.c index 69f1d90..a255d78 100644 --- a/src/libirecovery.c +++ b/src/libirecovery.c @@ -1760,6 +1760,15 @@ IRECV_API irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* dfu_hash_step(h1, buffer[i*packet_size + j]); } if (i+1 == packets) { + if (size+16 > packet_size) { + bytes = irecv_usb_control_transfer(client, 0x21, 1, i, 0, &buffer[i * packet_size], size, USB_TIMEOUT); + if (bytes != size) { + return IRECV_E_USB_UPLOAD; + } + count += size; + size = 0; + } + for (j = 0; j < 2; j++) { dfu_hash_step(h1, dfu_xbuf[j*6 + 0]); dfu_hash_step(h1, dfu_xbuf[j*6 + 1]); @@ -1770,7 +1779,9 @@ IRECV_API irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* } char* newbuf = (char*)malloc(size + 16); - memcpy(newbuf, &buffer[i * packet_size], size); + if (size > 0) { + memcpy(newbuf, &buffer[i * packet_size], size); + } memcpy(newbuf+size, dfu_xbuf, 12); newbuf[size+12] = h1 & 0xFF; newbuf[size+13] = (h1 >> 8) & 0xFF; -- cgit v1.1-32-gdbae