Skip to content

Commit d70d0c3

Browse files
committed
Make the overflow checks platform-invariant
1 parent 26a3f59 commit d70d0c3

1 file changed

Lines changed: 43 additions & 6 deletions

File tree

keepkey_board/local/baremetal/msg_dispatch.c

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,31 @@ static void raw_dispatch(const MessagesMap_t *entry, uint8_t *msg, uint32_t msg_
238238
}
239239
}
240240

241+
#if defined(__has_builtin) && __has_builtin(__builtin_add_overflow)
242+
# define check_uadd_overflow(A, B, R) \
243+
({ \
244+
typeof(A) __a = (A); \
245+
typeof(B) __b = (B); \
246+
typeof(R) __r = (R); \
247+
(void)(&__a == &__b && "types must match"); \
248+
(void)(&__a == __r && "types must match"); \
249+
_Static_assert(0 < (typeof(A))-1, "types must be unsigned"); \
250+
__builtin_add_overflow((A), (B), (R)); \
251+
})
252+
#else
253+
# define check_uadd_overflow(A, B, R) \
254+
({ \
255+
typeof(A) __a = (A); \
256+
typeof(B) __b = (B); \
257+
typeof(R) __r = (R); \
258+
(void)(&__a == &__b && "types must match"); \
259+
(void)(&__a == __r && "types must match"); \
260+
_Static_assert(0 < (typeof(A))-1, "types must be unsigned"); \
261+
*__r = __a + __b; \
262+
*__r < __a; \
263+
})
264+
#endif
265+
241266
/*
242267
* usb_rx_helper() - Common helper that handles USB messages from host
243268
*
@@ -251,7 +276,7 @@ static void usb_rx_helper(UsbMessage *msg, MessageMapType type)
251276
{
252277
static TrezorFrameHeaderFirst last_frame_header = { .id = 0xffff, .len = 0 };
253278
static uint8_t content_buf[MAX_FRAME_SIZE];
254-
static uint32_t content_pos = 0, content_size = 0;
279+
static size_t content_pos = 0, content_size = 0;
255280
static bool mid_frame = false;
256281

257282
const MessagesMap_t *entry;
@@ -286,7 +311,8 @@ static void usb_rx_helper(UsbMessage *msg, MessageMapType type)
286311
else if(mid_frame)
287312
{
288313
contents = frame_fragment->contents;
289-
content_pos += msg->len - 1;
314+
if (check_uadd_overflow(content_pos, (size_t)(msg->len - 1), &content_pos))
315+
goto reset;
290316
content_size = msg->len - 1;
291317
}
292318
else
@@ -310,7 +336,6 @@ static void usb_rx_helper(UsbMessage *msg, MessageMapType type)
310336
}
311337
else if(entry)
312338
{
313-
/* Copy content to frame buffer */
314339
size_t offset, len;
315340
if (content_size == content_pos) {
316341
offset = 0;
@@ -320,9 +345,12 @@ static void usb_rx_helper(UsbMessage *msg, MessageMapType type)
320345
len = msg->len - 1;
321346
}
322347

323-
if (offset + (uint64_t)len < sizeof(content_buf)) {
324-
memcpy(content_buf + offset, contents, len);
325-
}
348+
size_t end;
349+
if (check_uadd_overflow(offset, len, &end) || sizeof(content_buf) < end)
350+
goto reset;
351+
352+
/* Copy content to frame buffer */
353+
memcpy(content_buf + offset, contents, len);
326354
}
327355

328356
/*
@@ -344,6 +372,15 @@ static void usb_rx_helper(UsbMessage *msg, MessageMapType type)
344372
dispatch(entry, content_buf, last_frame_header.len);
345373
}
346374
}
375+
goto done_handling;
376+
377+
reset:
378+
last_frame_header.id = 0xffff;
379+
last_frame_header.len = 0;
380+
memset(content_buf, 0, sizeof(content_buf));
381+
content_pos = 0;
382+
content_size = 0;
383+
mid_frame = false;
347384

348385
done_handling:
349386
return;

0 commit comments

Comments
 (0)