@@ -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
348385done_handling :
349386 return ;
0 commit comments