ACK: [PATCH][V2] uefi: add a test for sanity checking for the UEFI Boot path (LP: #1316019)

Keng-Yu Lin keng-yu.lin at canonical.com
Thu Jul 10 08:06:54 UTC 2014


On Wed, Jun 11, 2014 at 1:25 AM, Alex Hung <alex.hung at canonical.com> wrote:
> On 05/22/2014 11:01 PM, Ivan Hu wrote:
>> Add the sanity checking for UEFI Boot Path Boot####.
>>
>> Signed-off-by: Ivan Hu <ivan.hu at canonical.com>
>> ---
>>  .../arg-show-tests-0001/arg-show-tests-0001.log    |    2 +
>>  .../arg-show-tests-full-0001.log                   |    6 +-
>>  src/Makefile.am                                    |    3 +-
>>  src/lib/include/fwts_uefi.h                        |   16 +-
>>  src/uefi/uefibootpath/uefibootpath.c               |  794 ++++++++++++++++++++
>>  5 files changed, 818 insertions(+), 3 deletions(-)
>>  create mode 100644 src/uefi/uefibootpath/uefibootpath.c
>>
>> diff --git a/fwts-test/arg-show-tests-0001/arg-show-tests-0001.log b/fwts-test/arg-show-tests-0001/arg-show-tests-0001.log
>> index 9833208..1e82885 100644
>> --- a/fwts-test/arg-show-tests-0001/arg-show-tests-0001.log
>> +++ b/fwts-test/arg-show-tests-0001/arg-show-tests-0001.log
>> @@ -37,6 +37,7 @@ Batch tests:
>>   pnp             BIOS Support Installation structure test.
>>   securebootcert  UEFI secure boot test.
>>   syntaxcheck     Re-assemble DSDT and find syntax errors and warnings.
>> + uefibootpath    Sanity check for UEFI Boot Path Boot####.
>>   version         Gather kernel system information.
>>   virt            CPU Virtualisation Configuration test.
>>   wakealarm       ACPI Wakealarm tests.
>> @@ -77,6 +78,7 @@ Unsafe tests:
>>  UEFI tests:
>>   csm             UEFI Compatibility Support Module test.
>>   securebootcert  UEFI secure boot test.
>> + uefibootpath    Sanity check for UEFI Boot Path Boot####.
>>   uefirtmisc      UEFI miscellaneous runtime service interface tests.
>>   uefirttime      UEFI Runtime service time interface tests.
>>   uefirtvariable  UEFI Runtime service variable interface tests.
>> diff --git a/fwts-test/arg-show-tests-full-0001/arg-show-tests-full-0001.log b/fwts-test/arg-show-tests-full-0001/arg-show-tests-full-0001.log
>> index 074a0f1..a9e743b 100644
>> --- a/fwts-test/arg-show-tests-full-0001/arg-show-tests-full-0001.log
>> +++ b/fwts-test/arg-show-tests-full-0001/arg-show-tests-full-0001.log
>> @@ -258,6 +258,8 @@ Batch tests:
>>   syntaxcheck     (2 tests):
>>    Disassemble and reassemble DSDT
>>    Disassemble and reassemble SSDT
>> + uefibootpath    (1 test):
>> +  Test UEFI Boot Path Boot####.
>>   version         (4 tests):
>>    Gather kernel signature.
>>    Gather kernel system information.
>> @@ -350,6 +352,8 @@ UEFI tests:
>>    UEFI Compatibility Support Module test.
>>   securebootcert  (1 test):
>>    UEFI secure boot test.
>> + uefibootpath    (1 test):
>> +  Test UEFI Boot Path Boot####.
>>   uefirtmisc      (2 tests):
>>    Test for UEFI miscellaneous runtime service interfaces.
>>    Stress test for UEFI miscellaneous runtime service interfaces.
>> @@ -367,4 +371,4 @@ UEFI tests:
>>    Test UEFI RT service set variable interface stress test.
>>    Test UEFI RT service query variable info interface stress test.
>>
>> -Total of 286 tests
>> +Total of 288 tests
>> diff --git a/src/Makefile.am b/src/Makefile.am
>> index 492eb46..8de4331 100644
>> --- a/src/Makefile.am
>> +++ b/src/Makefile.am
>> @@ -89,7 +89,8 @@ fwts_SOURCES = main.c                               \
>>       uefi/uefirtvariable/uefirtvariable.c    \
>>       uefi/uefirtmisc/uefirtmisc.c            \
>>       uefi/securebootcert/securebootcert.c    \
>> -     uefi/uefivarinfo/uefivarinfo.c
>> +     uefi/uefivarinfo/uefivarinfo.c          \
>> +     uefi/uefibootpath/uefibootpath.c
>>
>>  fwts_LDFLAGS = -lm
>>
>> diff --git a/src/lib/include/fwts_uefi.h b/src/lib/include/fwts_uefi.h
>> index b28901f..ff2d2b4 100644
>> --- a/src/lib/include/fwts_uefi.h
>> +++ b/src/lib/include/fwts_uefi.h
>> @@ -239,7 +239,8 @@ typedef enum {
>>       FWTS_UEFI_FILE_PATH_DEVICE_PATH_SUBTYPE =       (0x04),
>>       FWTS_UEFI_PROTOCOL_DEVICE_PATH_SUBTYPE =        (0x05),
>>       FWTS_UEFI_PIWG_FW_FILE_DEVICE_PATH_SUBTYPE =    (0x06),
>> -     FWTS_UEFI_PIWG_FW_VOLUME_DEVICE_PATH_SUBTYPE =  (0x07)
>> +     FWTS_UEFI_PIWG_FW_VOLUME_DEVICE_PATH_SUBTYPE =  (0x07),
>> +     FWTS_UEFI_RELATIVE_OFFSET_RANGE_SUBTYPE =       (0x08)
>>  } media_dev_path_subtypes;
>>
>>  typedef enum {
>> @@ -425,6 +426,12 @@ typedef struct {
>>  typedef struct {
>>       fwts_uefi_dev_path dev_path;
>>       fwts_uefi_guid guid;
>> +     uint32_t flow_control_map;
>> +} __attribute__((packed)) fwts_uefi_uart_flowctl_messaging_dev_path;
>> +
>> +typedef struct {
>> +     fwts_uefi_dev_path dev_path;
>> +     fwts_uefi_guid guid;
>>       uint32_t reserved;
>>       uint64_t sas_addr;
>>       uint64_t lun;
>> @@ -532,6 +539,13 @@ typedef struct {
>>
>>  typedef struct {
>>       fwts_uefi_dev_path dev_path;
>> +     uint32_t reserved;
>> +     uint64_t starting_offset;
>> +     uint64_t ending_offset;
>> +} __attribute__((packed)) fwts_relative_offset_range_path;
>> +
>> +typedef struct {
>> +     fwts_uefi_dev_path dev_path;
>>       uint16_t device_type;
>>       uint16_t status_flags;
>>       char description[0];
>> diff --git a/src/uefi/uefibootpath/uefibootpath.c b/src/uefi/uefibootpath/uefibootpath.c
>> new file mode 100644
>> index 0000000..007aa0f
>> --- /dev/null
>> +++ b/src/uefi/uefibootpath/uefibootpath.c
>> @@ -0,0 +1,794 @@
>> +/*
>> + * Copyright (C) 2014 Canonical
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License
>> + * as published by the Free Software Foundation; either version 2
>> + * of the License, or (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
>> + *
>> + */
>> +
>> +#include <inttypes.h>
>> +#include <stddef.h>
>> +#include <ctype.h>
>> +
>> +#include "fwts.h"
>> +#include "fwts_uefi.h"
>> +
>> +static int errors;
>> +
>> +static inline bool uefibootpath_check_pnpid(uint32_t id)
>> +{
>> +     return (id & 0xFFFF) == 0x41D0;
>> +}
>> +
>> +static int uefibootpath_init(fwts_framework *fw)
>> +{
>> +     if (fwts_firmware_detect() != FWTS_FIRMWARE_UEFI) {
>> +             fwts_log_info(fw, "Cannot detect any UEFI firmware. Aborted.");
>> +             return FWTS_ABORTED;
>> +     }
>> +
>> +     return FWTS_OK;
>> +}
>> +
>> +static int *uefibootpath_check_dev_path(fwts_framework *fw, fwts_uefi_dev_path *dev_path, const size_t dev_path_len)
>> +{
>> +     uint16_t len;
>> +
>> +     len = dev_path->length[0] | (((uint16_t)dev_path->length[1]) << 8);
>> +
>> +     switch (dev_path->type & 0x7f) {
>> +     case FWTS_UEFI_END_DEV_PATH_TYPE:
>> +             switch (dev_path->subtype) {
>> +             case FWTS_UEFI_END_ENTIRE_DEV_PATH_SUBTYPE:
>> +             case FWTS_UEFI_END_THIS_DEV_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIEndHwDevPathLength",
>> +                                     "The length of End of Hardware Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             default:
>> +                     fwts_log_info_verbatum(fw, "Unknow subtype of End of Hardware Device Path.");
>> +                     break;
>> +             }
>> +             break;
>> +
>> +     case FWTS_UEFI_HARDWARE_DEV_PATH_TYPE:
>> +             switch (dev_path->subtype) {
>> +             case FWTS_UEFI_PCI_DEV_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_pci_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIPCIDevPathLength",
>> +                                     "The length of PCI Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_pci_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_PCCARD_DEV_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_pccard_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIPCCARDDevPathLength",
>> +                                     "The length of PCCARD Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_pccard_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_MEMORY_MAPPED_DEV_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_mem_mapped_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIMemoryMapDevPathLength",
>> +                                     "The length of Memory Mapped Device Path  is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_mem_mapped_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_VENDOR_DEV_PATH_SUBTYPE:
>> +                     if (len < (sizeof(fwts_uefi_vendor_dev_path) - sizeof(uint8_t))) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIVendorDevPathLength",
>> +                                     "The length of Vendor Device Path is %" PRIu16 " bytes "
>> +                                     "should not be smaller than UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)(sizeof(fwts_uefi_vendor_dev_path) - sizeof(uint8_t)));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_CONTROLLER_DEV_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_controller_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIControllerDevPathLength",
>> +                                     "The length of Controller Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_controller_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             default:
>> +                     fwts_log_info_verbatum(fw, "Unknow subtype of Hardware Device Path.");
>> +                     break;
>> +             }
>> +             break;
>> +
>> +     case FWTS_UEFI_ACPI_DEVICE_PATH_TYPE:
>> +             switch (dev_path->subtype) {
>> +             case FWTS_UEFI_ACPI_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_acpi_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIACPIDevPathLength",
>> +                                     "The length of ACPI Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_acpi_dev_path));
>> +                             errors++;
>> +                     }
>> +
>> +                     fwts_uefi_acpi_dev_path *a = (fwts_uefi_acpi_dev_path *)dev_path;
>> +                     if (!uefibootpath_check_pnpid(a->hid)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIACPIDevPathPnPId",
>> +                                     "The ID value 0x%" PRIx32 " is not complied with "
>> +                                     "the compressed EISA-type ID.",
>> +                                     a->hid);
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE:
>> +                     if (len < (sizeof(fwts_uefi_expanded_acpi_dev_path) + 2*sizeof(char))) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIExpACPIDevPathLength",
>> +                                     "The length of Expanded ACPI Device Path is %" PRIu16 " bytes "
>> +                                     "should not be smaller than UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)(sizeof(fwts_uefi_expanded_acpi_dev_path) + 2*sizeof(char)));
>> +                             errors++;
>> +                     }
>> +
>> +                     fwts_uefi_expanded_acpi_dev_path *e = (fwts_uefi_expanded_acpi_dev_path *)dev_path;
>> +                     if (!uefibootpath_check_pnpid(e->hid)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIExpACPIDevPathPnPId",
>> +                                     "The ID value 0x%" PRIx32 " is not complied with "
>> +                                     "the compressed EISA-type ID.",
>> +                                     e->hid);
>> +                             errors++;
>> +                     }
>> +
>> +                     if (!uefibootpath_check_pnpid(e->cid)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIExpACPIDevPathPnPId",
>> +                                     "The ID value 0x%" PRIx32 " is not complied with "
>> +                                     "the compressed EISA-type ID.",
>> +                                     e->cid);
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_ACPI_ADR_DEVICE_PATH_SUBTYPE:
>> +                     if (len < sizeof(fwts_uefi_acpi_adr_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIADRDevPathLength",
>> +                                     "The length of _ADR Device Path is %" PRIu16 " bytes "
>> +                                     "should not be smaller than UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_acpi_adr_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             default:
>> +                     fwts_log_info_verbatum(fw, "Unknow subtype of ACPI Device Path.");
>> +                     break;
>> +             }
>> +             break;
>> +
>> +     case FWTS_UEFI_MESSAGING_DEVICE_PATH_TYPE:
>> +             switch (dev_path->subtype) {
>> +             case FWTS_UEFI_ATAPI_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_atapi_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIATAPIDevPathLength",
>> +                                     "The length of ATAPI Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_atapi_dev_path));
>> +                             errors++;
>> +                             break;
>> +                     }
>> +
>> +                     fwts_uefi_atapi_dev_path *a = (fwts_uefi_atapi_dev_path *)dev_path;
>> +                     if (a->primary_secondary > 1) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIATAPIDevPathConfInvalid",
>> +                                     "The PrimarySecondary value of ATAPI Device Path is %" PRIu8
>> +                                     " which is out of configuration range.",
>> +                                     a->primary_secondary);
>> +                             errors++;
>> +                     }
>> +                     if (a->slave_master > 1) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIATAPIDevPathConfInvalid",
>> +                                     "The SlaveMaster value of ATAPI Device Path is %" PRIu8
>> +                                     " which is out of configuration range.",
>> +                                     a->slave_master);
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_SCSI_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_scsi_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFISCSIDevPathLength",
>> +                                     "The length of SCSI Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_scsi_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_fibre_channel_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIFibreChannelDevPathLength",
>> +                                     "The length of Fibre Channel Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_fibre_channel_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_1394_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_1394_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFI1394DevPathLength",
>> +                                     "The length of 1394 Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_1394_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_USB_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_usb_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIUSBDevPathLength",
>> +                                     "The length of USB Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_usb_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_USB_CLASS_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_usb_class_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIUSBClassDevPathLength",
>> +                                     "The length of USB Class Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_usb_class_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_I2O_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_i2o_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFII2ODevPathLength",
>> +                                     "The length of i2o Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_i2o_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_mac_addr_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIMACAddrDevPathLength",
>> +                                     "The length of MAC Address Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_mac_addr_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_IPV4_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_ipv4_dev_path_v2) && len != sizeof(fwts_uefi_ipv4_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIIPv4DevPathLength",
>> +                                     "The length of IPv4 Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_ipv4_dev_path));
>> +                             errors++;
>> +                             break;
>> +                     }
>> +
>> +                     fwts_uefi_ipv4_dev_path *i4 = (fwts_uefi_ipv4_dev_path *)dev_path;
>> +                     if (i4->static_ip_address > 1) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIIPv4DevPathConfInvalid",
>> +                                     "The StaticIPAddress value of IPv4 Device Path is %" PRIu8
>> +                                     " which is out of configuration range.",
>> +                                     i4->static_ip_address);
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_IPV6_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_ipv6_dev_path_v2) && len != sizeof(fwts_uefi_ipv6_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIIPv6DevPathLength",
>> +                                     "The length of IPv6 Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_ipv6_dev_path));
>> +                             errors++;
>> +                             break;
>> +                     }
>> +
>> +                     fwts_uefi_ipv6_dev_path *i6 = (fwts_uefi_ipv6_dev_path *)dev_path;
>> +                     if (i6->static_ip_address > 2) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIIPV6DevPathConfInvalid",
>> +                                     "The IPAddressOrigin value of IPv6 Device Path is %" PRIu8
>> +                                     " which is out of configuration range.",
>> +                                     i6->static_ip_address);
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_INFINIBAND_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_infiniband_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIInfiniBandDevPathLength",
>> +                                     "The length of InfiniBand Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_infiniband_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_UART_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_uart_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIUARTDevPathLength",
>> +                                     "The length of UART Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_uart_dev_path));
>> +                             errors++;
>> +                             break;
>> +                     }
>> +
>> +                     fwts_uefi_uart_dev_path *u = (fwts_uefi_uart_dev_path *)dev_path;
>> +                     if (u->parity > 5) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIUARTDevPathConfInvalid",
>> +                                     "The Parity value of UART Device Path is %" PRIu8
>> +                                     " which is out of configuration range.",
>> +                                     u->parity);
>> +                             errors++;
>> +                     }
>> +                     if (u->stop_bits > 3) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIUARTDevPathConfInvalid",
>> +                                     "The Parity value of UART Device Path is %" PRIu8
>> +                                     " which is out of configuration range.",
>> +                                     u->parity);
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE:
>> +                     if (len < sizeof(fwts_uefi_vendor_messaging_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIVendorMessagingDevPathLength",
>> +                                     "The length of Vendor-Defined Messaging Device Path is %" PRIu16 " bytes "
>> +                                     "should not be smaller than UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_vendor_messaging_dev_path));
>> +                             errors++;
>> +                     }
>> +
>> +                     size_t i;
>> +                     static const fwts_uefi_guid guid[] = {
>> +                             EFI_PC_ANSI_GUID,
>> +                             EFI_VT_100_GUID,
>> +                             EFI_VT_100_PLUS_GUID,
>> +                             EFI_VT_UTF8_GUID,
>> +                             EFI_UART_DEVICE_PATH_GUID,
>> +                             EFI_SAS_DEVICE_PATH_GUID
>> +                     };
>> +
>> +                     fwts_uefi_vendor_messaging_dev_path *v = (fwts_uefi_vendor_messaging_dev_path *)dev_path;
>> +                     for (i = 0; i < sizeof(guid)/sizeof(guid[0]); i++)
>> +                             if (memcmp(&v->guid, &guid[i], sizeof(fwts_uefi_guid)) == 0)
>> +                                     break;
>> +                     switch (i) {
>> +                     case 0:
>> +                     case 1:
>> +                     case 2:
>> +                     case 3:
>> +                             if (len != sizeof(fwts_uefi_vendor_messaging_dev_path)) {
>> +                                     fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIVendorMessagingDevPathLength",
>> +                                             "The length of Vendor-Defined Messaging Device Path is %" PRIu16 " bytes "
>> +                                             "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                             len,
>> +                                             (uint16_t)sizeof(fwts_uefi_vendor_messaging_dev_path));
>> +                                     errors++;
>> +                             }
>> +                             break;
>> +                     case 4:
>> +                             if (len != (sizeof(fwts_uefi_uart_flowctl_messaging_dev_path))) {
>> +                                     fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIVendorMessagingDevPathLength",
>> +                                             "The length of UART Flow Control Device Path is %" PRIu16 " bytes "
>> +                                             "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                             len,
>> +                                             (uint16_t)(sizeof(fwts_uefi_uart_flowctl_messaging_dev_path)));
>> +                                     errors++;
>> +                             }
>> +                             break;
>> +                     case 5:
>> +                             if (len != (sizeof(fwts_uefi_sas_messaging_dev_path))) {
>> +                                     fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIVendorMessagingDevPathLength",
>> +                                             "The length of Serial Attached SCSI (SAS) Device Path is %" PRIu16 " bytes "
>> +                                             "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                             len,
>> +                                             (uint16_t)(sizeof(fwts_uefi_sas_messaging_dev_path)));
>> +                                     errors++;
>> +                             }
>> +                             break;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_FIBRE_CHANNEL_EX_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_fibre_channel_ex_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIFibreChannelExDevPathLength",
>> +                                     "The length of Fibre Channel Ex Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_fibre_channel_ex_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_SATA_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_sata_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFISATADevPathLength",
>> +                                     "The length of SATA Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_sata_dev_path));
>> +                             errors++;
>> +                             break;
>> +                     }
>> +
>> +                     fwts_uefi_sata_dev_path *s = (fwts_uefi_sata_dev_path *)dev_path;
>> +                     if (s->hbapn == 0xFFFF) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFISATADevPathConfInvalid",
>> +                                     "The HBA Port Number value of length of SATA Device Path is %" PRIu16
>> +                                     " which is reserved.",
>> +                                     s->hbapn);
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_USB_WWID_DEVICE_PATH_SUBTYPE:
>> +                     if (len < sizeof(fwts_uefi_usb_wwid_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIUSBWWIDDevPathLength",
>> +                                     "The length of USB WWID Device Path is %" PRIu16 " bytes "
>> +                                     "should not be smaller than UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_usb_wwid_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_VLAN_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_vlan_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIVLANDevPathLength",
>> +                                     "The length of VLAN Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_vlan_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_LOGICAL_UNIT_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_logical_unit_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIDeviceLogicalUnitLength",
>> +                                     "The length of Device Logical Unit is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_logical_unit_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_SAS_EX_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_sas_ex_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFISASExDevPathLength",
>> +                                     "The length of Serial Attached SCSI Ex Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_sas_ex_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_ISCSI_DEVICE_PATH_SUBTYPE:
>> +                     if (len < sizeof(fwts_uefi_iscsi_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIiSCSIDevPathLength",
>> +                                     "The length of iSCSI Device Path is %" PRIu16 " bytes "
>> +                                     "should not be smaller than UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_iscsi_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_NVM_EXPRESS_NAMESP_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_nvm_express_namespace_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFINVMExpressDevPathLength",
>> +                                     "The length of NVM Express Namespace Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_nvm_express_namespace_dev_path));
>> +                             errors++;
>> +                             break;
>> +                     }
>> +
>> +                     fwts_uefi_nvm_express_namespace_dev_path *n = (fwts_uefi_nvm_express_namespace_dev_path *)dev_path;
>> +                     if ((n->namesp_id == 0xFFFFFFFF) || (n->namesp_id == 0)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFINVMExpressDevPathInvalid",
>> +                                     "The Namespace Identifier value of NVM Express namespace Device Path is %" PRIu32
>> +                                     " which is invalid.",
>> +                                     n->namesp_id);
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_RELATIVE_OFFSET_RANGE_SUBTYPE:
>> +                     if (len != sizeof(fwts_relative_offset_range_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIRelativeOffsetRangeLength",
>> +                                     "The length of Relative Offset Range is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_relative_offset_range_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             default:
>> +                     fwts_log_info_verbatum(fw, "Unknow subtype of Messaging Device PaERRORth.");
>> +                     break;
>> +             }
>> +             break;
>> +
>> +     case FWTS_UEFI_MEDIA_DEVICE_PATH_TYPE:
>> +             switch (dev_path->subtype) {
>> +             case FWTS_UEFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_hard_drive_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIHardDriveDevPathLength",
>> +                                     "The length of Hard Drive Media Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_hard_drive_dev_path));
>> +                             errors++;
>> +                             break;
>> +                     }
>> +
>> +                     fwts_uefi_hard_drive_dev_path *h = (fwts_uefi_hard_drive_dev_path *)dev_path;
>> +                     if ((h->mbr_type > 2) || (h->mbr_type == 0)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIHardDriveDevPathConfInvalid",
>> +                                     "The Partition Format value of Hard Drive Media Device Path is %" PRIu8
>> +                                     " which is reserved.",
>> +                                     h->mbr_type);
>> +                             errors++;
>> +                     }
>> +                     if (h->signature_type > 2) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIHardDriveDevPathConfInvalid",
>> +                                     "The Signature Type value of Hard Drive Media Device Path is %" PRIu8
>> +                                     " which is reserved.",
>> +                                     h->signature_type);
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_CDROM_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_uefi_cdrom_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFICDROMDevPathLength",
>> +                                     "The length of CD-ROM Media Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_cdrom_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE:
>> +                     if (len < sizeof(fwts_uefi_vendor_media_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIVendorMediaDevPathLength",
>> +                                     "The length of Vendor-Defined Media Device Path is %" PRIu16 " bytes "
>> +                                     "should not be smaller than UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_vendor_media_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_FILE_PATH_DEVICE_PATH_SUBTYPE:
>> +                     if (len < sizeof(fwts_uefi_file_path_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIFilePathMediaDevPathLength",
>> +                                     "The length of File Path Media Device Path is %" PRIu16 " bytes "
>> +                                     "should not be smaller than UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_file_path_dev_path));
>> +                             errors++;
>> +                             break;
>> +                     }
>> +                     fwts_uefi_file_path_dev_path *f = (fwts_uefi_file_path_dev_path *)dev_path;
>> +                     if (len != (sizeof(fwts_uefi_file_path_dev_path) + ((fwts_uefi_str16len(f->path_name) + 1) * sizeof(uint16_t)))) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIFilePathMediaPathLength",
>> +                                     "The length of File Path Media Device Path is %" PRIu16 " bytes "
>> +                                     "is not matching with adding the length of Path String %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)(sizeof(fwts_uefi_file_path_dev_path) + (fwts_uefi_str16len(f->path_name) * sizeof(uint16_t))));
>> +                             errors++;
>> +                             break;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_PROTOCOL_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_media_protocol_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIMediaProtocolDevPathLength",
>> +                                     "The length of Media Protocol Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_media_protocol_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_PIWG_FW_FILE_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_piwg_fw_file_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIPIWGFwFileDevPathLength",
>> +                                     "The length of PIWG Firmware File Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_piwg_fw_file_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             case FWTS_UEFI_PIWG_FW_VOLUME_DEVICE_PATH_SUBTYPE:
>> +                     if (len != sizeof(fwts_piwg_fw_volume_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIPIWGFwVolumeDevPathLength",
>> +                                     "The length of PIWG Firmware Volume Device Path is %" PRIu16 " bytes "
>> +                                     "and differs from UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_piwg_fw_volume_dev_path));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             default:
>> +                     fwts_log_info_verbatum(fw, "Unknow subtype of Media Device Path.");
>> +                     break;
>> +             }
>> +             break;
>> +
>> +     case FWTS_UEFI_BIOS_DEVICE_PATH_TYPE:
>> +             switch (dev_path->subtype) {
>> +             case FWTS_UEFI_BIOS_DEVICE_PATH_SUBTYPE:
>> +                     if (len < sizeof(fwts_uefi_bios_dev_path)) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIBiosBootDevPathLength",
>> +                                     "The length of BIOS Boot Specification Device Path is %" PRIu16 " bytes "
>> +                                     "should not be smaller than UEFI specification defined %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)sizeof(fwts_uefi_bios_dev_path));
>> +                             errors++;
>> +                             break;
>> +                     }
>> +                     fwts_uefi_bios_dev_path *b = (fwts_uefi_bios_dev_path *)dev_path;
>> +                     if (len != (sizeof(fwts_uefi_bios_dev_path) + strlen(b->description))) {
>> +                             fwts_failed(fw, LOG_LEVEL_MEDIUM, "UEFIBiosBootDevPathLength",
>> +                                     "The length of BIOS Boot Specification Device Path is %" PRIu16 " bytes "
>> +                                     "is not matching with adding the length of Description String %" PRIu16 " bytes.",
>> +                                     len,
>> +                                     (uint16_t)(sizeof(fwts_uefi_bios_dev_path) + strlen(b->description)));
>> +                             errors++;
>> +                     }
>> +                     break;
>> +             default:
>> +                     fwts_log_info_verbatum(fw, "Unknow subtype of BIOS Boot Specification Device Path.");
>> +                     break;
>> +             }
>> +             break;
>> +     default:
>> +             fwts_log_info_verbatum(fw, "Unknow Type of Device Path.");
>> +             break;
>> +
>> +     }
>> +
>> +     /* Not end? - collect more */
>> +     if (!((dev_path->type & 0x7f) == (FWTS_UEFI_END_DEV_PATH_TYPE) &&
>> +           (dev_path->subtype == FWTS_UEFI_END_ENTIRE_DEV_PATH_SUBTYPE))) {
>> +             len = dev_path->length[0] | (((uint16_t)dev_path->length[1]) << 8);
>> +             if (len > 0) {
>> +                     dev_path = (fwts_uefi_dev_path *)((char *)dev_path + len);
>> +                     uefibootpath_check_dev_path(fw, dev_path, dev_path_len - len);
>> +             }
>> +     }
>> +
>> +     return FWTS_OK;
>> +}
>> +
>> +static int uefibootpath_info_bootdev(fwts_framework *fw, fwts_uefi_var *var)
>> +{
>> +     fwts_uefi_load_option *load_option;
>> +     size_t len, offset;
>> +     char tmp[2048];
>> +
>> +     if (var->datalen < sizeof(fwts_uefi_load_option)) {
>> +             fwts_failed(fw, LOG_LEVEL_MEDIUM,
>> +                     "UEFIBootPathLength",
>> +                     "The length of boot path variable is less than "
>> +                     "the load option structure.");
>> +             return FWTS_ERROR;
>> +     }
>> +
>> +     load_option = (fwts_uefi_load_option *)var->data;
>> +     fwts_uefi_str16_to_str(tmp, sizeof(tmp), load_option->description);
>> +     len = fwts_uefi_str16len(load_option->description);
>> +     fwts_log_info_verbatum(fw, "Info: %s\n", tmp);
>> +
>> +     if (var->datalen < (sizeof(uint16_t) * (len + 1))) {
>> +             fwts_failed(fw, LOG_LEVEL_MEDIUM,
>> +                     "UEFIBootPathDescriptionLength",
>> +                     "The length of description is large than "
>> +                     "the boot path variable length.");
>> +             return FWTS_ERROR;
>> +     }
>> +
>> +     /* Skip over description */
>> +     offset = sizeof(load_option->attributes) +
>> +              sizeof(load_option->file_path_list_length) +
>> +              (sizeof(uint16_t) * (len + 1));
>> +
>> +     uefibootpath_check_dev_path(fw, (fwts_uefi_dev_path *)(var->data + offset), var->datalen - offset);
>> +
>> +     return FWTS_OK;
>> +
>> +}
>> +
>> +static void uefibootpath_var(fwts_framework *fw, fwts_uefi_var *var)
>> +{
>> +     char varname[512];
>> +     int ret;
>> +
>> +     fwts_uefi_get_varname(varname, sizeof(varname), var);
>> +
>> +     /* Check the boot load option Boot####. #### is a printed hex value */
>> +     if ((strlen(varname) == 8) && (strncmp(varname, "Boot", 4) == 0)
>> +                     && isxdigit(varname[4]) && isxdigit(varname[5])
>> +                     && isxdigit(varname[6]) && isxdigit(varname[7])) {
>> +             fwts_log_info_verbatum(fw, "Name: %s", varname);
>> +             errors = 0;
>> +             ret = uefibootpath_info_bootdev(fw, var);
>> +
>> +             if (!errors && (ret == FWTS_OK))
>> +                     fwts_passed(fw, "Check bootpath %s test passed.", varname);
>> +
>> +             return;
>> +     }
>> +
>> +}
>> +
>> +static int uefibootpath_test1(fwts_framework *fw)
>> +{
>> +     fwts_list name_list;
>> +
>> +     if (fwts_uefi_get_variable_names(&name_list) == FWTS_ERROR) {
>> +             fwts_skipped(fw, "Cannot find any UEFI variables.");
>> +             return FWTS_SKIP;
>> +     } else {
>> +             fwts_list_link *item;
>> +
>> +             fwts_list_foreach(item, &name_list) {
>> +                     fwts_uefi_var var;
>> +                     char *name = fwts_list_data(char *, item);
>> +
>> +                     if (fwts_uefi_get_variable(name, &var) == FWTS_OK) {
>> +                             uefibootpath_var(fw, &var);
>> +                             fwts_uefi_free_variable(&var);
>> +                     }
>> +             }
>> +     }
>> +
>> +     fwts_uefi_free_variable_names(&name_list);
>> +
>> +     return FWTS_OK;
>> +}
>> +
>> +static fwts_framework_minor_test uefibootpath_tests[] = {
>> +     { uefibootpath_test1, "Test UEFI Boot Path Boot####." },
>> +     { NULL, NULL }
>> +};
>> +
>> +static fwts_framework_ops uefibootpath_ops = {
>> +     .description     = "Sanity check for UEFI Boot Path Boot####.",
>> +     .init            = uefibootpath_init,
>> +     .minor_tests     = uefibootpath_tests
>> +};
>> +
>> +FWTS_REGISTER("uefibootpath", &uefibootpath_ops, FWTS_TEST_ANYTIME, FWTS_FLAG_TEST_UEFI | FWTS_FLAG_BATCH | FWTS_FLAG_ROOT_PRIV);
>>
>
> Acked-by: Alex Hung <alex.hung at canonical.com>
>
Acked-by: Keng-Yu Lin <kengyu at canonical.com>



More information about the fwts-devel mailing list