wifi: rtw89: don't request partial firmware if SECURITY_LOADPIN_ENFORCE
Kernel logs on platform enabling SECURITY_LOADPIN_ENFORCE ------ ``` LoadPin: firmware old-api-denied obj=<unknown> pid=810 cmdline="modprobe -q -- rtw89_8852ce" rtw89_8852ce 0000:01:00.0: loading /lib/firmware/rtw89/rtw8852c_fw.bin failed with error -1 rtw89_8852ce 0000:01:00.0: Direct firmware load for rtw89/rtw8852c_fw.bin failed with error -1 rtw89_8852ce 0000:01:00.0: failed to early request firmware: -1 ``` Trace ------ ``` request_partial_firmware_into_buf() > _request_firmware() >> fw_get_filesystem_firmware() >>> kernel_read_file_from_path_initns() >>>> kernel_read_file() >>>>> security_kernel_read_file() // It will iterate enabled LSMs' hooks for kernel_read_file. // With loadpin, it hooks loadpin_read_file. ``` If SECURITY_LOADPIN_ENFORCE is enabled, doing kernel_read_file() on partial files will be denied and return -EPERM (-1). Then, the outer API based on it, e.g. request_partial_firmware_into_buf(), will get the error. In the case, we cannot get the firmware stuffs right, even though there might be no error other than a permission issue on reading a partial file. So we have to request full firmware if SECURITY_LOADPIN_ENFORCE is enabled. It makes us still have a chance to do early firmware work on this kind of platforms. Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Signed-off-by: Kalle Valo <kvalo@kernel.org> Link: https://lore.kernel.org/r/20221202060521.501512-2-pkshih@realtek.com
This commit is contained in:
parent
c2f2924bc7
commit
3ddfe3bdd3
|
@ -277,25 +277,37 @@ void rtw89_early_fw_feature_recognize(struct device *device,
|
|||
const struct rtw89_chip_info *chip,
|
||||
u32 *early_feat_map)
|
||||
{
|
||||
union {
|
||||
struct rtw89_mfw_hdr mfw_hdr;
|
||||
u8 fw_hdr[RTW89_FW_HDR_SIZE];
|
||||
} buf = {};
|
||||
union rtw89_compat_fw_hdr buf = {};
|
||||
const struct firmware *firmware;
|
||||
bool full_req = false;
|
||||
u32 ver_code;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
ret = request_partial_firmware_into_buf(&firmware, chip->fw_name,
|
||||
device, &buf, sizeof(buf), 0);
|
||||
/* If SECURITY_LOADPIN_ENFORCE is enabled, reading partial files will
|
||||
* be denied (-EPERM). Then, we don't get right firmware things as
|
||||
* expected. So, in this case, we have to request full firmware here.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_SECURITY_LOADPIN_ENFORCE))
|
||||
full_req = true;
|
||||
|
||||
if (full_req)
|
||||
ret = request_firmware(&firmware, chip->fw_name, device);
|
||||
else
|
||||
ret = request_partial_firmware_into_buf(&firmware, chip->fw_name,
|
||||
device, &buf, sizeof(buf),
|
||||
0);
|
||||
|
||||
if (ret) {
|
||||
dev_err(device, "failed to early request firmware: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ver_code = buf.mfw_hdr.sig != RTW89_MFW_SIG ?
|
||||
RTW89_FW_HDR_VER_CODE(&buf.fw_hdr) :
|
||||
RTW89_MFW_HDR_VER_CODE(&buf.mfw_hdr);
|
||||
if (full_req)
|
||||
ver_code = rtw89_compat_fw_hdr_ver_code(firmware->data);
|
||||
else
|
||||
ver_code = rtw89_compat_fw_hdr_ver_code(&buf);
|
||||
|
||||
if (!ver_code)
|
||||
goto out;
|
||||
|
||||
|
|
|
@ -3291,6 +3291,21 @@ struct fwcmd_hdr {
|
|||
__le32 hdr1;
|
||||
};
|
||||
|
||||
union rtw89_compat_fw_hdr {
|
||||
struct rtw89_mfw_hdr mfw_hdr;
|
||||
u8 fw_hdr[RTW89_FW_HDR_SIZE];
|
||||
};
|
||||
|
||||
static inline u32 rtw89_compat_fw_hdr_ver_code(const void *fw_buf)
|
||||
{
|
||||
const union rtw89_compat_fw_hdr *compat = (typeof(compat))fw_buf;
|
||||
|
||||
if (compat->mfw_hdr.sig == RTW89_MFW_SIG)
|
||||
return RTW89_MFW_HDR_VER_CODE(&compat->mfw_hdr);
|
||||
else
|
||||
return RTW89_FW_HDR_VER_CODE(&compat->fw_hdr);
|
||||
}
|
||||
|
||||
#define RTW89_H2C_RF_PAGE_SIZE 500
|
||||
#define RTW89_H2C_RF_PAGE_NUM 3
|
||||
struct rtw89_fw_h2c_rf_reg_info {
|
||||
|
|
Loading…
Reference in New Issue