diff options
Diffstat (limited to 'drivers/acpi/tables/tbrsdt.c')
-rw-r--r-- | drivers/acpi/tables/tbrsdt.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c index abcb08c2592a..0ad3dbb9ebca 100644 --- a/drivers/acpi/tables/tbrsdt.c +++ b/drivers/acpi/tables/tbrsdt.c | |||
@@ -183,6 +183,17 @@ acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr) | |||
183 | 183 | ||
184 | ACPI_FUNCTION_ENTRY(); | 184 | ACPI_FUNCTION_ENTRY(); |
185 | 185 | ||
186 | /* Validate minimum length */ | ||
187 | |||
188 | if (table_ptr->length < sizeof(struct acpi_table_header)) { | ||
189 | ACPI_ERROR((AE_INFO, | ||
190 | "RSDT/XSDT length (%X) is smaller than minimum (%X)", | ||
191 | table_ptr->length, | ||
192 | sizeof(struct acpi_table_header))); | ||
193 | |||
194 | return (AE_INVALID_TABLE_LENGTH); | ||
195 | } | ||
196 | |||
186 | /* Search for appropriate signature, RSDT or XSDT */ | 197 | /* Search for appropriate signature, RSDT or XSDT */ |
187 | 198 | ||
188 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { | 199 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { |
@@ -210,7 +221,7 @@ acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr) | |||
210 | ACPI_ERROR((AE_INFO, "Looking for XSDT")); | 221 | ACPI_ERROR((AE_INFO, "Looking for XSDT")); |
211 | } | 222 | } |
212 | 223 | ||
213 | ACPI_DUMP_BUFFER((char *)table_ptr, 48); | 224 | ACPI_DUMP_BUFFER(ACPI_CAST_PTR(char, table_ptr), 48); |
214 | return (AE_BAD_SIGNATURE); | 225 | return (AE_BAD_SIGNATURE); |
215 | } | 226 | } |
216 | 227 | ||
@@ -258,7 +269,7 @@ acpi_status acpi_tb_get_table_rsdt(void) | |||
258 | 269 | ||
259 | status = acpi_tb_validate_rsdt(table_info.pointer); | 270 | status = acpi_tb_validate_rsdt(table_info.pointer); |
260 | if (ACPI_FAILURE(status)) { | 271 | if (ACPI_FAILURE(status)) { |
261 | return_ACPI_STATUS(status); | 272 | goto error_cleanup; |
262 | } | 273 | } |
263 | 274 | ||
264 | /* Get the number of tables defined in the RSDT or XSDT */ | 275 | /* Get the number of tables defined in the RSDT or XSDT */ |
@@ -270,14 +281,14 @@ acpi_status acpi_tb_get_table_rsdt(void) | |||
270 | 281 | ||
271 | status = acpi_tb_convert_to_xsdt(&table_info); | 282 | status = acpi_tb_convert_to_xsdt(&table_info); |
272 | if (ACPI_FAILURE(status)) { | 283 | if (ACPI_FAILURE(status)) { |
273 | return_ACPI_STATUS(status); | 284 | goto error_cleanup; |
274 | } | 285 | } |
275 | 286 | ||
276 | /* Save the table pointers and allocation info */ | 287 | /* Save the table pointers and allocation info */ |
277 | 288 | ||
278 | status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_XSDT, &table_info); | 289 | status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_XSDT, &table_info); |
279 | if (ACPI_FAILURE(status)) { | 290 | if (ACPI_FAILURE(status)) { |
280 | return_ACPI_STATUS(status); | 291 | goto error_cleanup; |
281 | } | 292 | } |
282 | 293 | ||
283 | acpi_gbl_XSDT = | 294 | acpi_gbl_XSDT = |
@@ -285,4 +296,12 @@ acpi_status acpi_tb_get_table_rsdt(void) | |||
285 | 296 | ||
286 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT)); | 297 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT)); |
287 | return_ACPI_STATUS(status); | 298 | return_ACPI_STATUS(status); |
299 | |||
300 | error_cleanup: | ||
301 | |||
302 | /* Free table allocated by acpi_tb_get_table */ | ||
303 | |||
304 | acpi_tb_delete_single_table(&table_info); | ||
305 | |||
306 | return_ACPI_STATUS(status); | ||
288 | } | 307 | } |