]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: rtw89: fw: add blacklist to avoid obsolete secure firmware
authorPing-Ke Shih <pkshih@realtek.com>
Mon, 17 Feb 2025 06:43:04 +0000 (14:43 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 May 2025 09:13:13 +0000 (11:13 +0200)
[ Upstream commit f11d042b3a2e92ab1aa10e0da8e290bcdcf31d39 ]

To ensure secure chip only runs expected secure firmware, stop using
obsolete firmware in blacklist which weakness or flaw was found.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20250217064308.43559-2-pkshih@realtek.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/fw.c
drivers/net/wireless/realtek/rtw89/fw.h
drivers/net/wireless/realtek/rtw89/rtw8851b.c
drivers/net/wireless/realtek/rtw89/rtw8852a.c
drivers/net/wireless/realtek/rtw89/rtw8852b.c
drivers/net/wireless/realtek/rtw89/rtw8852bt.c
drivers/net/wireless/realtek/rtw89/rtw8852c.c
drivers/net/wireless/realtek/rtw89/rtw8922a.c

index 979587e92c8492587100d89eefde5bd6c50ff97d..c493153ec77b350f1bca66bdda83bddf71e692f0 100644 (file)
@@ -17,6 +17,7 @@ struct rtw89_dev;
 struct rtw89_pci_info;
 struct rtw89_mac_gen_def;
 struct rtw89_phy_gen_def;
+struct rtw89_fw_blacklist;
 struct rtw89_efuse_block_cfg;
 struct rtw89_h2c_rf_tssi;
 struct rtw89_fw_txpwr_track_cfg;
@@ -4251,6 +4252,7 @@ struct rtw89_chip_info {
        bool try_ce_fw;
        u8 bbmcu_nr;
        u32 needed_fw_elms;
+       const struct rtw89_fw_blacklist *fw_blacklist;
        u32 fifo_size;
        bool small_fifo_size;
        u32 dle_scc_rsvd_size;
index 3164ff69803a123b716167af4c6b37df30cbb87a..92e6bc05cbf66c9a354ce17443f0d99cbb22895a 100644 (file)
@@ -38,6 +38,16 @@ struct rtw89_arp_rsp {
 
 static const u8 mss_signature[] = {0x4D, 0x53, 0x53, 0x4B, 0x50, 0x4F, 0x4F, 0x4C};
 
+const struct rtw89_fw_blacklist rtw89_fw_blacklist_default = {
+       .ver = 0x00,
+       .list = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+       },
+};
+EXPORT_SYMBOL(rtw89_fw_blacklist_default);
+
 union rtw89_fw_element_arg {
        size_t offset;
        enum rtw89_rf_path rf_path;
@@ -344,6 +354,46 @@ ignore:
        return 0;
 }
 
+static int __check_secure_blacklist(struct rtw89_dev *rtwdev,
+                                   struct rtw89_fw_bin_info *info,
+                                   struct rtw89_fw_hdr_section_info *section_info,
+                                   const void *content)
+{
+       const struct rtw89_fw_blacklist *chip_blacklist = rtwdev->chip->fw_blacklist;
+       const union rtw89_fw_section_mssc_content *section_content = content;
+       struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
+       u8 byte_idx;
+       u8 bit_mask;
+
+       if (!sec->secure_boot)
+               return 0;
+
+       if (!info->secure_section_exist || section_info->ignore)
+               return 0;
+
+       if (!chip_blacklist) {
+               rtw89_err(rtwdev, "chip no blacklist for secure firmware\n");
+               return -ENOENT;
+       }
+
+       byte_idx = section_content->blacklist.bit_in_chip_list >> 3;
+       bit_mask = BIT(section_content->blacklist.bit_in_chip_list & 0x7);
+
+       if (section_content->blacklist.ver > chip_blacklist->ver) {
+               rtw89_err(rtwdev, "chip blacklist out of date (%u, %u)\n",
+                         section_content->blacklist.ver, chip_blacklist->ver);
+               return -EINVAL;
+       }
+
+       if (chip_blacklist->list[byte_idx] & bit_mask) {
+               rtw89_err(rtwdev, "firmware %u in chip blacklist\n",
+                         section_content->blacklist.ver);
+               return -EPERM;
+       }
+
+       return 0;
+}
+
 static int __parse_security_section(struct rtw89_dev *rtwdev,
                                    struct rtw89_fw_bin_info *info,
                                    struct rtw89_fw_hdr_section_info *section_info,
@@ -374,7 +424,7 @@ static int __parse_security_section(struct rtw89_dev *rtwdev,
                info->secure_section_exist = true;
        }
 
-       return 0;
+       return __check_secure_blacklist(rtwdev, info, section_info, content);
 }
 
 static int rtw89_fw_hdr_parser_v1(struct rtw89_dev *rtwdev, const u8 *fw, u32 len,
index 2026bc2fd2acd43aa4f8ccf71a2d3bb58f57a846..ee2be09bd3dbd836f71842ffd990397585f012dc 100644 (file)
@@ -663,6 +663,11 @@ struct rtw89_fw_mss_pool_hdr {
 } __packed;
 
 union rtw89_fw_section_mssc_content {
+       struct {
+               u8 pad[0x20];
+               u8 bit_in_chip_list;
+               u8 ver;
+       } __packed blacklist;
        struct {
                u8 pad[58];
                __le32 v;
@@ -673,6 +678,13 @@ union rtw89_fw_section_mssc_content {
        } __packed key_sign_len;
 } __packed;
 
+struct rtw89_fw_blacklist {
+       u8 ver;
+       u8 list[32];
+};
+
+extern const struct rtw89_fw_blacklist rtw89_fw_blacklist_default;
+
 static inline void SET_CTRL_INFO_MACID(void *table, u32 val)
 {
        le32p_replace_bits((__le32 *)(table) + 0, val, GENMASK(6, 0));
index 24d48aced57ac51cecbd510bf7ade559702fd202..a1df4ba97cd4d9ad0350c264ffbf6d6545a6a04c 100644 (file)
@@ -2445,6 +2445,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
        .try_ce_fw              = true,
        .bbmcu_nr               = 0,
        .needed_fw_elms         = 0,
+       .fw_blacklist           = NULL,
        .fifo_size              = 196608,
        .small_fifo_size        = true,
        .dle_scc_rsvd_size      = 98304,
index eeb40a60c2b987eb8d53b54575050c1263dcda6d..cd79a997fe0221797e2d915ffd5083e41991c3c7 100644 (file)
@@ -2162,6 +2162,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
        .try_ce_fw              = false,
        .bbmcu_nr               = 0,
        .needed_fw_elms         = 0,
+       .fw_blacklist           = NULL,
        .fifo_size              = 458752,
        .small_fifo_size        = false,
        .dle_scc_rsvd_size      = 0,
index 4335fa85c334b4294d013ac6abd7852bda751648..fcb69fa6cf86d6884922dbef645dcc8548f48133 100644 (file)
@@ -798,6 +798,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
        .try_ce_fw              = true,
        .bbmcu_nr               = 0,
        .needed_fw_elms         = 0,
+       .fw_blacklist           = &rtw89_fw_blacklist_default,
        .fifo_size              = 196608,
        .small_fifo_size        = true,
        .dle_scc_rsvd_size      = 98304,
index 7f64a5695486b6343583c1a610bede6ab0319f03..bc740e9abf2630327ffb99fef375afea7ef1513c 100644 (file)
@@ -732,6 +732,7 @@ const struct rtw89_chip_info rtw8852bt_chip_info = {
        .try_ce_fw              = true,
        .bbmcu_nr               = 0,
        .needed_fw_elms         = RTW89_AX_GEN_DEF_NEEDED_FW_ELEMENTS_NO_6GHZ,
+       .fw_blacklist           = &rtw89_fw_blacklist_default,
        .fifo_size              = 458752,
        .small_fifo_size        = true,
        .dle_scc_rsvd_size      = 98304,
index 9778621d9bc4156bd33a38ebe51b3208e8254ff6..63a2bc88cdbcdaf29711ffaf0db0f4acf54ed806 100644 (file)
@@ -2954,6 +2954,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
        .try_ce_fw              = false,
        .bbmcu_nr               = 0,
        .needed_fw_elms         = 0,
+       .fw_blacklist           = &rtw89_fw_blacklist_default,
        .fifo_size              = 458752,
        .small_fifo_size        = false,
        .dle_scc_rsvd_size      = 0,
index 731bc6f18d38b8fcfc59d6e80fff9a9680efea93..2696fdf350f630660402b499571df7fe7e913183 100644 (file)
@@ -2721,6 +2721,7 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
        .try_ce_fw              = false,
        .bbmcu_nr               = 1,
        .needed_fw_elms         = RTW89_BE_GEN_DEF_NEEDED_FW_ELEMENTS,
+       .fw_blacklist           = &rtw89_fw_blacklist_default,
        .fifo_size              = 589824,
        .small_fifo_size        = false,
        .dle_scc_rsvd_size      = 0,