r8152: add checking fw_offset field of struct fw_mac
authorHayes Wang <hayeswang@realtek.com>
Mon, 21 Oct 2019 03:41:11 +0000 (11:41 +0800)
committerJakub Kicinski <jakub.kicinski@netronome.com>
Tue, 22 Oct 2019 16:45:21 +0000 (09:45 -0700)
Make sure @fw_offset field of struct fw_mac is more than the size
of struct fw_mac.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
drivers/net/usb/r8152.c

index 55a7674a0c0686cfa193fca93472b47c002f3e17..090ddd5fb9737c7c24b28bbd16386fdcdd4a7d3b 100644 (file)
@@ -3399,7 +3399,7 @@ static void rtl_clear_bp(struct r8152 *tp, u16 type)
 
 static bool rtl8152_is_fw_mac_ok(struct r8152 *tp, struct fw_mac *mac)
 {
-       u16 fw_reg, bp_ba_addr, bp_en_addr, bp_start;
+       u16 fw_reg, bp_ba_addr, bp_en_addr, bp_start, fw_offset;
        bool rc = false;
        u32 length, type;
        int i, max_bp;
@@ -3461,13 +3461,19 @@ static bool rtl8152_is_fw_mac_ok(struct r8152 *tp, struct fw_mac *mac)
                goto out;
        }
 
+       fw_offset = __le16_to_cpu(mac->fw_offset);
+       if (fw_offset < sizeof(*mac)) {
+               dev_err(&tp->intf->dev, "fw_offset too small\n");
+               goto out;
+       }
+
        length = __le32_to_cpu(mac->blk_hdr.length);
-       if (length < __le16_to_cpu(mac->fw_offset)) {
+       if (length < fw_offset) {
                dev_err(&tp->intf->dev, "invalid fw_offset\n");
                goto out;
        }
 
-       length -= __le16_to_cpu(mac->fw_offset);
+       length -= fw_offset;
        if (length < 4 || (length & 3)) {
                dev_err(&tp->intf->dev, "invalid block length\n");
                goto out;