]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[linux] Validate length of ACPI table read from sysfs
authorMichael Brown <mcb30@ipxe.org>
Wed, 3 Mar 2021 01:55:07 +0000 (01:55 +0000)
committerMichael Brown <mcb30@ipxe.org>
Wed, 3 Mar 2021 01:55:07 +0000 (01:55 +0000)
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>
src/include/ipxe/errfile.h
src/interface/linux/linux_acpi.c

index 3daf7bde7ab512800bf1206a56f3f31f8f0959ee..e3bf9f565929d5e5d5942794152a908fe64df7e9 100644 (file)
@@ -389,6 +389,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define ERRFILE_efi_autoexec         ( ERRFILE_OTHER | 0x00540000 )
 #define ERRFILE_efi_cachedhcp        ( ERRFILE_OTHER | 0x00550000 )
 #define ERRFILE_linux_sysfs          ( ERRFILE_OTHER | 0x00560000 )
+#define ERRFILE_linux_acpi           ( ERRFILE_OTHER | 0x00570000 )
 
 /** @} */
 
index 851cc54e6540d21a87b0d64a061242f859fe7ec4..e658936f2a447a9c982d33abbe108f0a0c6e1664 100644 (file)
@@ -57,6 +57,7 @@ static LIST_HEAD ( linux_acpi_tables );
  */
 static userptr_t linux_acpi_find ( uint32_t signature, unsigned int index ) {
        struct linux_acpi_table *table;
+       struct acpi_header *header;
        union {
                uint32_t signature;
                char filename[5];
@@ -100,6 +101,14 @@ static userptr_t linux_acpi_find ( uint32_t signature, unsigned int index ) {
                       filename, strerror ( rc ) );
                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 */
        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;
 
+ err_len:
        ufree ( table->data );
  err_read:
        free ( table );