提交 b1cc4097 编写于 作者: M Marc-André Lureau 提交者: Michael S. Tsirkin

fw_cfg: handle fw_cfg_read_blob() error

fw_cfg_read_blob() may fail, but does not return error. This may lead
to surprising behaviours, like populating zero file entries (in
register_file() or during read). Return an error if ACPI locking
failed. Also, the following DMA read/write extension will add more
error paths that should be handled appropriately.
Signed-off-by: NMarc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: NMichael S. Tsirkin <mst@redhat.com>
上级 59ecab18
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
...@@ -77,8 +77,8 @@ static void fw_cfg_sel_endianness(u16 key) ...@@ -77,8 +77,8 @@ static void fw_cfg_sel_endianness(u16 key)
} }
/* read chunk of given fw_cfg blob (caller responsible for sanity-check) */ /* read chunk of given fw_cfg blob (caller responsible for sanity-check) */
static void fw_cfg_read_blob(u16 key, static ssize_t fw_cfg_read_blob(u16 key,
void *buf, loff_t pos, size_t count) void *buf, loff_t pos, size_t count)
{ {
u32 glk = -1U; u32 glk = -1U;
acpi_status status; acpi_status status;
...@@ -91,7 +91,7 @@ static void fw_cfg_read_blob(u16 key, ...@@ -91,7 +91,7 @@ static void fw_cfg_read_blob(u16 key,
/* Should never get here */ /* Should never get here */
WARN(1, "fw_cfg_read_blob: Failed to lock ACPI!\n"); WARN(1, "fw_cfg_read_blob: Failed to lock ACPI!\n");
memset(buf, 0, count); memset(buf, 0, count);
return; return -EINVAL;
} }
mutex_lock(&fw_cfg_dev_lock); mutex_lock(&fw_cfg_dev_lock);
...@@ -102,6 +102,7 @@ static void fw_cfg_read_blob(u16 key, ...@@ -102,6 +102,7 @@ static void fw_cfg_read_blob(u16 key,
mutex_unlock(&fw_cfg_dev_lock); mutex_unlock(&fw_cfg_dev_lock);
acpi_release_global_lock(glk); acpi_release_global_lock(glk);
return count;
} }
/* clean up fw_cfg device i/o */ /* clean up fw_cfg device i/o */
...@@ -183,8 +184,9 @@ static int fw_cfg_do_platform_probe(struct platform_device *pdev) ...@@ -183,8 +184,9 @@ static int fw_cfg_do_platform_probe(struct platform_device *pdev)
} }
/* verify fw_cfg device signature */ /* verify fw_cfg device signature */
fw_cfg_read_blob(FW_CFG_SIGNATURE, sig, 0, FW_CFG_SIG_SIZE); if (fw_cfg_read_blob(FW_CFG_SIGNATURE, sig,
if (memcmp(sig, "QEMU", FW_CFG_SIG_SIZE) != 0) { 0, FW_CFG_SIG_SIZE) < 0 ||
memcmp(sig, "QEMU", FW_CFG_SIG_SIZE) != 0) {
fw_cfg_io_cleanup(); fw_cfg_io_cleanup();
return -ENODEV; return -ENODEV;
} }
...@@ -344,8 +346,7 @@ static ssize_t fw_cfg_sysfs_read_raw(struct file *filp, struct kobject *kobj, ...@@ -344,8 +346,7 @@ static ssize_t fw_cfg_sysfs_read_raw(struct file *filp, struct kobject *kobj,
if (count > entry->size - pos) if (count > entry->size - pos)
count = entry->size - pos; count = entry->size - pos;
fw_cfg_read_blob(entry->select, buf, pos, count); return fw_cfg_read_blob(entry->select, buf, pos, count);
return count;
} }
static struct bin_attribute fw_cfg_sysfs_attr_raw = { static struct bin_attribute fw_cfg_sysfs_attr_raw = {
...@@ -501,7 +502,11 @@ static int fw_cfg_register_dir_entries(void) ...@@ -501,7 +502,11 @@ static int fw_cfg_register_dir_entries(void)
struct fw_cfg_file *dir; struct fw_cfg_file *dir;
size_t dir_size; size_t dir_size;
fw_cfg_read_blob(FW_CFG_FILE_DIR, &files_count, 0, sizeof(files_count)); ret = fw_cfg_read_blob(FW_CFG_FILE_DIR, &files_count,
0, sizeof(files_count));
if (ret < 0)
return ret;
count = be32_to_cpu(files_count); count = be32_to_cpu(files_count);
dir_size = count * sizeof(struct fw_cfg_file); dir_size = count * sizeof(struct fw_cfg_file);
...@@ -509,7 +514,10 @@ static int fw_cfg_register_dir_entries(void) ...@@ -509,7 +514,10 @@ static int fw_cfg_register_dir_entries(void)
if (!dir) if (!dir)
return -ENOMEM; return -ENOMEM;
fw_cfg_read_blob(FW_CFG_FILE_DIR, dir, sizeof(files_count), dir_size); ret = fw_cfg_read_blob(FW_CFG_FILE_DIR, dir,
sizeof(files_count), dir_size);
if (ret < 0)
goto end;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
ret = fw_cfg_register_file(&dir[i]); ret = fw_cfg_register_file(&dir[i]);
...@@ -517,6 +525,7 @@ static int fw_cfg_register_dir_entries(void) ...@@ -517,6 +525,7 @@ static int fw_cfg_register_dir_entries(void)
break; break;
} }
end:
kfree(dir); kfree(dir);
return ret; return ret;
} }
...@@ -557,7 +566,10 @@ static int fw_cfg_sysfs_probe(struct platform_device *pdev) ...@@ -557,7 +566,10 @@ static int fw_cfg_sysfs_probe(struct platform_device *pdev)
goto err_probe; goto err_probe;
/* get revision number, add matching top-level attribute */ /* get revision number, add matching top-level attribute */
fw_cfg_read_blob(FW_CFG_ID, &rev, 0, sizeof(rev)); err = fw_cfg_read_blob(FW_CFG_ID, &rev, 0, sizeof(rev));
if (err < 0)
goto err_probe;
fw_cfg_rev = le32_to_cpu(rev); fw_cfg_rev = le32_to_cpu(rev);
err = sysfs_create_file(fw_cfg_top_ko, &fw_cfg_rev_attr.attr); err = sysfs_create_file(fw_cfg_top_ko, &fw_cfg_rev_attr.attr);
if (err) if (err)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册