]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.14.111/efi-cper-fix-possible-out-of-bounds-access.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.14.111 / efi-cper-fix-possible-out-of-bounds-access.patch
CommitLineData
04fd09d4
SL
1From 4762198f67971267219148d22af61719cd9110fe Mon Sep 17 00:00:00 2001
2From: Ross Lagerwall <ross.lagerwall@citrix.com>
3Date: Mon, 28 Jan 2019 10:04:24 +0000
4Subject: efi: cper: Fix possible out-of-bounds access
5
6[ Upstream commit 45b14a4ffcc1e0b5caa246638f942cbe7eaea7ad ]
7
8When checking a generic status block, we iterate over all the generic
9data blocks. The loop condition only checks that the start of the
10generic data block is valid (within estatus->data_length) but not the
11whole block. Because the size of data blocks (excluding error data) may
12vary depending on the revision and the revision is contained within the
13data block, ensure that enough of the current data block is valid before
14dereferencing any members otherwise an out-of-bounds access may occur if
15estatus->data_length is invalid.
16
17This relies on the fact that struct acpi_hest_generic_data_v300 is a
18superset of the earlier version. Also rework the other checks to avoid
19potential underflow.
20
21Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
22Acked-by: Borislav Petkov <bp@suse.de>
23Tested-by: Tyler Baicar <baicar.tyler@gmail.com>
24Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
25Signed-off-by: Sasha Levin <sashal@kernel.org>
26---
27 drivers/firmware/efi/cper.c | 13 +++++++++----
28 1 file changed, 9 insertions(+), 4 deletions(-)
29
30diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
31index d2fcafcea07e..ce23d5402bd6 100644
32--- a/drivers/firmware/efi/cper.c
33+++ b/drivers/firmware/efi/cper.c
34@@ -641,19 +641,24 @@ EXPORT_SYMBOL_GPL(cper_estatus_check_header);
35 int cper_estatus_check(const struct acpi_hest_generic_status *estatus)
36 {
37 struct acpi_hest_generic_data *gdata;
38- unsigned int data_len, gedata_len;
39+ unsigned int data_len, record_size;
40 int rc;
41
42 rc = cper_estatus_check_header(estatus);
43 if (rc)
44 return rc;
45+
46 data_len = estatus->data_length;
47
48 apei_estatus_for_each_section(estatus, gdata) {
49- gedata_len = acpi_hest_get_error_length(gdata);
50- if (gedata_len > data_len - acpi_hest_get_size(gdata))
51+ if (sizeof(struct acpi_hest_generic_data) > data_len)
52+ return -EINVAL;
53+
54+ record_size = acpi_hest_get_record_size(gdata);
55+ if (record_size > data_len)
56 return -EINVAL;
57- data_len -= acpi_hest_get_record_size(gdata);
58+
59+ data_len -= record_size;
60 }
61 if (data_len)
62 return -EINVAL;
63--
642.19.1
65