From d295b9219275f24a984e58474a1b23b832d2a8f6 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Fri, 18 Mar 2016 21:01:36 +0100 Subject: [PATCH] ensure usb_msg_hdr contains raw message length we want to ensure that the length of every (current or future) message can be determined by looking at cardemu_usb_msg_hdr.msg_len, rather than having a length that is relative to the respective specific command. --- firmware/src_simtrace/card_emu.c | 8 +++++--- firmware/src_simtrace/cardemu_prot.h | 14 ++++++++++---- firmware/src_simtrace/mode_cardemu.c | 2 +- firmware/test/card_emu_tests.c | 9 +++++---- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/firmware/src_simtrace/card_emu.c b/firmware/src_simtrace/card_emu.c index 83769437..8e9fef8c 100644 --- a/firmware/src_simtrace/card_emu.c +++ b/firmware/src_simtrace/card_emu.c @@ -174,7 +174,8 @@ static void flush_rx_buffer(struct card_handle *ch) /* store length of data payload fild in header */ rd = (struct cardemu_usb_msg_rx_data *) rctx->data; - rd->hdr.data_len = rctx->idx; + rd->data_len = rctx->idx; + rd->hdr.msg_len = sizeof(*rd) + rd->data_len; llist_add_tail(&rctx->list, &ch->usb_tx_queue); req_ctx_set_state(rctx, RCTX_S_USB_TX_PENDING); @@ -229,7 +230,8 @@ static void flush_pts(struct card_handle *ch) ptsi = (struct cardemu_usb_msg_pts_info *) rctx->data; ptsi->hdr.msg_type = CEMU_USB_MSGT_DO_PTS; - ptsi->hdr.data_len = serialize_pts(ptsi->req, ch->pts.req); + ptsi->hdr.msg_len = sizeof(*ptsi); + ptsi->pts_len = serialize_pts(ptsi->req, ch->pts.req); serialize_pts(ptsi->resp, ch->pts.resp); llist_add_tail(&rctx->list, &ch->usb_tx_queue); @@ -701,7 +703,7 @@ static int tx_byte_tpdu(struct card_handle *ch) } /* check if the buffer has now been fully transmitted */ - if ((rctx->idx >= td->hdr.data_len) || + if ((rctx->idx >= td->data_len) || (td->data + rctx->idx >= rctx->data + rctx->tot_len)) { if (td->flags & CEMU_DATA_F_PB_AND_RX) { /* we have just sent the procedure byte and now diff --git a/firmware/src_simtrace/cardemu_prot.h b/firmware/src_simtrace/cardemu_prot.h index da490344..1a8c213a 100644 --- a/firmware/src_simtrace/cardemu_prot.h +++ b/firmware/src_simtrace/cardemu_prot.h @@ -43,7 +43,8 @@ enum cardemu_usb_msg_type { struct cardemu_usb_msg_hdr { uint8_t msg_type; /* enum cardemu_usb_msg_type */ uint8_t seq_nr; /* sequence number */ - uint16_t data_len; /* length of optional data field */ + uint16_t msg_len; /* length of message including hdr */ + uint8_t data[0]; } __attribute__ ((packed)); /* indicates a TPDU header is present in this message */ @@ -64,7 +65,8 @@ struct cardemu_usb_msg_cardinsert { /* CEMU_USB_MSGT_DT_SET_ATR */ struct cardemu_usb_msg_set_atr { struct cardemu_usb_msg_hdr hdr; - /* variable-length ATR data (hdr.data_len) */ + uint8_t atr_len; + /* variable-length ATR data */ uint8_t atr[0]; } __attribute__ ((packed)); @@ -72,7 +74,8 @@ struct cardemu_usb_msg_set_atr { struct cardemu_usb_msg_tx_data { struct cardemu_usb_msg_hdr hdr; uint32_t flags; - /* variable-length TPDU data (hdr.data_len) */ + uint16_t data_len; + /* variable-length TPDU data */ uint8_t data[0]; } __attribute__ ((packed)); @@ -80,7 +83,8 @@ struct cardemu_usb_msg_tx_data { struct cardemu_usb_msg_rx_data { struct cardemu_usb_msg_hdr hdr; uint32_t flags; - /* variable-length TPDU data (hdr.data_len) */ + uint16_t data_len; + /* variable-length TPDU data */ uint8_t data[0]; } __attribute__ ((packed)); @@ -105,6 +109,7 @@ struct cardemu_usb_msg_status { /* CEMU_USB_MSGT_DO_PTS */ struct cardemu_usb_msg_pts_info { struct cardemu_usb_msg_hdr hdr; + uint8_t pts_len; /* PTS request as sent from reader */ uint8_t req[6]; /* PTS response as sent by card */ @@ -117,6 +122,7 @@ struct cardemu_usb_msg_error { uint8_t severity; uint8_t subsystem; uint16_t code; + uint8_t msg_len; /* human-readable error message */ uint8_t msg[0]; } __attribute__ ((packed)); diff --git a/firmware/src_simtrace/mode_cardemu.c b/firmware/src_simtrace/mode_cardemu.c index a26abe79..3651752b 100644 --- a/firmware/src_simtrace/mode_cardemu.c +++ b/firmware/src_simtrace/mode_cardemu.c @@ -305,7 +305,7 @@ static void dispatch_usb_command(struct req_ctx *rctx, struct cardem_inst *ci) break; case CEMU_USB_MSGT_DT_SET_ATR: atr = (struct cardemu_usb_msg_set_atr *) hdr; - card_emu_set_atr(ci->ch, atr->atr, hdr->data_len); + card_emu_set_atr(ci->ch, atr->atr, atr->atr_len); req_ctx_put(rctx); break; case CEMU_USB_MSGT_DT_CARDINSERT: diff --git a/firmware/test/card_emu_tests.c b/firmware/test/card_emu_tests.c index e071dfa0..babb3ec3 100644 --- a/firmware/test/card_emu_tests.c +++ b/firmware/test/card_emu_tests.c @@ -140,7 +140,7 @@ static void dump_rctx(struct req_ctx *rctx) case CEMU_USB_MSGT_DO_RX_DATA: rxd = (struct cardemu_usb_msg_rx_data *)mh; printf(" flags=%x, data=", rxd->flags); - for (i = 0; i < mh->data_len; i++) + for (i = 0; i < rxd->data_len; i++) printf(" %02x", rxd->data[i]); printf("\n"); break; @@ -162,13 +162,13 @@ static void get_and_verify_rctx(int state, const uint8_t *data, unsigned int len case RCTX_S_USB_TX_PENDING: td = (struct cardemu_usb_msg_tx_data *) rctx->data; assert(td->hdr.msg_type == CEMU_USB_MSGT_DO_RX_DATA); - assert(td->hdr.data_len == len); + assert(td->data_len == len); assert(!memcmp(td->data, data, len)); break; #if 0 case RCTX_S_UART_RX_PENDING: rd = (struct cardemu_usb_msg_rx_data *) rctx->data; - assert(rd->hdr.data_len == len); + assert(rd->data_len == len); assert(!memcmp(rd->data, data, len)); break; #endif @@ -229,8 +229,9 @@ static void host_to_device_data(const uint8_t *data, uint16_t len, unsigned int cardemu_hdr_set(&rd->hdr, CEMU_USB_MSGT_DT_TX_DATA); rd->flags = flags; /* copy data and set length */ - rd->hdr.data_len = len; + rd->data_len = len; memcpy(rd->data, data, len); + rd->hdr.msg_len = sizeof(*rd) + len; /* hand the req_ctx to the UART transmit code */ req_ctx_set_state(rctx, RCTX_S_UART_TX_PENDING);