Skip to content

Commit

Permalink
acpi, nfit: validate ars_status output buffer size
Browse files Browse the repository at this point in the history
If an ARS Status command returns truncated output, do not process
partial records or otherwise consume non-status fields.

Cc: <[email protected]>
Fixes: 0caeef6 ("libnvdimm: Add a poison list and export badblocks")
Signed-off-by: Dan Williams <[email protected]>
  • Loading branch information
djbw committed Dec 7, 2016
1 parent efda1b5 commit 82aa37c
Showing 1 changed file with 17 additions and 4 deletions.
21 changes: 17 additions & 4 deletions drivers/acpi/nfit/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
* then just continue with the returned results.
*/
if (status == NFIT_ARS_STATUS_INTR) {
if (ars_status->flags & NFIT_ARS_F_OVERFLOW)
if (ars_status->out_length >= 40 && (ars_status->flags
& NFIT_ARS_F_OVERFLOW))
return -ENOSPC;
return 0;
}
Expand Down Expand Up @@ -2002,19 +2003,32 @@ static int ars_get_status(struct acpi_nfit_desc *acpi_desc)
return cmd_rc;
}

static int ars_status_process_records(struct nvdimm_bus *nvdimm_bus,
static int ars_status_process_records(struct acpi_nfit_desc *acpi_desc,
struct nd_cmd_ars_status *ars_status)
{
struct nvdimm_bus *nvdimm_bus = acpi_desc->nvdimm_bus;
int rc;
u32 i;

/*
* First record starts at 44 byte offset from the start of the
* payload.
*/
if (ars_status->out_length < 44)
return 0;
for (i = 0; i < ars_status->num_records; i++) {
/* only process full records */
if (ars_status->out_length
< 44 + sizeof(struct nd_ars_record) * (i + 1))
break;
rc = nvdimm_bus_add_poison(nvdimm_bus,
ars_status->records[i].err_address,
ars_status->records[i].length);
if (rc)
return rc;
}
if (i < ars_status->num_records)
dev_warn(acpi_desc->dev, "detected truncated ars results\n");

return 0;
}
Expand Down Expand Up @@ -2267,8 +2281,7 @@ static int acpi_nfit_query_poison(struct acpi_nfit_desc *acpi_desc,
if (rc < 0 && rc != -ENOSPC)
return rc;

if (ars_status_process_records(acpi_desc->nvdimm_bus,
acpi_desc->ars_status))
if (ars_status_process_records(acpi_desc, acpi_desc->ars_status))
return -ENOMEM;

return 0;
Expand Down

0 comments on commit 82aa37c

Please sign in to comment.