From babca445ffa9f7af6f5e1deb78476754c484a2b1 Mon Sep 17 00:00:00 2001 From: pwpiwi Date: Tue, 8 May 2018 07:54:49 +0200 Subject: [PATCH] rework of GetFromBigBuf() (#597) * this should fix crashes reported in issue #497 * don't allow receiver thread to write directly into arbitrary main thread's memory * instead use cmdBuffer[] for CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K as well * add timeout and warning options to GetFromBigBuf(), same as in WaitForResponseTimeoutW() * move GetFromBigBuf() from data.c to comms.c * remove data.c and data.h --- client/Makefile | 1 - client/cmddata.c | 12 +++----- client/cmdhf.c | 7 ++--- client/cmdhf14a.c | 1 - client/cmdhf14b.c | 1 - client/cmdhf15.c | 1 - client/cmdhficlass.c | 7 ++--- client/cmdhflegic.c | 7 ++--- client/cmdhflist.c | 1 - client/cmdhfmfu.c | 4 +-- client/cmdhw.c | 6 +--- client/cmdlf.c | 1 - client/cmdlfcotag.c | 6 ++-- client/cmdlfem4x.c | 4 +-- client/cmdlfhitag.c | 7 ++--- client/cmdlfio.c | 1 - client/cmdlft55xx.c | 4 +-- client/cmdlfti.c | 5 ++-- client/cmdmain.c | 1 - client/cmdscript.c | 1 - client/comms.c | 66 ++++++++++++++++++++++++++++++++++++++------ client/comms.h | 1 + client/data.c | 25 ----------------- client/data.h | 23 --------------- client/mifarehost.h | 2 +- client/util.c | 1 - client/util.h | 7 +++++ 27 files changed, 87 insertions(+), 116 deletions(-) delete mode 100644 client/data.c delete mode 100644 client/data.h diff --git a/client/Makefile b/client/Makefile index 883f3b6f..d4ac33b2 100644 --- a/client/Makefile +++ b/client/Makefile @@ -105,7 +105,6 @@ CMDSRCS = crapto1/crapto1.c\ crc64.c \ iso14443crc.c \ iso15693tools.c \ - data.c \ graph.c \ ui.c \ cmddata.c \ diff --git a/client/cmddata.c b/client/cmddata.c index 9bfe58f9..471665b7 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -12,7 +12,6 @@ #include // also included in util.h #include #include // for CmdNorm INT_MIN && INT_MAX -#include "data.h" // also included in util.h #include "cmddata.h" #include "util.h" #include "cmdmain.h" @@ -591,8 +590,7 @@ int CmdBitsamples(const char *Cmd) int cnt = 0; uint8_t got[12288]; - GetFromBigBuf(got,sizeof(got),0); - WaitForResponse(CMD_ACK,NULL); + GetFromBigBuf(got, sizeof(got), 0 , NULL, -1, false); for (int j = 0; j < sizeof(got); j++) { for (int k = 0; k < 8; k++) { @@ -1131,8 +1129,7 @@ int CmdHexsamples(const char *Cmd) return 0; } - GetFromBigBuf(got,requested,offset); - WaitForResponse(CMD_ACK,NULL); + GetFromBigBuf(got, requested, offset, NULL, -1, false); i = 0; for (j = 0; j < requested; j++) { @@ -1200,10 +1197,9 @@ int getSamples(int n, bool silent) n = sizeof(got); if (!silent) PrintAndLog("Reading %d bytes from device memory\n", n); - GetFromBigBuf(got,n,0); - if (!silent) PrintAndLog("Data fetched"); UsbCommand response; - WaitForResponse(CMD_ACK, &response); + GetFromBigBuf(got, n, 0, &response, -1, false); + if (!silent) PrintAndLog("Data fetched"); uint8_t bits_per_sample = 8; //Old devices without this feature would send 0 at arg[0] diff --git a/client/cmdhf.c b/client/cmdhf.c index 82313ae0..4a672255 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -14,7 +14,6 @@ #include #include "proxmark3.h" #include "util.h" -#include "data.h" #include "ui.h" #include "iso14443crc.h" #include "parity.h" @@ -497,8 +496,7 @@ int CmdHFList(const char *Cmd) trace = malloc(USB_CMD_DATA_SIZE); // Query for the size of the trace UsbCommand response; - GetFromBigBuf(trace, USB_CMD_DATA_SIZE, 0); - WaitForResponse(CMD_ACK, &response); + GetFromBigBuf(trace, USB_CMD_DATA_SIZE, 0, &response, -1, false); traceLen = response.arg[2]; if (traceLen > USB_CMD_DATA_SIZE) { uint8_t *p = realloc(trace, traceLen); @@ -508,8 +506,7 @@ int CmdHFList(const char *Cmd) return 2; } trace = p; - GetFromBigBuf(trace, traceLen, 0); - WaitForResponse(CMD_ACK, NULL); + GetFromBigBuf(trace, traceLen, 0, NULL, -1, false); } } diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 480923d6..4684ae29 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -20,7 +20,6 @@ #include "util.h" #include "util_posix.h" #include "iso14443crc.h" -#include "data.h" #include "proxmark3.h" #include "ui.h" #include "cmdparser.h" diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index 36932cbd..bae40c09 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -15,7 +15,6 @@ #include #include "iso14443crc.h" #include "proxmark3.h" -#include "data.h" #include "graph.h" #include "util.h" #include "ui.h" diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 8ddbea89..570a0420 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -28,7 +28,6 @@ #include #include "proxmark3.h" -#include "data.h" #include "graph.h" #include "ui.h" #include "util.h" diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index d42f7eef..e99c3285 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -16,7 +16,6 @@ #include #include #include "iso14443crc.h" // Can also be used for iClass, using 0xE012 as CRC-type -#include "data.h" #include "proxmark3.h" #include "ui.h" #include "cmdparser.h" @@ -750,8 +749,7 @@ int CmdHFiClassReader_Dump(const char *Cmd) { blocksRead = (sizeof(tag_data)/8) - blockno; } // response ok - now get bigbuf content of the dump - GetFromBigBuf(tag_data+(blockno*8), blocksRead*8, startindex); - WaitForResponse(CMD_ACK,NULL); + GetFromBigBuf(tag_data+(blockno*8), blocksRead*8, startindex, NULL, -1, false); size_t gotBytes = blocksRead*8 + blockno*8; // try AA2 @@ -793,8 +791,7 @@ int CmdHFiClassReader_Dump(const char *Cmd) { blocksRead = (sizeof(tag_data) - gotBytes)/8; } // get dumped data from bigbuf - GetFromBigBuf(tag_data+gotBytes, blocksRead*8, startindex); - WaitForResponse(CMD_ACK,NULL); + GetFromBigBuf(tag_data+gotBytes, blocksRead*8, startindex, NULL, -1, false); gotBytes += blocksRead*8; } else { //field is still on - turn it off... diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index c9f3485e..9c9613ae 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -12,7 +12,6 @@ #include #include #include "proxmark3.h" -#include "data.h" #include "ui.h" #include "cmdparser.h" #include "cmdhflegic.h" @@ -64,8 +63,7 @@ int CmdLegicDecode(const char *Cmd) char token_type[4]; // copy data from proxmark into buffer - GetFromBigBuf(data_buf,sizeof(data_buf),0); - WaitForResponse(CMD_ACK,NULL); + GetFromBigBuf(data_buf, sizeof(data_buf), 0, NULL, -1, false); // Output CDF System area (9 bytes) plus remaining header area (12 bytes) @@ -294,8 +292,7 @@ int CmdLegicSave(const char *Cmd) return -1; } - GetFromBigBuf(got,requested,offset); - WaitForResponse(CMD_ACK,NULL); + GetFromBigBuf(got, requested, offset, NULL, -1, false); for (int j = 0; j < requested; j += 8) { fprintf(f, "%02x %02x %02x %02x %02x %02x %02x %02x\n", diff --git a/client/cmdhflist.c b/client/cmdhflist.c index cf69abba..c87aa237 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -16,7 +16,6 @@ #include #include #include "util.h" -#include "data.h" #include "ui.h" #include "iso14443crc.h" #include "parity.h" diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 63c41728..ac76c8dd 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -22,7 +22,6 @@ #include "mifare.h" #include "util.h" #include "protocols.h" -#include "data.h" #define MAX_UL_BLOCKS 0x0f #define MAX_ULC_BLOCKS 0x2b @@ -1325,8 +1324,7 @@ int CmdHF14AMfUDump(const char *Cmd){ PrintAndLog("Data exceeded Buffer size!"); bufferSize = sizeof(data); } - GetFromBigBuf(data, bufferSize, startindex); - WaitForResponse(CMD_ACK,NULL); + GetFromBigBuf(data, bufferSize, startindex, NULL, -1, false); Pages = bufferSize/4; // Load lock bytes. diff --git a/client/cmdhw.c b/client/cmdhw.c index 8f7243ad..4ede122f 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -18,7 +18,6 @@ #include "cmdhw.h" #include "cmdmain.h" #include "cmddata.h" -#include "data.h" /* low-level hardware control */ @@ -429,13 +428,10 @@ int CmdVersion(const char *Cmd) int CmdStatus(const char *Cmd) { - uint8_t speed_test_buffer[USB_CMD_DATA_SIZE]; - sample_buf = speed_test_buffer; - clearCommandBuffer(); UsbCommand c = {CMD_STATUS}; SendCommand(&c); - if (!WaitForResponseTimeout(CMD_ACK,&c,1900)) { + if (!WaitForResponseTimeout(CMD_ACK, &c, 1900)) { PrintAndLog("Status command failed. USB Speed Test timed out"); } return 0; diff --git a/client/cmdlf.c b/client/cmdlf.c index 51e89581..285d377a 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -22,7 +22,6 @@ #include "graph.h" // for graph data #include "cmdparser.h" // for getting cli commands included in cmdmain.h #include "cmdmain.h" // for sending cmds to device -#include "data.h" // for GetFromBigBuf #include "cmddata.h" // for `lf search` #include "cmdlfawid.h" // for awid menu #include "cmdlfem4x.h" // for em4x menu diff --git a/client/cmdlfcotag.c b/client/cmdlfcotag.c index 6d035e8c..ca163480 100644 --- a/client/cmdlfcotag.c +++ b/client/cmdlfcotag.c @@ -13,7 +13,6 @@ #include "proxmark3.h" #include "ui.h" #include "cmddata.h" -#include "data.h" #include "cmdlfcotag.h" #include "lfdemod.h" #include "usb_cmd.h" @@ -99,10 +98,9 @@ int CmdCOTAGRead(const char *Cmd) { getSamples(0, true); break; } case 1: { - GetFromBigBuf(DemodBuffer, COTAG_BITS, 0); - DemodBufferLen = COTAG_BITS; UsbCommand response; - if ( !WaitForResponseTimeout(CMD_ACK, &response, 1000) ) { + DemodBufferLen = COTAG_BITS; + if (!GetFromBigBuf(DemodBuffer, COTAG_BITS, 0, &response, 1000, true)) { PrintAndLog("timeout while waiting for reply."); return -1; } diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 6d562be0..ff2ae5b0 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -15,7 +15,6 @@ #include "proxmark3.h" #include "ui.h" #include "util.h" -#include "data.h" #include "graph.h" #include "cmdparser.h" #include "cmddata.h" @@ -804,8 +803,7 @@ int usage_lf_em_read(void) { bool downloadSamplesEM() { // 8 bit preamble + 32 bit word response (max clock (128) * 40bits = 5120 samples) uint8_t got[6000]; - GetFromBigBuf(got, sizeof(got), 0); - if ( !WaitForResponseTimeout(CMD_ACK, NULL, 4000) ) { + if (!GetFromBigBuf(got, sizeof(got), 0, NULL, 4000, true)) { PrintAndLog("command execution time out"); return false; } diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 73c02a14..26ba9238 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -11,7 +11,6 @@ #include #include #include -#include "data.h" #include "proxmark3.h" #include "ui.h" #include "cmdparser.h" @@ -34,8 +33,7 @@ int CmdLFHitagList(const char *Cmd) // Query for the actual size of the trace UsbCommand response; - GetFromBigBuf(got, USB_CMD_DATA_SIZE, 0); - WaitForResponse(CMD_ACK, &response); + GetFromBigBuf(got, USB_CMD_DATA_SIZE, 0, &response, -1, false); uint16_t traceLen = response.arg[2]; if (traceLen > USB_CMD_DATA_SIZE) { uint8_t *p = realloc(got, traceLen); @@ -45,8 +43,7 @@ int CmdLFHitagList(const char *Cmd) return 2; } got = p; - GetFromBigBuf(got, traceLen, 0); - WaitForResponse(CMD_ACK,NULL); + GetFromBigBuf(got, traceLen, 0, NULL, -1, false); } PrintAndLog("recorded activity (TraceLen = %d bytes):"); diff --git a/client/cmdlfio.c b/client/cmdlfio.c index 4ccd5538..f2f2df06 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -15,7 +15,6 @@ #include #include "cmdlfio.h" #include "proxmark3.h" -#include "data.h" #include "graph.h" #include "ui.h" #include "cmdparser.h" diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index c5a6dd3f..a9fbb71e 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -21,7 +21,6 @@ #include "cmdlf.h" #include "cmdlft55xx.h" #include "util.h" -#include "data.h" #include "lfdemod.h" #include "cmdhf14a.h" //for getTagInfo #include "protocols.h" @@ -1355,8 +1354,7 @@ int CmdResetRead(const char *Cmd) { } uint8_t got[BIGBUF_SIZE-1]; - GetFromBigBuf(got,sizeof(got),0); - WaitForResponse(CMD_ACK,NULL); + GetFromBigBuf(got, sizeof(got), 0, NULL, -1 , 0); setGraphBuf(got, sizeof(got)); return 1; } diff --git a/client/cmdlfti.c b/client/cmdlfti.c index 5dae9c0e..7e0af94b 100644 --- a/client/cmdlfti.c +++ b/client/cmdlfti.c @@ -8,16 +8,17 @@ // Low frequency TI commands //----------------------------------------------------------------------------- +#include "cmdlfti.h" + #include #include #include #include "crc16.h" #include "proxmark3.h" -#include "data.h" #include "ui.h" #include "graph.h" #include "cmdparser.h" -#include "cmdlfti.h" +#include "util.h" static int CmdHelp(const char *Cmd); diff --git a/client/cmdmain.c b/client/cmdmain.c index a45e3430..c3b46145 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -17,7 +17,6 @@ #include #include "cmdparser.h" #include "proxmark3.h" -#include "data.h" #include "usb_cmd.h" #include "ui.h" #include "cmdhf.h" diff --git a/client/cmdscript.c b/client/cmdscript.c index 0d19f496..7b0e9000 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -17,7 +17,6 @@ #include "proxmark3.h" #include "scripting.h" -#include "data.h" #include "ui.h" #include "graph.h" #include "cmdparser.h" diff --git a/client/comms.c b/client/comms.c index 97d58ef9..b62f6fda 100644 --- a/client/comms.c +++ b/client/comms.c @@ -15,7 +15,6 @@ #include "uart.h" #include "ui.h" #include "common.h" -#include "data.h" #include "util_posix.h" // Declare globals. @@ -173,6 +172,10 @@ int getCommand(UsbCommand* response) } +//---------------------------------------------------------------------------------- +// Entry point into our code: called whenever we received a packet over USB. +// Handle debug commands directly, store all other commands in circular buffer. +//---------------------------------------------------------------------------------- static void UsbCommandReceived(UsbCommand *UC) { switch(UC->cmd) { @@ -191,13 +194,6 @@ static void UsbCommandReceived(UsbCommand *UC) return; } break; - case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: { - // FIXME: This does unsanitised copies into memory when we don't know - // the size of the buffer. - memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]); - return; - } break; - default: storeCommand(UC); break; @@ -242,6 +238,58 @@ __attribute__((force_align_arg_pointer)) } + +/** + * Data transfer from Proxmark to client. This method times out after + * ms_timeout milliseconds. + * @brief GetFromBigBuf + * @param dest Destination address for transfer + * @param bytes number of bytes to be transferred + * @param start_index offset into Proxmark3 BigBuf[] + * @param response struct to copy last command (CMD_ACK) into + * @param ms_timeout timeout in milliseconds + * @param show_warning display message after 2 seconds + * @return true if command was returned, otherwise false + */ +bool GetFromBigBuf(uint8_t *dest, int bytes, int start_index, UsbCommand *response, size_t ms_timeout, bool show_warning) +{ + UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}}; + SendCommand(&c); + + uint64_t start_time = msclock(); + + UsbCommand resp; + if (response == NULL) { + response = &resp; + } + + int bytes_completed = 0; + while(true) { + if (getCommand(response)) { + if (response->cmd == CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K) { + int copy_bytes = MIN(bytes - bytes_completed, response->arg[1]); + memcpy(dest + response->arg[0], response->d.asBytes, copy_bytes); + bytes_completed += copy_bytes; + } else if (response->cmd == CMD_ACK) { + return true; + } + } + + if (msclock() - start_time > ms_timeout) { + break; + } + + if (msclock() - start_time > 2000 && show_warning) { + PrintAndLog("Waiting for a response from the proxmark..."); + PrintAndLog("You can cancel this operation by pressing the pm3 button"); + show_warning = false; + } + } + + return false; +} + + /** * Waits for a certain response type. This method waits for a maximum of * ms_timeout milliseconds for a specified response command. @@ -249,7 +297,7 @@ __attribute__((force_align_arg_pointer)) * @param cmd command to wait for, or CMD_UNKNOWN to take any command. * @param response struct to copy received command into. * @param ms_timeout - * @param show_warning + * @param show_warning display message after 2 seconds * @return true if command was returned, otherwise false */ bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeout, bool show_warning) { diff --git a/client/comms.h b/client/comms.h index 616f7ddb..111677ad 100644 --- a/client/comms.h +++ b/client/comms.h @@ -44,5 +44,6 @@ void clearCommandBuffer(); bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeout, bool show_warning); bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout); bool WaitForResponse(uint32_t cmd, UsbCommand* response); +bool GetFromBigBuf(uint8_t *dest, int bytes, int start_index, UsbCommand *response, size_t ms_timeout, bool show_warning); #endif // COMMS_H_ diff --git a/client/data.c b/client/data.c deleted file mode 100644 index 4d7d1e41..00000000 --- a/client/data.c +++ /dev/null @@ -1,25 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) 2010 iZsh -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// Data utilities -//----------------------------------------------------------------------------- - -#include -#include -#include "data.h" -#include "ui.h" -#include "proxmark3.h" -#include "cmdmain.h" - -uint8_t* sample_buf; - -void GetFromBigBuf(uint8_t *dest, int bytes, int start_index) -{ - sample_buf = dest; - UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}}; - SendCommand(&c); -} diff --git a/client/data.h b/client/data.h deleted file mode 100644 index 7d85e1f1..00000000 --- a/client/data.h +++ /dev/null @@ -1,23 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) 2010 iZsh -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// Data utilities -//----------------------------------------------------------------------------- - -#ifndef DATA_H__ -#define DATA_H__ - -#include - -#define FILE_PATH_SIZE 1000 - -extern uint8_t* sample_buf; -#define arraylen(x) (sizeof(x)/sizeof((x)[0])) - -void GetFromBigBuf(uint8_t *dest, int bytes, int start_index); - -#endif diff --git a/client/mifarehost.h b/client/mifarehost.h index 457a879f..6a37fef1 100644 --- a/client/mifarehost.h +++ b/client/mifarehost.h @@ -13,8 +13,8 @@ #include #include -#include "data.h" #include "crapto1/crapto1.h" +#include "util.h" // defaults // timeout in units. (ms * 106)/10 or us*0.0106 diff --git a/client/util.c b/client/util.c index 5dc9a455..4f84e3b5 100644 --- a/client/util.c +++ b/client/util.c @@ -16,7 +16,6 @@ #include #include #include -#include "data.h" #ifdef _WIN32 #include diff --git a/client/util.h b/client/util.h index 2e64d7ca..878938f4 100644 --- a/client/util.h +++ b/client/util.h @@ -24,10 +24,17 @@ #ifndef MAX # define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif +#ifndef arraylen +#define arraylen(x) (sizeof(x)/sizeof((x)[0])) +#endif #define EVEN 0 #define ODD 1 +#ifndef FILE_PATH_SIZE +#define FILE_PATH_SIZE 2000 +#endif + extern int ukbhit(void); extern void AddLogLine(char *fileName, char *extData, char *c); -- 2.39.2