CVE-2022-25050: Out-of-bounds Write (CWE-787)
value: rtl_433 21.12 was discovered to contain a stack overflow in the function somfy_iohc_decode(). This vulnerability allows attackers to cause a Denial of Service (DoS) via a crafted file.
CWE description: The product writes data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 5.5
Published: 2022-03-02T00:15Z
Repository: https://github.com/merbanan/rtl_433
Language: C
Files changed: src/devices/cmr113.c, src/devices/somfy_iohc.c
Commit date: 2022-01-24 15:53:20 +0100
Commit message: minor: Fix overflow in Clipsal-CMR113 and Somfy-IOHC reported by aug5t7

Diff: diff --git a/src/devices/cmr113.c b/src/devices/cmr113.c
index c85dfac5..19ec5d42 100644
--- a/src/devices/cmr113.c
+++ b/src/devices/cmr113.c
@@ -40,12 +40,12 @@ D) The output from C represents the final bitstream. This is 83
 Kudos to Jon Oxer for decoding this stream and putting it here:
 https://github.com/jonoxer/CentAReceiver
 
 */
 
-#define COMPARE_BITS 83
-#define COMPARE_BYTES (COMPARE_BITS/8)
+#define COMPARE_BITS  83
+#define COMPARE_BYTES ((COMPARE_BITS + 7) / 8)
 
 static int cmr113_decode(r_device *decoder, bitbuffer_t *bitbuffer)
 {
     int start, bit;
     uint8_t buf[4];
diff --git a/src/devices/somfy_iohc.c b/src/devices/somfy_iohc.c
index 906cae53..2c88067b 100644
--- a/src/devices/somfy_iohc.c
+++ b/src/devices/somfy_iohc.c
@@ -98,15 +98,16 @@ static int somfy_iohc_decode(r_device *decoder, bitbuffer_t *bitbuffer)
     uint8_t b[19 + 15]; // 19 byte + up 15 byte payload
 
     if (bitbuffer->num_rows != 1)
         return DECODE_ABORT_EARLY;
 
-    int offset = bitbuffer_search(bitbuffer, 0, 0, preamble_pattern, 24) + 24;
-    if (offset >= bitbuffer->bits_per_row[0] - 19 * 10)
+    unsigned offset = bitbuffer_search(bitbuffer, 0, 0, preamble_pattern, 24) + 24;
+    if (offset + 19 * 10 >= bitbuffer->bits_per_row[0])
         return DECODE_ABORT_EARLY;
 
-    int num_bits = bitbuffer->bits_per_row[0] - offset;
+    unsigned num_bits = bitbuffer->bits_per_row[0] - offset;
+    num_bits = MIN(num_bits, sizeof (b) * 8);
 
     int len = extract_bytes_uart(bitbuffer->bb[0], offset, num_bits, b);
     if (len < 19)
         return DECODE_ABORT_LENGTH;
 
@@ -118,11 +119,11 @@ static int somfy_iohc_decode(r_device *decoder, bitbuffer_t *bitbuffer)
         return DECODE_ABORT_LENGTH;
 
     // calculate and verify checksum
     if (crc16lsb(b, len, 0x8408, 0x0000) != 0) // unreflected poly 0x1021
         return DECODE_FAIL_MIC;
-    bitrow_printf(b, len * 8, "%s: offset %d, num_bits %d, len %d, msg_len %d\n", __func__, offset, num_bits, len, msg_len);
+    bitrow_printf(b, len * 8, "%s: offset %u, num_bits %u, len %d, msg_len %d\n", __func__, offset, num_bits, len, msg_len);
 
     int msg_type = (b[0]);
     int dst_id   = ((unsigned)b[4] << 24) | (b[3] << 16) | (b[2] << 8) | (b[1]); // assume Little-Endian
     int src_id   = ((unsigned)b[8] << 24) | (b[7] << 16) | (b[6] << 8) | (b[5]); // assume Little-Endian
     int counter  = (b[len - 10] << 8) | (b[len - 9]);

Vulnerable code: #define COMPARE_BITS 83
#define COMPARE_BYTES (COMPARE_BITS/8)
    int offset = bitbuffer_search(bitbuffer, 0, 0, preamble_pattern, 24) + 24;
    if (offset >= bitbuffer->bits_per_row[0] - 19 * 10)
    int num_bits = bitbuffer->bits_per_row[0] - offset;
    bitrow_printf(b, len * 8, "%s: offset %d, num_bits %d, len %d, msg_len %d\n", __func__, offset, num_bits, len, msg_len);
Fixed code: #define COMPARE_BITS  83
#define COMPARE_BYTES ((COMPARE_BITS + 7) / 8)
    unsigned offset = bitbuffer_search(bitbuffer, 0, 0, preamble_pattern, 24) + 24;
    if (offset + 19 * 10 >= bitbuffer->bits_per_row[0])
    unsigned num_bits = bitbuffer->bits_per_row[0] - offset;
    num_bits = MIN(num_bits, sizeof (b) * 8);
    bitrow_printf(b, len * 8, "%s: offset %u, num_bits %u, len %d, msg_len %d\n", __func__, offset, num_bits, len, msg_len);