diff options
author | Dan Williams <dan.j.williams@intel.com> | 2017-04-25 15:58:31 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2017-04-26 18:27:49 -0400 |
commit | 0de0e198bc7191a0e46cf71f66fec4d07ca91396 (patch) | |
tree | c87c76de72cb5ba4f4d93a3b85f4f39ed5b92eaf | |
parent | 5a7ad1146caa895ad718a534399e38bd2ba721b7 (diff) |
ACPI / sysfs: fix acpi_get_table() leak / acpi-sysfs denial of service
Reading an ACPI table through the /sys/firmware/acpi/tables interface
more than 65,536 times leads to the following log message:
ACPI Error: Table ffff88033595eaa8, Validation count is zero after increment
(20170119/tbutils-423)
...and the table being unavailable until the next reboot. Add the
missing acpi_put_table() so the table ->validation_count is decremented
after each read.
Reported-by: Anush Seetharaman <anush.seetharaman@intel.com>
Fixes: 174cc7187e6f "ACPICA: Tables: Back port acpi_get_table_with_size() ..."
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Cc: 4.10+ <stable@vger.kernel.org> # 4.10+
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/acpi/sysfs.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index cf05ae973381..5180fef9eb49 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c | |||
@@ -333,14 +333,17 @@ static ssize_t acpi_table_show(struct file *filp, struct kobject *kobj, | |||
333 | container_of(bin_attr, struct acpi_table_attr, attr); | 333 | container_of(bin_attr, struct acpi_table_attr, attr); |
334 | struct acpi_table_header *table_header = NULL; | 334 | struct acpi_table_header *table_header = NULL; |
335 | acpi_status status; | 335 | acpi_status status; |
336 | ssize_t rc; | ||
336 | 337 | ||
337 | status = acpi_get_table(table_attr->name, table_attr->instance, | 338 | status = acpi_get_table(table_attr->name, table_attr->instance, |
338 | &table_header); | 339 | &table_header); |
339 | if (ACPI_FAILURE(status)) | 340 | if (ACPI_FAILURE(status)) |
340 | return -ENODEV; | 341 | return -ENODEV; |
341 | 342 | ||
342 | return memory_read_from_buffer(buf, count, &offset, | 343 | rc = memory_read_from_buffer(buf, count, &offset, table_header, |
343 | table_header, table_header->length); | 344 | table_header->length); |
345 | acpi_put_table(table_header); | ||
346 | return rc; | ||
344 | } | 347 | } |
345 | 348 | ||
346 | static int acpi_table_attr_init(struct kobject *tables_obj, | 349 | static int acpi_table_attr_init(struct kobject *tables_obj, |