aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid E. Box <david.e.box@linux.intel.com>2014-07-07 22:06:17 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-07-08 08:22:25 -0400
commitce5eb07339b9162812458ee611b6e7af7604a3e4 (patch)
tree71c9c03ab9035c2c21a72b4d619afabc54be718f
parente740304c7cf389b5d498bd86865fc82518d9ea1a (diff)
ACPICA: Utilities: Validate full RSDP header
Implement proper RSDP validation in acpi_ut_read_table(). Prevents a segmentation fault that can occur if a user passes the wrong file to iasl. This patch is only useful for iasl, which is not shipped in the Linux kernel. After the new table reading utility functions are well tested, acpidump can also switch to use the generic acpi_ut_read_table_xxx() APIs. Currently this patch is no-op as acpidump does not link to the new APIs. Signed-off-by: David E. Box <david.e.box@linux.intel.com> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/acpi/acpica/utfileio.c19
1 files changed, 7 insertions, 12 deletions
diff --git a/drivers/acpi/acpica/utfileio.c b/drivers/acpi/acpica/utfileio.c
index c8f63594b198..bdf9914733cb 100644
--- a/drivers/acpi/acpica/utfileio.c
+++ b/drivers/acpi/acpica/utfileio.c
@@ -150,6 +150,7 @@ acpi_ut_read_table(FILE * fp,
150 acpi_status status; 150 acpi_status status;
151 u32 file_size; 151 u32 file_size;
152 u8 standard_header = TRUE; 152 u8 standard_header = TRUE;
153 s32 count;
153 154
154 /* Get the file size */ 155 /* Get the file size */
155 156
@@ -164,27 +165,21 @@ acpi_ut_read_table(FILE * fp,
164 165
165 /* Read the signature */ 166 /* Read the signature */
166 167
167 if (fread(&table_header, 1, 4, fp) != 4) { 168 fseek(fp, 0, SEEK_SET);
168 acpi_os_printf("Could not read the table signature\n"); 169
170 count = fread(&table_header, 1, sizeof(struct acpi_table_header), fp);
171 if (count != sizeof(struct acpi_table_header)) {
172 acpi_os_printf("Could not read the table header\n");
169 return (AE_BAD_HEADER); 173 return (AE_BAD_HEADER);
170 } 174 }
171 175
172 fseek(fp, 0, SEEK_SET);
173
174 /* The RSDP table does not have standard ACPI header */ 176 /* The RSDP table does not have standard ACPI header */
175 177
176 if (ACPI_COMPARE_NAME(table_header.signature, "RSD ")) { 178 if (ACPI_VALIDATE_RSDP_SIG(table_header.signature)) {
177 *table_length = file_size; 179 *table_length = file_size;
178 standard_header = FALSE; 180 standard_header = FALSE;
179 } else { 181 } else {
180 /* Read the table header */
181 182
182 if (fread
183 (&table_header, 1, sizeof(struct acpi_table_header),
184 fp) != sizeof(struct acpi_table_header)) {
185 acpi_os_printf("Could not read the table header\n");
186 return (AE_BAD_HEADER);
187 }
188#if 0 183#if 0
189 /* Validate the table header/length */ 184 /* Validate the table header/length */
190 185