From 6249b40aea5f53bf6124f4a12d762ba9b1daceaa Mon Sep 17 00:00:00 2001 From: Oleksii Lukin Date: Sun, 5 Jul 2026 08:56:23 +0300 Subject: [PATCH] fix(region): signed integer overflow in RegionCommonComputeSymbolTimeLoRa at SF11/SF12 ( 1 << phyDr ) * 1000000 is evaluated in (signed) int arithmetic. For phyDr >= 11 the intermediate product (2048e6 / 4096e6) exceeds INT32_MAX, which is undefined behavior in C. On typical two's-complement targets the wrapped value makes the returned symbol time garbage instead of e.g. 32768 us for SF12/125kHz, corrupting the RX window timeout/offset computation downstream; with a different compiler/optimization level the behavior is not defined at all. Force the computation into uint32_t: the maximum intermediate value (4096 * 1000000 = 4.096e9) fits in an unsigned 32-bit integer. Found by UndefinedBehaviorSanitizer while host-testing the MAC against a stub radio (join at DR0/EU868): RegionCommon.c: runtime error: signed integer overflow: 4096 * 1000000 cannot be represented in type 'int' #0 RegionCommonComputeSymbolTimeLoRa #1 RegionEU868ComputeRxWindowParameters #2 ScheduleTx --- src/mac/region/RegionCommon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mac/region/RegionCommon.c b/src/mac/region/RegionCommon.c index 6a54d423e..d2aef2387 100644 --- a/src/mac/region/RegionCommon.c +++ b/src/mac/region/RegionCommon.c @@ -443,7 +443,7 @@ uint8_t RegionCommonLinkAdrReqVerifyParams( RegionCommonLinkAdrReqVerifyParams_t uint32_t RegionCommonComputeSymbolTimeLoRa( uint8_t phyDr, uint32_t bandwidthInHz ) { - return ( 1 << phyDr ) * 1000000 / bandwidthInHz; + return ( ( uint32_t )1 << phyDr ) * 1000000U / bandwidthInHz; } uint32_t RegionCommonComputeSymbolTimeFsk( uint8_t phyDrInKbps )