Verify all table headers, but ignore unrecognized signatures

date	2000.05.10.23.07.00;	author rmoore1;	state Exp;
This commit is contained in:
aystarik 2005-06-29 18:54:41 +00:00
parent a468b354f9
commit 3f4b5115e0
3 changed files with 126 additions and 65 deletions

View File

@ -155,7 +155,10 @@ TbInstallTable (
FUNCTION_TRACE ("TbInstallTable");
/* Check the table signature and make sure it is recognized */
/*
* Check the table signature and make sure it is recognized
* Also checks the header checksum
*/
Status = TbRecognizeTable (TablePtr, TableInfo);
if (ACPI_FAILURE (Status))
@ -180,23 +183,10 @@ TbInstallTable (
return_ACPI_STATUS (Status);
}
DEBUG_PRINT (ACPI_INFO, ("%s located at %p\n",
Gbl_AcpiTableData[TableType].Name, TableHeader));
CmReleaseMutex (MTX_TABLES);
/* Validate checksum for _most_ tables */
if (TableType != TABLE_FACS)
{
/* But don't abort if the checksum is wrong */
/* TBD: make this a configuration option? */
TbVerifyTableChecksum (TableHeader);
}
return_ACPI_STATUS (AE_OK);
}
@ -212,6 +202,13 @@ TbInstallTable (
*
* DESCRIPTION: Check a table signature for a match against known table types
*
* NOTE: All table pointers are validated as follows:
* 1) Table pointer must point to valid physical memory
* 2) Signature must be 4 ASCII chars, even if we don't recognize the name
* 3) Table must be readable for length specified in the header
* 4) Table checksum must be valid (with the exception of the FACS which
* has no checksum for some odd reason)
*
******************************************************************************/
ACPI_STATUS
@ -236,10 +233,9 @@ TbRecognizeTable (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/* Search for a signature match among the known table types */
Status = AE_BAD_SIGNATURE;
Status = AE_SUPPORT;
for (i = 1; i < NUM_ACPI_TABLES; i++) /* Start at one -> Skip RSDP */
{
if (!STRNCMP (TableHeader->Signature, Gbl_AcpiTableData[i].Signature, Gbl_AcpiTableData[i].SigLength))
@ -247,7 +243,7 @@ TbRecognizeTable (
/* Found a signature match, get the pertinent info from the TableData structure */
TableType = i;
Status = Gbl_AcpiTableData[i].Status;
Status = Gbl_AcpiTableData[i].Status; /* AE_SUPPORT or AE_OK */
break;
}
@ -255,43 +251,34 @@ TbRecognizeTable (
/* Return the table type and length via the info struct */
TableInfo->Type = (UINT8) TableType;
TableInfo->Length = TableHeader->Length;
/*
* Bad_Signature means that the table is bad or not one of the recognized tables
*/
if (Status == AE_BAD_SIGNATURE)
{
/* Unknown table */
DEBUG_PRINT (ACPI_ERROR, ("Unknown table at %x in RSDT with signature '%4.4s'\n",
TableHeader, TableHeader->Signature));
REPORT_ERROR ("Unknown table in the RSDT");
TbVerifyTableChecksum (TableHeader);
/*
* TBD: - need to be able to handle multiple unknown tables. Error should be
* displayed when table is displayed, Displaying it here for now
*/
DUMP_BUFFER (TableHeader, 32);
}
TableInfo->Type = (UINT8) TableType;
TableInfo->Length = TableHeader->Length;
/*
* An AE_SUPPORT means that the table was recognized, but is not supported
* Validate checksum for _most_ tables,
* even the ones whose signature we don't recognize
*/
else if (Status == AE_SUPPORT)
if (TableType != TABLE_FACS)
{
/* But don't abort if the checksum is wrong */
/* TBD: make this a configuration option? */
TbVerifyTableChecksum (TableHeader);
}
/*
* An AE_SUPPORT means that the table was not recognized.
* We basically ignore this; just print a debug message
*/
if (Status == AE_SUPPORT)
{
DEBUG_PRINT (ACPI_INFO, ("Unsupported table %s (Type %d) was found and discarded\n",
Gbl_AcpiTableData[TableType].Name, TableType));
}
return_ACPI_STATUS (Status);
}

View File

@ -118,6 +118,7 @@
#include <acpi.h>
#include <tables.h>
#include <interp.h>
#define _COMPONENT TABLE_MANAGER
@ -233,6 +234,63 @@ TbSystemTablePointer (
/******************************************************************************
*
* FUNCTION: TbValidateTableHeader
*
* PARAMETERS: TableHeader - Logical pointer to the table
*
* RETURN: Status
*
* DESCRIPTION: Check an ACPI table header for validity
*
* NOTE: Table pointers are validated as follows:
* 1) Table pointer must point to valid physical memory
* 2) Signature must be 4 ASCII chars, even if we don't recognize the name
* 3) Table must be readable for length specified in the header
* 4) Table checksum must be valid (with the exception of the FACS which
* has no checksum for some odd reason)
*
******************************************************************************/
ACPI_STATUS
TbValidateTableHeader (
ACPI_TABLE_HEADER *TableHeader)
{
/* Verify that this is a valid address */
if (!OsdReadable (TableHeader, sizeof (ACPI_TABLE_HEADER)))
{
DEBUG_PRINT (ACPI_ERROR, ("Cannot read table header at %p\n", TableHeader));
return AE_BAD_ADDRESS;
}
/* Ensure that the signature is 4 ASCII characters */
if (!CmValidAcpiName (*(UINT32 *) TableHeader->Signature))
{
DEBUG_PRINT (ACPI_ERROR, ("Table signature [%X] contains one or more invalid characters\n", *(UINT32 *) TableHeader->Signature));
REPORT_WARNING ("Invalid table signature found");
return AE_BAD_SIGNATURE;
}
/* Validate the table length */
if (TableHeader->Length < (UINT32) sizeof (ACPI_TABLE_HEADER))
{
DEBUG_PRINT (ACPI_ERROR, ("Invalid length in header at %08lXh name %4.4s\n", TableHeader, &TableHeader->Signature));
REPORT_WARNING ("Invalid table header length found");
return AE_BAD_HEADER;
}
return AE_OK;
}
/******************************************************************************
*
* FUNCTION: TbMapAcpiTable
@ -241,6 +299,7 @@ TbSystemTablePointer (
* *Size - Size of the table. If zero, the size
* from the table header is used. Actual
* size is returned here.
* **LogicalAddress - Logical address of mapped table
*
* RETURN: Logical address of the mapped table.
*
@ -248,13 +307,15 @@ TbSystemTablePointer (
*
******************************************************************************/
void *
ACPI_STATUS
TbMapAcpiTable (
void *PhysicalAddress,
UINT32 *Size)
UINT32 *Size,
void **LogicalAddress)
{
ACPI_TABLE_HEADER *Table;
UINT32 TableSize = *Size;
ACPI_STATUS Status = AE_OK;
@ -264,10 +325,19 @@ TbMapAcpiTable (
{
/* Get the table header so we can extract the table length */
Table = OsdMapMemory (PhysicalAddress, sizeof (ACPI_TABLE_HEADER));
if (!Table)
Status = OsdMapMemory (PhysicalAddress, sizeof (ACPI_TABLE_HEADER), &Table);
if (ACPI_FAILURE (Status))
{
return Status;
}
/* Validate the header */
Status = TbValidateTableHeader (Table);
if (ACPI_FAILURE (Status))
{
return NULL;
OsdUnMapMemory (Table, sizeof (ACPI_TABLE_HEADER));
return Status;
}
/* Now we know how large to make the mapping (table + header) */
@ -279,17 +349,19 @@ TbMapAcpiTable (
/* Map the physical memory for the correct length */
Table = OsdMapMemory (PhysicalAddress, TableSize);
if (!Table)
{
return NULL;
}
Status = OsdMapMemory (PhysicalAddress, TableSize, &Table);
if (ACPI_FAILURE (Status))
{
return Status;
}
DEBUG_PRINT (ACPI_INFO, ("Mapped memory for ACPI table, length=%d(0x%X) at %p\n",
DEBUG_PRINT (ACPI_INFO, ("Mapped memory for ACPI table, length=%d(0x%X) at %p\n",
TableSize, TableSize, Table));
*Size = TableSize;
return Table;
*LogicalAddress = Table;
return Status;
}

View File

@ -151,6 +151,7 @@ TbGetTableFacs (
void *TablePtr = NULL;
UINT32 Size;
UINT8 Allocation;
ACPI_STATUS Status = AE_OK;
FUNCTION_TRACE ("TbGetTableFacs");
@ -187,11 +188,11 @@ TbGetTableFacs (
{
/* Just map the physical memory to our address space */
TablePtr = TbMapAcpiTable ((void *) Gbl_FACP->FirmwareCtrl, &Size);
if (!TablePtr)
{
return_ACPI_STATUS (AE_NO_MEMORY);
}
Status = TbMapAcpiTable ((void *) Gbl_FACP->FirmwareCtrl, &Size, &TablePtr);
if (ACPI_FAILURE(Status))
{
return_ACPI_STATUS (Status);
}
/* Save allocation type */
@ -201,10 +202,11 @@ TbGetTableFacs (
/* Return values */
TableInfo->Pointer = TablePtr;
TableInfo->Length = Size;
TableInfo->Allocation = Allocation;
TableInfo->Pointer = TablePtr;
TableInfo->Length = Size;
TableInfo->Allocation = Allocation;
TableInfo->BasePointer = TablePtr;
return_ACPI_STATUS (AE_OK);
return_ACPI_STATUS (Status);
}