From patchwork Tue Apr 24 19:35:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Stone X-Patchwork-Id: 10360837 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 3E41C602D6 for ; Tue, 24 Apr 2018 19:35:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2D0A628066 for ; Tue, 24 Apr 2018 19:35:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 202D228346; Tue, 24 Apr 2018 19:35:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A697228066 for ; Tue, 24 Apr 2018 19:35:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751994AbeDXTfk (ORCPT ); Tue, 24 Apr 2018 15:35:40 -0400 Received: from mx1.redhat.com ([209.132.183.28]:41922 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752187AbeDXTfQ (ORCPT ); Tue, 24 Apr 2018 15:35:16 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3BFF930BB7C9; Tue, 24 Apr 2018 19:35:16 +0000 (UTC) Received: from fidelio.ahs3.com (ovpn-117-94.phx2.redhat.com [10.3.117.94]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7A38483B3B; Tue, 24 Apr 2018 19:35:15 +0000 (UTC) From: Al Stone To: linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Al Stone , "Rafael J . Wysocki" , Len Brown Subject: [PATCH v2 2/3] ACPI: ensure acpi_parse_entries_array() does not access non-existent table data Date: Tue, 24 Apr 2018 13:35:04 -0600 Message-Id: <20180424193505.6934-3-ahs3@redhat.com> In-Reply-To: <20180424193505.6934-1-ahs3@redhat.com> References: <20180424193505.6934-1-ahs3@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Tue, 24 Apr 2018 19:35:16 +0000 (UTC) Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP For ACPI tables that have subtables, acpi_parse_entries_array() gets used to step through each of the subtables in memory. The primary loop for this was checking that the beginning location of the subtable being examined plus the length of struct acpi_subtable_header was not beyond the end of the complete ACPI table; if it wasn't, the subtable could be examined, but if it was the loop would terminate as it should. In the middle of this subtable loop, a callback is used to examine the subtable in detail. Should the callback function try to examine elements of the subtable that are located past the subtable header, and the ACPI table containing this subtable has an incorrect length, it is possible to access either invalid or protected memory and cause a fault. And, the length of struct acpi_subtable_header will always be smaller than the length of the actual subtable. To fix this, we make the main loop check that the beginning of the subtable being examined plus the actual length of the subtable does not go past the end of the enclosing ACPI table. While this cannot protect us from malicious callback functions, it can prevent us from failing because of some poorly constructed ACPI tables. Found by inspection. There is no functional change to existing code that is known to work when calling acpi_parse_entries_array(). Signed-off-by: Al Stone Cc: Rafael J. Wysocki Cc: Len Brown --- drivers/acpi/tables.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 21535762b890..c7b028f231a6 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -271,8 +271,7 @@ acpi_parse_entries_array(char *id, unsigned long table_size, entry = (struct acpi_subtable_header *) ((unsigned long)table_header + table_size); - while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) < - table_end) { + while (((unsigned long)entry + entry->length) <= table_end) { if (max_entries && count >= max_entries) break;