aboutsummaryrefslogtreecommitdiffstats
path: root/xen/drivers/acpi
diff options
context:
space:
mode:
authorHuang Ying <ying.huang@intel.com>2012-10-16 17:26:36 +0200
committerHuang Ying <ying.huang@intel.com>2012-10-16 17:26:36 +0200
commit915ef37d7cc8fcac5b37eb0b40c693754fcd12ab (patch)
treec396c41fc57983ffabe7079115d8722c0f08a989 /xen/drivers/acpi
parent02be82737e0659e231d0be71d5d5de1081cef295 (diff)
downloadxen-915ef37d7cc8fcac5b37eb0b40c693754fcd12ab.tar.gz
xen-915ef37d7cc8fcac5b37eb0b40c693754fcd12ab.tar.bz2
xen-915ef37d7cc8fcac5b37eb0b40c693754fcd12ab.zip
ACPI: fix APEI related table size checking
On Huang Ying's machine: erst_tab->header_length == sizeof(struct acpi_table_einj) but Yinghai reported that on his machine, erst_tab->header_length == sizeof(struct acpi_table_einj) - sizeof(struct acpi_table_header) To make erst table size checking code works on all systems, both testing are treated as PASS. Same situation applies to einj_tab->header_length, so corresponding table size checking is changed in similar way too. Originally-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Huang Ying <ying.huang@intel.com> - use switch() for better readability - add comment explaining why a formally invalid size it also being accepted - check erst_tab->header.length before even looking at erst_tab->header_length - prefer sizeof(*erst_tab) over sizeof(struct acpi_table_erst) Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org> Committed-by: Jan Beulich <jbeulich@suse.com>
Diffstat (limited to 'xen/drivers/acpi')
-rw-r--r--xen/drivers/acpi/apei/erst.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/xen/drivers/acpi/apei/erst.c b/xen/drivers/acpi/apei/erst.c
index eb666a6fca..31ce50d73c 100644
--- a/xen/drivers/acpi/apei/erst.c
+++ b/xen/drivers/acpi/apei/erst.c
@@ -715,12 +715,23 @@ int erst_clear(u64 record_id)
static int __init erst_check_table(struct acpi_table_erst *erst_tab)
{
- if (erst_tab->header_length != sizeof(struct acpi_table_erst))
+ if (erst_tab->header.length < sizeof(*erst_tab))
return -EINVAL;
- if (erst_tab->header.length < sizeof(struct acpi_table_erst))
+
+ switch (erst_tab->header_length) {
+ case sizeof(*erst_tab) - sizeof(erst_tab->header):
+ /*
+ * While invalid per specification, there are (early?) systems
+ * indicating the full header size here, so accept that value too.
+ */
+ case sizeof(*erst_tab):
+ break;
+ default:
return -EINVAL;
+ }
+
if (erst_tab->entries !=
- (erst_tab->header.length - sizeof(struct acpi_table_erst)) /
+ (erst_tab->header.length - sizeof(*erst_tab)) /
sizeof(struct acpi_erst_entry))
return -EINVAL;