Skip to content

Commit 1c0d9b1

Browse files
rosslagerwallrafaeljw
authored andcommitted
ACPI: APEI: Fix possible out-of-bounds access to BERT region
Check that the length recorded in the generic error status block is within the region before checking the contents of the region itself. Otherwise it may result in an out-of-bounds access if the system firmware has generated a status block with an invalid length (larger than the mapped region). Also move the block_status check so that it only happens after the block has been verified to be within the mapped region. Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com> Acked-by: Borislav Petkov <bp@suse.de> Tested-by: Tyler Baicar <baicar.tyler@gmail.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent a2ed1ee commit 1c0d9b1

File tree

1 file changed

+10
-13
lines changed

1 file changed

+10
-13
lines changed

drivers/acpi/apei/bert.c

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,23 @@ static void __init bert_print_all(struct acpi_bert_region *region,
4242
int remain = region_len;
4343
u32 estatus_len;
4444

45-
if (!estatus->block_status)
46-
return;
47-
48-
while (remain > sizeof(struct acpi_bert_region)) {
49-
if (cper_estatus_check(estatus)) {
50-
pr_err(FW_BUG "Invalid error record.\n");
51-
return;
52-
}
53-
45+
while (remain >= sizeof(struct acpi_bert_region)) {
5446
estatus_len = cper_estatus_len(estatus);
5547
if (remain < estatus_len) {
5648
pr_err(FW_BUG "Truncated status block (length: %u).\n",
5749
estatus_len);
5850
return;
5951
}
6052

53+
/* No more error records. */
54+
if (!estatus->block_status)
55+
return;
56+
57+
if (cper_estatus_check(estatus)) {
58+
pr_err(FW_BUG "Invalid error record.\n");
59+
return;
60+
}
61+
6162
pr_info_once("Error records from previous boot:\n");
6263

6364
cper_estatus_print(KERN_INFO HW_ERR, estatus);
@@ -70,10 +71,6 @@ static void __init bert_print_all(struct acpi_bert_region *region,
7071
estatus->block_status = 0;
7172

7273
estatus = (void *)estatus + estatus_len;
73-
/* No more error records. */
74-
if (!estatus->block_status)
75-
return;
76-
7774
remain -= estatus_len;
7875
}
7976
}

0 commit comments

Comments
 (0)