Skip to content
Permalink
Browse files
Make the overflow checks platform-invariant
  • Loading branch information
keepkeyjon committed Jun 11, 2018
1 parent 26a3f59 commit d70d0c37ad643a328f19908cd84a8312388b65b7
Showing with 43 additions and 6 deletions.
  1. +43 −6 keepkey_board/local/baremetal/msg_dispatch.c
@@ -238,6 +238,31 @@ static void raw_dispatch(const MessagesMap_t *entry, uint8_t *msg, uint32_t msg_
}
}

#if defined(__has_builtin) && __has_builtin(__builtin_add_overflow)
# define check_uadd_overflow(A, B, R) \
({ \
typeof(A) __a = (A); \
typeof(B) __b = (B); \
typeof(R) __r = (R); \
(void)(&__a == &__b && "types must match"); \
(void)(&__a == __r && "types must match"); \
_Static_assert(0 < (typeof(A))-1, "types must be unsigned"); \
__builtin_add_overflow((A), (B), (R)); \
})
#else
# define check_uadd_overflow(A, B, R) \
({ \
typeof(A) __a = (A); \
typeof(B) __b = (B); \
typeof(R) __r = (R); \
(void)(&__a == &__b && "types must match"); \
(void)(&__a == __r && "types must match"); \
_Static_assert(0 < (typeof(A))-1, "types must be unsigned"); \
*__r = __a + __b; \
*__r < __a; \
})
#endif

/*
* usb_rx_helper() - Common helper that handles USB messages from host
*
@@ -251,7 +276,7 @@ static void usb_rx_helper(UsbMessage *msg, MessageMapType type)
{
static TrezorFrameHeaderFirst last_frame_header = { .id = 0xffff, .len = 0 };
static uint8_t content_buf[MAX_FRAME_SIZE];
static uint32_t content_pos = 0, content_size = 0;
static size_t content_pos = 0, content_size = 0;
static bool mid_frame = false;

const MessagesMap_t *entry;
@@ -286,7 +311,8 @@ static void usb_rx_helper(UsbMessage *msg, MessageMapType type)
else if(mid_frame)
{
contents = frame_fragment->contents;
content_pos += msg->len - 1;
if (check_uadd_overflow(content_pos, (size_t)(msg->len - 1), &content_pos))
goto reset;
content_size = msg->len - 1;
}
else
@@ -310,7 +336,6 @@ static void usb_rx_helper(UsbMessage *msg, MessageMapType type)
}
else if(entry)
{
/* Copy content to frame buffer */
size_t offset, len;
if (content_size == content_pos) {
offset = 0;
@@ -320,9 +345,12 @@ static void usb_rx_helper(UsbMessage *msg, MessageMapType type)
len = msg->len - 1;
}

if (offset + (uint64_t)len < sizeof(content_buf)) {
memcpy(content_buf + offset, contents, len);
}
size_t end;
if (check_uadd_overflow(offset, len, &end) || sizeof(content_buf) < end)
goto reset;

/* Copy content to frame buffer */
memcpy(content_buf + offset, contents, len);
}

/*
@@ -344,6 +372,15 @@ static void usb_rx_helper(UsbMessage *msg, MessageMapType type)
dispatch(entry, content_buf, last_frame_header.len);
}
}
goto done_handling;

reset:
last_frame_header.id = 0xffff;
last_frame_header.len = 0;
memset(content_buf, 0, sizeof(content_buf));
content_pos = 0;
content_size = 0;
mid_frame = false;

done_handling:
return;

0 comments on commit d70d0c3

Please sign in to comment.