Fix integer overflows in iwm(4) and iwx(4) firmware file parsers.
authorstsp <stsp@openbsd.org>
Mon, 29 Aug 2022 17:59:12 +0000 (17:59 +0000)
committerstsp <stsp@openbsd.org>
Mon, 29 Aug 2022 17:59:12 +0000 (17:59 +0000)
Found by hshoexer and gerhard@, and reported to me by Christian Ehrhardt.

ok gerhard@

sys/dev/pci/if_iwm.c
sys/dev/pci/if_iwx.c

index 0bc32b5..b7d37d7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_iwm.c,v 1.403 2022/07/11 11:28:37 stsp Exp $       */
+/*     $OpenBSD: if_iwm.c,v 1.404 2022/08/29 17:59:12 stsp Exp $       */
 
 /*
  * Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -1015,6 +1015,13 @@ iwm_read_firmware(struct iwm_softc *sc)
                        goto parse_out;
                }
 
+               /*
+                * Check for size_t overflow and ignore missing padding at
+                * end of firmware file.
+                */
+               if (roundup(tlv_len, 4) > len)
+                       break;
+
                len -= roundup(tlv_len, 4);
                data += roundup(tlv_len, 4);
        }
index 9497ddb..f4dc3de 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_iwx.c,v 1.149 2022/05/14 05:42:39 stsp Exp $       */
+/*     $OpenBSD: if_iwx.c,v 1.150 2022/08/29 17:59:12 stsp Exp $       */
 
 /*
  * Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -1566,6 +1566,13 @@ iwx_read_firmware(struct iwx_softc *sc)
                        goto parse_out;
                }
 
+               /*
+                * Check for size_t overflow and ignore missing padding at
+                * end of firmware file.
+                */
+               if (roundup(tlv_len, 4) > len)
+                       break;
+
                len -= roundup(tlv_len, 4);
                data += roundup(tlv_len, 4);
        }
@@ -3986,6 +3993,8 @@ iwx_pnvm_handle_section(struct iwx_softc *sc, const uint8_t *data,
                        break;
                }
 
+               if (roundup(tlv_len, 4) > len)
+                       break;
                len -= roundup(tlv_len, 4);
                data += roundup(tlv_len, 4);
        }
@@ -4024,7 +4033,7 @@ iwx_pnvm_parse(struct iwx_softc *sc, const uint8_t *data, size_t len)
                tlv_len = le32toh(tlv->length);
                tlv_type = le32toh(tlv->type);
 
-               if (len < tlv_len)
+               if (len < tlv_len || roundup(tlv_len, 4) > len)
                        return EINVAL;
 
                if (tlv_type == IWX_UCODE_TLV_PNVM_SKU) {