[PATCH 2/2] acpi: acpidump: check for zero length headers to stop segfaulting (LP: #1375300)
Alex Hung
alex.hung at canonical.com
Wed Oct 1 03:08:23 UTC 2014
On 14-09-29 11:00 PM, Colin King wrote:
> From: Colin Ian King <colin.king at canonical.com>
>
> There are a bunch of places in fwts acpidump that takes the
> given table header sizes and sub-table sizes as given,
> however, firmware can get this wrong.
>
> So bail out early on bad looking header sizes rather than
> believe the data and fall off the end of the table.
>
> Signed-off-by: Colin Ian King <colin.king at canonical.com>
> ---
> src/acpi/acpidump/acpidump.c | 25 ++++++++++++++++++++++---
> 1 file changed, 22 insertions(+), 3 deletions(-)
>
> diff --git a/src/acpi/acpidump/acpidump.c b/src/acpi/acpidump/acpidump.c
> index b42363c..daad644 100644
> --- a/src/acpi/acpidump/acpidump.c
> +++ b/src/acpi/acpidump/acpidump.c
> @@ -1055,6 +1055,9 @@ static void acpidump_slit(fwts_framework *fw, const fwts_acpi_table_info *table)
> uint64_t n = table->length - sizeof(fwts_acpi_table_slit);
> const uint8_t *entry;
>
> + if (table->length < sizeof(fwts_acpi_table_slit))
> + return;
> +
> fwts_log_info_verbatum(fw, "# Sys Localities: 0x%" PRIx64 "(%" PRIu64 ")",
> slit->num_of_system_localities, slit->num_of_system_localities);
> if (n < slit->num_of_system_localities * slit->num_of_system_localities) {
> @@ -1303,6 +1306,8 @@ static void acpidump_asf(fwts_framework *fw, const fwts_acpi_table_info *table)
> break; /* Unknown! */
> }
>
> + if (hdr->length == 0)
> + break;
> ptr += hdr->length; /* Jump to next header */
>
> if (type & 0x80) /* Last record indicator, top bit of type field */
> @@ -1333,18 +1338,22 @@ static void acpidump_dmar_device_scope(
>
> /* Parse through multiple device scope entries */
> while (length > 0) {
> - unsigned int i;
> + ssize_t i, len;
>
> fwts_acpi_table_dmar_device_scope *device_scope_entry =
> (fwts_acpi_table_dmar_device_scope *)device_scope;
> __acpi_dump_table_fields(fw, device_scope, dmar_device_scope_fields, device_scope - data);
> + len = device_scope_entry->length - sizeof(fwts_acpi_table_dmar_device_scope);
> + /* Something not good about the data */
> + if (len <= 0)
> + break;
> /*
> * The device scope has a variable length path,
> * so just dump this raw data out for now.
> */
> - for (i = 0; i < device_scope_entry->length - sizeof(fwts_acpi_table_dmar_device_scope); i++) {
> + for (i = 0; i < len; i++) {
> uint8_t val8 = device_scope_entry->path[i];
> - fwts_log_info_verbatum(fw, "%s 0x%2.2x [%d]", acpi_dump_field_info("Path", 1,
> + fwts_log_info_verbatum(fw, "%s 0x%2.2x [%zd]", acpi_dump_field_info("Path", 1,
> (device_scope - data) + sizeof(fwts_acpi_table_dmar_device_scope) + i),
> val8, i);
> }
> @@ -1441,6 +1450,10 @@ static void acpidump_dmar(fwts_framework *fw, const fwts_acpi_table_info *table)
> break;
> }
>
> + /* Something not good with the data */
> + if (header->length == 0)
> + break;
> +
> ptr += header->length;
> }
> }
> @@ -1515,6 +1528,8 @@ static void acpidump_slic(fwts_framework *fw, const fwts_acpi_table_info *table)
> break;
> }
>
> + if (header->length == 0)
> + break;
> ptr += header->length;
> }
> }
> @@ -1756,6 +1771,8 @@ static void acpidump_pcct(fwts_framework *fw, const fwts_acpi_table_info *table)
> default:
> break;
> }
> + if (header->length == 0)
> + break;
> ptr += header->length;
> }
> }
> @@ -1911,6 +1928,8 @@ static void acpidump_dbg2(fwts_framework *fw, const fwts_acpi_table_info *table)
> (void *)oem_data - table->data);
> }
>
> + if (dbg2_info->length == 0)
> + break;
> offset += dbg2_info->length;
> if (offset > table->length)
> break;
Will it be better if fwts output errors when length == 0?
More information about the fwts-devel
mailing list