Skip to content

Commit

Permalink
[acpi] Compute and check checksum for ACPI tables
Browse files Browse the repository at this point in the history
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
Laurent Gourvénec authored and mcb30 committed Jul 28, 2017
1 parent 8866c91 commit 041d362
Showing 1 changed file with 37 additions and 6 deletions.
43 changes: 37 additions & 6 deletions src/core/acpi.c
Expand Up @@ -42,19 +42,41 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
******************************************************************************
*/

/**
* Compute ACPI table checksum
*
* @v table Any ACPI table
* @ret checksum 0 if checksum is good
*/
static uint8_t acpi_checksum ( userptr_t table ) {
struct acpi_header acpi;
uint8_t sum = 0;
uint8_t data;
unsigned int i;

/* Read table length */
copy_from_user ( &acpi.length, table,
offsetof ( typeof ( acpi ), length ),
sizeof ( acpi.length ) );

/* Compute checksum */
for ( i = 0 ; i < le32_to_cpu ( acpi.length ) ; i++ ) {
copy_from_user ( &data, table, i, sizeof ( data ) );
sum += data;
}

return sum;
}

/**
* Fix up ACPI table checksum
*
* @v acpi ACPI table header
*/
void acpi_fix_checksum ( struct acpi_header *acpi ) {
unsigned int i = 0;
uint8_t sum = 0;

for ( i = 0 ; i < acpi->length ; i++ ) {
sum += *( ( ( uint8_t * ) acpi ) + i );
}
acpi->checksum -= sum;
/* Update checksum */
acpi->checksum -= acpi_checksum ( virt_to_user ( acpi ) );
}

/**
Expand Down Expand Up @@ -123,6 +145,15 @@ userptr_t acpi_find ( uint32_t signature, unsigned int index ) {
if ( index-- )
continue;

/* Check table integrity */
if ( acpi_checksum ( table ) != 0 ) {
DBGC ( rsdt, "RSDT %#08lx found %s with bad checksum "
"at %08lx\n", user_to_phys ( rsdt, 0 ),
acpi_name ( signature ),
user_to_phys ( table, 0 ) );
break;
}

DBGC ( rsdt, "RSDT %#08lx found %s at %08lx\n",
user_to_phys ( rsdt, 0 ), acpi_name ( signature ),
user_to_phys ( table, 0 ) );
Expand Down

0 comments on commit 041d362

Please sign in to comment.