acpi, nfit: validate ars_status output buffer size
If an ARS Status command returns truncated output, do not process
partial records or otherwise consume non-status fields.
Cc: <stable@vger.kernel.org>
Fixes: 0caeef63e6
("libnvdimm: Add a poison list and export badblocks")
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
efda1b5d87
commit
82aa37cf09
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue