From 0a36e49b3a02470caeb8696180a337fc93b816b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laurent=20Gourv=C3=A9nec?= Date: Thu, 27 Jul 2017 16:04:35 +0200 Subject: [PATCH 1/4] [acpi] Compute and check checksum for ACPI tables --- src/core/acpi.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/include/ipxe/acpi.h | 1 + 2 files changed, 41 insertions(+) diff --git a/src/core/acpi.c b/src/core/acpi.c index ff8875e1c1..110591d511 100644 --- a/src/core/acpi.c +++ b/src/core/acpi.c @@ -28,6 +28,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include +#include /** @file * @@ -57,6 +58,37 @@ void acpi_fix_checksum ( struct acpi_header *acpi ) { acpi->checksum -= sum; } +/** + * Check ACPI table checksum + * + * @v table Any ACPI table + * @ret check 0 if checksum is good + */ +int acpi_table_check ( userptr_t table ) { + struct acpi_header acpi; + uint32_t i; + uint8_t *data; + uint8_t sum = 0; + + /* Get header to get length and checksum values */ + copy_from_user ( &acpi, table, 0, sizeof ( acpi ) ); + + /* Get whole table to compute checksum */ + if ( ( data = malloc ( acpi.length ) ) == NULL ) { + DBG ( "Can't malloc\n" ); + return 1; + } + copy_from_user ( data, table, 0, acpi.length ); + + /* Compute checksum */ + for ( i = 0 ; i < acpi.length ; i++ ) + sum += data[i]; + + free ( data ); + + return acpi.checksum == sum; +} + /** * Locate ACPI table * @@ -123,6 +155,14 @@ userptr_t acpi_find ( uint32_t signature, unsigned int index ) { if ( index-- ) continue; + /* Check table integrity */ + if ( acpi_table_check ( table ) ) { + DBGC ( rsdt, "RSDT %#08lx found a table (%s) with bad CRC at %08lx\n", + user_to_phys ( rsdt, 0 ), acpi_name ( signature ), + user_to_phys ( table, 0 ) ); + return UNULL; + } + DBGC ( rsdt, "RSDT %#08lx found %s at %08lx\n", user_to_phys ( rsdt, 0 ), acpi_name ( signature ), user_to_phys ( table, 0 ) ); diff --git a/src/include/ipxe/acpi.h b/src/include/ipxe/acpi.h index 68131e73ac..ef60b7c165 100644 --- a/src/include/ipxe/acpi.h +++ b/src/include/ipxe/acpi.h @@ -233,6 +233,7 @@ acpi_describe ( struct interface *interface ); typeof ( struct acpi_descriptor * ( object_type ) ) extern void acpi_fix_checksum ( struct acpi_header *acpi ); +extern int acpi_table_check ( userptr_t table ); extern userptr_t acpi_find ( uint32_t signature, unsigned int index ); extern int acpi_sx ( uint32_t signature ); extern void acpi_add ( struct acpi_descriptor *desc ); From f178a7cea8671f0c57b23a71dec16be94333cd60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laurent=20Gourv=C3=A9nec?= Date: Fri, 28 Jul 2017 16:14:50 +0200 Subject: [PATCH 2/4] fixup! [acpi] Compute and check checksum for ACPI tables --- src/core/acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/acpi.c b/src/core/acpi.c index 110591d511..d702f6faf7 100644 --- a/src/core/acpi.c +++ b/src/core/acpi.c @@ -157,7 +157,7 @@ userptr_t acpi_find ( uint32_t signature, unsigned int index ) { /* Check table integrity */ if ( acpi_table_check ( table ) ) { - DBGC ( rsdt, "RSDT %#08lx found a table (%s) with bad CRC at %08lx\n", + DBGC ( rsdt, "RSDT %#08lx found a table (%s) with bad checksum at %08lx\n", user_to_phys ( rsdt, 0 ), acpi_name ( signature ), user_to_phys ( table, 0 ) ); return UNULL; From 5ee9cb70e7af805aa8095389457dbb3c07c85120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laurent=20Gourv=C3=A9nec?= Date: Fri, 28 Jul 2017 16:15:33 +0200 Subject: [PATCH 3/4] fixup! [acpi] Compute and check checksum for ACPI tables --- src/core/acpi.c | 30 +++++++++++------------------- src/include/ipxe/acpi.h | 2 +- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/src/core/acpi.c b/src/core/acpi.c index d702f6faf7..9b588df290 100644 --- a/src/core/acpi.c +++ b/src/core/acpi.c @@ -28,7 +28,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include -#include /** @file * @@ -59,34 +58,27 @@ void acpi_fix_checksum ( struct acpi_header *acpi ) { } /** - * Check ACPI table checksum + * Compute ACPI table checksum * * @v table Any ACPI table - * @ret check 0 if checksum is good + * @ret checksum 0 if checksum is good */ -int acpi_table_check ( userptr_t table ) { +uint8_t acpi_checksum ( userptr_t table ) { struct acpi_header acpi; uint32_t i; - uint8_t *data; + uint8_t data; uint8_t sum = 0; - /* Get header to get length and checksum values */ + /* Get header to get length */ copy_from_user ( &acpi, table, 0, sizeof ( acpi ) ); - /* Get whole table to compute checksum */ - if ( ( data = malloc ( acpi.length ) ) == NULL ) { - DBG ( "Can't malloc\n" ); - return 1; - } - copy_from_user ( data, table, 0, acpi.length ); - /* Compute checksum */ - for ( i = 0 ; i < acpi.length ; i++ ) - sum += data[i]; - - free ( data ); + for ( i = 0 ; i < acpi.length ; i++ ) { + copy_from_user ( &data, table, i, 1 ); + sum += data; + } - return acpi.checksum == sum; + return sum; } /** @@ -156,7 +148,7 @@ userptr_t acpi_find ( uint32_t signature, unsigned int index ) { continue; /* Check table integrity */ - if ( acpi_table_check ( table ) ) { + if ( acpi_checksum ( table ) != 0 ) { DBGC ( rsdt, "RSDT %#08lx found a table (%s) with bad checksum at %08lx\n", user_to_phys ( rsdt, 0 ), acpi_name ( signature ), user_to_phys ( table, 0 ) ); diff --git a/src/include/ipxe/acpi.h b/src/include/ipxe/acpi.h index ef60b7c165..f65d9236f6 100644 --- a/src/include/ipxe/acpi.h +++ b/src/include/ipxe/acpi.h @@ -233,7 +233,7 @@ acpi_describe ( struct interface *interface ); typeof ( struct acpi_descriptor * ( object_type ) ) extern void acpi_fix_checksum ( struct acpi_header *acpi ); -extern int acpi_table_check ( userptr_t table ); +extern uint8_t acpi_checksum ( userptr_t table ); extern userptr_t acpi_find ( uint32_t signature, unsigned int index ); extern int acpi_sx ( uint32_t signature ); extern void acpi_add ( struct acpi_descriptor *desc ); From 7cd9170a3c4c83032989940d2ba36878bcb257fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laurent=20Gourv=C3=A9nec?= Date: Fri, 28 Jul 2017 16:15:44 +0200 Subject: [PATCH 4/4] fixup! [acpi] Compute and check checksum for ACPI tables --- src/core/acpi.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/core/acpi.c b/src/core/acpi.c index 9b588df290..cb167bb8a5 100644 --- a/src/core/acpi.c +++ b/src/core/acpi.c @@ -48,13 +48,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * @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; + acpi->checksum -= acpi_checksum ( virt_to_user ( acpi ) ); } /**