PN533: Abuse the overflow bug to restore USB descriptors in one go

This commit is contained in:
Philippe Teuwen 2017-04-20 08:35:13 +02:00
parent 38164c49ef
commit 767abe50e2

View file

@ -185,7 +185,8 @@ static void pn533_fix_usbdesc(nfc_device *pnd)
btXramUsbDesc = (uint8_t *)btXramUsbDesc_asklogo; btXramUsbDesc = (uint8_t *)btXramUsbDesc_asklogo;
szXramUsbDesc = sizeof(btXramUsbDesc_asklogo); szXramUsbDesc = sizeof(btXramUsbDesc_asklogo);
} }
if (szXramUsbDesc == 0) #define MAXSZXRAMUSBDESC 61
if ((szXramUsbDesc == 0) || (MAXSZXRAMUSBDESC > 61))
return; return;
/* /*
// Debug routine to check if corruption occurred: // Debug routine to check if corruption occurred:
@ -209,26 +210,17 @@ static void pn533_fix_usbdesc(nfc_device *pnd)
} }
} }
*/ */
// Restore USB descriptors // Abuse the overflow bug to restore USB descriptors in one go
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO, "%s", "Fixing USB descriptors corruption"); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO, "%s", "Fixing USB descriptors corruption");
// Don't write more regs at once or it will trigger the bug and corrupt what we're busy reading! uint8_t abtCmdWR[19 + MAXSZXRAMUSBDESC] = { GetFirmwareVersion };
uint8_t abtCmdWR[] = { WriteRegister, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; for (uint8_t i = 0; i < szXramUsbDesc; i++) {
size_t szCmdWR = sizeof(abtCmdWR); abtCmdWR[i + 19] = btXramUsbDesc[i];
uint8_t nWRreg = ((sizeof(abtCmdWR) - 1) / 3);
uint8_t abtRxWR[1];
for (uint8_t i = 0x19, j = 0; i < 0x19 + szXramUsbDesc;) {
if (j == szXramUsbDesc)
break;
for (uint8_t k = 0; (k < nWRreg) && (j < szXramUsbDesc); k++) {
abtCmdWR[(3 * k) + 2] = i++;
abtCmdWR[(3 * k) + 3] = btXramUsbDesc[j++];
} }
if (j == szXramUsbDesc) size_t szCmdWR = sizeof(abtCmdWR);
szCmdWR = ((((szXramUsbDesc - 1) % nWRreg) + 1) * 3) + 1; uint8_t abtRxWR[4];
if (pn53x_transceive(pnd, abtCmdWR, szCmdWR, abtRxWR, sizeof(abtRxWR), -1) < 0) { if (pn53x_transceive(pnd, abtCmdWR, szCmdWR, abtRxWR, sizeof(abtRxWR), -1) < 0) {
return; // void return; // void
} }
}
DRIVER_DATA(pnd)->possibly_corrupted_usbdesc = false; DRIVER_DATA(pnd)->possibly_corrupted_usbdesc = false;
} }