Last active
February 22, 2017 05:19
-
-
Save parkerhoyes/54f8ad30cce1134351ee3ffcb13e69f1 to your computer and use it in GitHub Desktop.
Demonstration of Bug (Core Fault?) on Nano S
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdbool.h> | |
#include <stdint.h> | |
#include "os.h" | |
#include "os_io_seproxyhal.h" | |
// BEGIN TEST CODE | |
static const uint8_t app_test_obj = 42; | |
static int8_t app_test_int; | |
static uint8_t app_test_buff[8]; | |
static uint8_t *app_test_buff_ptr; | |
static void run_test() { | |
app_test_int = -1; | |
app_test_buff_ptr = app_test_buff; | |
const uint8_t *obj_ptr = &app_test_obj; | |
os_memcpy(app_test_buff_ptr, &obj_ptr, sizeof(obj_ptr)); | |
app_test_buff_ptr += sizeof(uint8_t*); | |
const uint8_t **obj_ptr_ptr = (const uint8_t**) (app_test_buff_ptr - sizeof(uint8_t*)); | |
const uint8_t *temp = *obj_ptr_ptr; // Core fault on this line? | |
os_sched_exit(0); | |
app_test_int = *temp; | |
} | |
static void app_event_ticker() { | |
if (app_test_int == -1) | |
app_test_int = 0; | |
} | |
// END TEST CODE | |
unsigned char G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B]; | |
void sample_main() { | |
volatile unsigned int rx = 0; | |
volatile unsigned int tx = 0; | |
volatile unsigned int flags = 0; | |
while (true) { | |
volatile unsigned short sw = 0; | |
BEGIN_TRY { | |
TRY { | |
rx = tx; | |
tx = 0; // Ensure no race in catch_other if io_exchange throws an error | |
rx = io_exchange(CHANNEL_APDU | flags, rx); | |
flags = 0; | |
// No APDU received, well, reset the session, and reset the bootloader configuration | |
if (rx == 0) { | |
THROW(0x6982); | |
} | |
if (G_io_apdu_buffer[0] != 0x80) { | |
THROW(0x6E00); | |
} | |
// Unauthenticated instruction | |
switch (G_io_apdu_buffer[1]) { | |
case 0x00: // Reset | |
flags |= IO_RESET_AFTER_REPLIED; | |
THROW(0x9000); | |
break; | |
case 0x01: // Case 1 | |
THROW(0x9000); | |
break; | |
case 0x02: // Echo | |
tx = rx; | |
THROW(0x9000); | |
break; | |
case 0xFF: // Return to dashboard | |
goto return_to_dashboard; | |
default: | |
THROW(0x6D00); | |
break; | |
} | |
} CATCH_OTHER(e) { | |
switch (e & 0xF000) { | |
case 0x6000: | |
case 0x9000: | |
sw = e; | |
break; | |
default: | |
sw = 0x6800 | (e & 0x7FF); | |
break; | |
} | |
// Unexpected exception => report | |
G_io_apdu_buffer[tx] = sw >> 8; | |
G_io_apdu_buffer[tx + 1] = sw; | |
tx += 2; | |
} FINALLY {} | |
} END_TRY; | |
} | |
return_to_dashboard: | |
return; | |
} | |
unsigned short io_exchange_al(unsigned char channel, unsigned short tx_len) { | |
switch (channel & ~(IO_FLAGS)) { | |
case CHANNEL_KEYBOARD: | |
break; | |
// Multiplexed io exchange over a SPI channel and TLV encapsulated protocol | |
case CHANNEL_SPI: | |
if (tx_len) { | |
io_seproxyhal_spi_send(G_io_apdu_buffer, tx_len); | |
if (channel & IO_RESET_AFTER_REPLIED) { | |
reset(); | |
} | |
return 0; // Nothing received from the master so far (it's a tx transaction) | |
} else { | |
return io_seproxyhal_spi_recv(G_io_apdu_buffer, sizeof(G_io_apdu_buffer), 0); | |
} | |
default: | |
THROW(INVALID_PARAMETER); | |
} | |
return 0; | |
} | |
unsigned char io_event(unsigned char channel) { | |
switch (G_io_seproxyhal_spi_buffer[0]) { | |
case SEPROXYHAL_TAG_TICKER_EVENT: | |
app_event_ticker(); | |
break; | |
// Unknown events are acknowledged | |
default: | |
break; | |
} | |
// Close the event if not done previously (by a display or whatever) | |
if (!io_seproxyhal_spi_is_status_sent()) { | |
io_seproxyhal_general_status(); | |
} | |
// Command has been processed, DO NOT reset the current APDU transport | |
return 1; | |
} | |
__attribute__((section(".boot"))) int main() { | |
// Exit critical section | |
__asm volatile("cpsie i"); | |
// Ensure exception will work as planned | |
os_boot(); | |
BEGIN_TRY { | |
TRY { | |
io_seproxyhal_init(); | |
USB_power(0); | |
USB_power(1); | |
run_test(); | |
sample_main(); | |
} CATCH_OTHER(e) {} FINALLY {} | |
} END_TRY; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment