wifi: rtw89: fw: add firmware blacklist to avoid obsolete secure firmware
Ping-Ke Shih
maintainercover wifi: rtw89: fw: add firmware blacklist to avoid obsolete secure firmware
Considering weak or flaw firmware is not safe. Refuse using obsolete firmware on secure chips. Add and update a blacklist in driver, when a firmware is considered not secure.
The remaining four patches are to refine firmware codes by the way.
Ping-Ke Shih (5):
wifi: rtw89: fw: add blacklist to avoid obsolete secure firmware
wifi: rtw89: fw: get sb_sel_ver via get_unaligned_le32()
wifi: rtw89: fw: propagate error code from rtw89_h2c_tx()
wifi: rtw89: fw: add debug message for unexpected secure firmware
wifi: rtw89: fw: safely cast mfw_hdr pointer from firmware->data
drivers/net/wireless/realtek/rtw89/core.h | 2 + drivers/net/wireless/realtek/rtw89/fw.c | 91 ++++++++++++++++--- drivers/net/wireless/realtek/rtw89/fw.h | 12 +++ drivers/net/wireless/realtek/rtw89/rtw8851b.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + .../net/wireless/realtek/rtw89/rtw8852bt.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8922a.c | 1 + 9 files changed, 100 insertions(+), 11 deletions(-)
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 1/5 wifi: rtw89: fw: add blacklist to avoid obsolete secure firmware
To ensure secure chip only runs expected secure firmware, stop using obsolete firmware in blacklist which weakness or flaw was found.
--- drivers/net/wireless/realtek/rtw89/core.h | 2 + drivers/net/wireless/realtek/rtw89/fw.c | 52 ++++++++++++++++++- drivers/net/wireless/realtek/rtw89/fw.h | 12 +++++ drivers/net/wireless/realtek/rtw89/rtw8851b.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + .../net/wireless/realtek/rtw89/rtw8852bt.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8922a.c | 1 + 9 files changed, 71 insertions(+), 1 deletion(-)
drivers/net/wireless/realtek/rtw89/core.h +2 -0
@@ -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 ;
@@ -4257,6 +4258,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;
drivers/net/wireless/realtek/rtw89/fw.c +51 -1
70 lines not on this page · raw message
drivers/net/wireless/realtek/rtw89/fw.h +12 -0
@@ -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 ));
drivers/net/wireless/realtek/rtw89/rtw8851b.c +1 -0
@@ -2458,6 +2458,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,
drivers/net/wireless/realtek/rtw89/rtw8852a.c +1 -0
@@ -2175,6 +2175,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,
drivers/net/wireless/realtek/rtw89/rtw8852b.c +1 -0
@@ -811,6 +811,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,
drivers/net/wireless/realtek/rtw89/rtw8852bt.c +1 -0
@@ -745,6 +745,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,
drivers/net/wireless/realtek/rtw89/rtw8852c.c +1 -0
@@ -2967,6 +2967,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,
drivers/net/wireless/realtek/rtw89/rtw8922a.c +1 -0
@@ -2728,6 +2728,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,
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerRe: [PATCH 1/5] wifi: rtw89: fw: add blacklist to avoid obsolete secure firmware
Quoted 4 lines · Ping-Ke Shih
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 <[email protected]>
5 patch(es) applied to rtw-next branch of rtw.git, thanks.
f11d042b3a2e wifi: rtw89: fw: add blacklist to avoid obsolete secure firmware 2f9da853f4d8 wifi: rtw89: fw: get sb_sel_ver via get_unaligned_le32() 56e1acaa0f80 wifi: rtw89: fw: propagate error code from rtw89_h2c_tx() dc2fc1a3419e wifi: rtw89: fw: add debug message for unexpected secure firmware e0722103306f wifi: rtw89: fw: safely cast mfw_hdr pointer from firmware->data
Ping-Ke Shih
maintainerPATCH 2/5 wifi: rtw89: fw: get sb_sel_ver via get_unaligned_le32()
In reply to Ping-Ke ShihThe sb_sel_ver is selection version for secure boot recorded in firmware binary data, and its size is 4 and offset is 58 (not natural alignment). Use get_unaligned_le32() to get this value safely. Find this by reviewing.
--- drivers/net/wireless/realtek/rtw89/fw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/realtek/rtw89/fw.c +1 -1
@@ -324,7 +324,7 @@ static int __parse_formatted_mssc(struct rtw89_dev *rtwdev,if (!sec->secure_boot) goto out; - sb_sel_ver =le32_to_cpu (section_content->sb_sel_ver.v); + sb_sel_ver =get_unaligned_le32 (§ion_content->sb_sel_ver.v);if (sb_sel_ver && sb_sel_ver != sec->sb_sel_mgn) goto ignore;
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 3/5 wifi: rtw89: fw: propagate error code from rtw89_h2c_tx()
In reply to Ping-Ke ShihThe error code should be propagated to callers during downloading firmware header and body. Remove unnecessary assignment of -1.
--- drivers/net/wireless/realtek/rtw89/fw.c | 2 -- 1 file changed, 2 deletions(-)
drivers/net/wireless/realtek/rtw89/fw.c +0 -2
@@ -1510,7 +1510,6 @@ static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, ret =rtw89_h2c_tx (rtwdev, skb, false);if (ret) {rtw89_err (rtwdev,"failed to send h2c\n" ); - ret =-1 ; goto fail; }
@@ -1597,7 +1596,6 @@ static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev, ret =rtw89_h2c_tx (rtwdev, skb, true);if (ret) {rtw89_err (rtwdev,"failed to send h2c\n" ); - ret =-1 ; goto fail; }
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 4/5 wifi: rtw89: fw: add debug message for unexpected secure firmware
In reply to Ping-Ke ShihIf failed to load a non-secure firmware with a secure chip, it only throws a unclear message:
rtw89_8922ae 0000:03:00.0: parse fw header fail
To address this case simpler, add a message to point out this.
--- drivers/net/wireless/realtek/rtw89/fw.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/wireless/realtek/rtw89/fw.c +4 -1
@@ -414,8 +414,11 @@ static int __parse_security_section(struct rtw89_dev *rtwdev, *mssc_len += section_info->mssc *FWDL_SECURITY_CHKSUM_LEN ;if (sec->secure_boot) { -if (sec->mss_idx >= section_info->mssc) +if (sec->mss_idx >= section_info->mssc) { +rtw89_err (rtwdev,"unexpected MSS %d >= %d\n" , + sec->mss_idx, section_info->mssc);return -EFAULT ; + } section_info->key_addr = content + section_info->len + sec->mss_idx *FWDL_SECURITY_SIGLEN ; section_info->key_len =FWDL_SECURITY_SIGLEN ;
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 5/5 wifi: rtw89: fw: safely cast mfw_hdr pointer from firmware->data
In reply to Ping-Ke ShihCheck size of struct mfw_hdr within firmware->size before type casting to ensure to validly dereference fields from mfm_hdr pointer. Then, check if signature field is equal to RTW89_MFW_SIG to assert current is multi-firmware.
Addresses-Coverity-ID: 1494046 ("Untrusted loop bound")
Addresses-Coverity-ID: 1544385 ("Untrusted array index read")
--- drivers/net/wireless/realtek/rtw89/fw.c | 30 ++++++++++++++++++++----- 1 file changed, 24 insertions(+), 6 deletions(-)
drivers/net/wireless/realtek/rtw89/fw.c +24 -6
@@ -542,6 +542,23 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, } } +static +const struct rtw89_mfw_hdr *rtw89_mfw_get_hdr_ptr (struct rtw89_dev *rtwdev, +const struct firmware *firmware) +{ +const struct rtw89_mfw_hdr *mfw_hdr; + +if (sizeof (*mfw_hdr) > firmware->size) +return NULL ; + + mfw_hdr = (const struct rtw89_mfw_hdr *)firmware->data; + +if (mfw_hdr->sig !=RTW89_MFW_SIG ) +return NULL ; + +return mfw_hdr; +} +static int rtw89_mfw_validate_hdr (struct rtw89_dev *rtwdev,const struct firmware *firmware,const struct rtw89_mfw_hdr *mfw_hdr)
@@ -572,14 +589,15 @@ int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, {struct rtw89_fw_info *fw_info = &rtwdev->fw;const struct firmware *firmware = fw_info->req.firmware; +const struct rtw89_mfw_info *mfw_info =NULL , *tmp; +const struct rtw89_mfw_hdr *mfw_hdr;const u8 *mfw = firmware->data;u32 mfw_len = firmware->size; -const struct rtw89_mfw_hdr *mfw_hdr = (const struct rtw89_mfw_hdr *)mfw; -const struct rtw89_mfw_info *mfw_info =NULL , *tmp;int ret;int i; -if (mfw_hdr->sig !=RTW89_MFW_SIG ) { + mfw_hdr =rtw89_mfw_get_hdr_ptr (rtwdev, firmware); +if (!mfw_hdr) {rtw89_debug (rtwdev,RTW89_DBG_FW ,"use legacy firmware\n" );/* legacy firmware support normal type only */ if (type !=RTW89_FW_NORMAL )
@@ -635,13 +653,13 @@ static u32 rtw89_mfw_get_size(struct rtw89_dev *rtwdev) {struct rtw89_fw_info *fw_info = &rtwdev->fw;const struct firmware *firmware = fw_info->req.firmware; -const struct rtw89_mfw_hdr *mfw_hdr = - (const struct rtw89_mfw_hdr *)firmware->data;const struct rtw89_mfw_info *mfw_info; +const struct rtw89_mfw_hdr *mfw_hdr;u32 size;int ret; -if (mfw_hdr->sig !=RTW89_MFW_SIG ) { + mfw_hdr =rtw89_mfw_get_hdr_ptr (rtwdev, firmware); +if (!mfw_hdr) {rtw89_warn (rtwdev,"not mfw format\n" );return 0 ; }
Signature · 1 line
2.25.1