[linux] Validate length of ACPI table read from sysfs

Consumers of acpi_find() will assume that returned structures include
a valid table header and that the length in the table header is
correct.  These assumptions are necessary when dealing with raw ACPI
tables, since there exists no independent source of length
information.

Ensure that these assumptions are also valid for ACPI tables read from
sysfs.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
pull/310/head
Michael Brown 2021-03-03 01:55:07 +00:00
parent 50d13907c4
commit 1c4917b6a7
2 changed files with 11 additions and 0 deletions

View File

@ -389,6 +389,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ERRFILE_efi_autoexec ( ERRFILE_OTHER | 0x00540000 ) #define ERRFILE_efi_autoexec ( ERRFILE_OTHER | 0x00540000 )
#define ERRFILE_efi_cachedhcp ( ERRFILE_OTHER | 0x00550000 ) #define ERRFILE_efi_cachedhcp ( ERRFILE_OTHER | 0x00550000 )
#define ERRFILE_linux_sysfs ( ERRFILE_OTHER | 0x00560000 ) #define ERRFILE_linux_sysfs ( ERRFILE_OTHER | 0x00560000 )
#define ERRFILE_linux_acpi ( ERRFILE_OTHER | 0x00570000 )
/** @} */ /** @} */

View File

@ -57,6 +57,7 @@ static LIST_HEAD ( linux_acpi_tables );
*/ */
static userptr_t linux_acpi_find ( uint32_t signature, unsigned int index ) { static userptr_t linux_acpi_find ( uint32_t signature, unsigned int index ) {
struct linux_acpi_table *table; struct linux_acpi_table *table;
struct acpi_header *header;
union { union {
uint32_t signature; uint32_t signature;
char filename[5]; char filename[5];
@ -100,6 +101,14 @@ static userptr_t linux_acpi_find ( uint32_t signature, unsigned int index ) {
filename, strerror ( rc ) ); filename, strerror ( rc ) );
goto err_read; goto err_read;
} }
header = user_to_virt ( table->data, 0 );
if ( ( ( ( size_t ) len ) < sizeof ( *header ) ) ||
( ( ( size_t ) len ) < le32_to_cpu ( header->length ) ) ) {
rc = -ENOENT;
DBGC ( &linux_acpi_tables, "ACPI underlength %s (%d bytes)\n",
filename, len );
goto err_len;
}
/* Add to list of tables */ /* Add to list of tables */
list_add ( &table->list, &linux_acpi_tables ); list_add ( &table->list, &linux_acpi_tables );
@ -107,6 +116,7 @@ static userptr_t linux_acpi_find ( uint32_t signature, unsigned int index ) {
return table->data; return table->data;
err_len:
ufree ( table->data ); ufree ( table->data );
err_read: err_read:
free ( table ); free ( table );