Message ID | 1515396249-7923-1-git-send-email-ivan.hu@canonical.com |
---|---|
State | Accepted |
Headers | show |
Series | [1/2] securebootcert: add checking read-only for the AuditMode and DeployedMode | expand |
On 2018-01-07 11:24 PM, Ivan Hu wrote: > UEFI spec 2.7 add the update of AuditMode and DeplyedMode variable, these two > global variables should be always becomes read-only after ExitBootServices() is > called. > > Add the testing read-only by setting variables, no EFI_SUCCESS return is > expected. > > Signed-off-by: Ivan Hu <ivan.hu@canonical.com> > --- > src/uefi/securebootcert/securebootcert.c | 131 +++++++++++++++++++++++++++++-- > 1 file changed, 124 insertions(+), 7 deletions(-) > > diff --git a/src/uefi/securebootcert/securebootcert.c b/src/uefi/securebootcert/securebootcert.c > index a74c55d..60fc489 100644 > --- a/src/uefi/securebootcert/securebootcert.c > +++ b/src/uefi/securebootcert/securebootcert.c > @@ -22,10 +22,16 @@ > > #include <stddef.h> > #include <inttypes.h> > +#include <sys/ioctl.h> > > #include "fwts_uefi.h" > #include "sbkeydefs.h" > > +#include "fwts_efi_runtime.h" > +#include "fwts_efi_module.h" > + > +static int fd; > + > typedef void (*securebootcert_func)(fwts_framework *fw, fwts_uefi_var *var, char *varname); > > typedef struct { > @@ -33,13 +39,6 @@ typedef struct { > securebootcert_func func; /* Function to dump this variable */ > } securebootcert_info; > > -typedef struct { > - uint32_t Data1; > - uint16_t Data2; > - uint16_t Data3; > - uint8_t Data4[8]; > -} __attribute__ ((packed)) EFI_GUID; > - > typedef struct _EFI_SIGNATURE_LIST { > EFI_GUID SignatureType; > uint32_t SignatureListSize; > @@ -70,6 +69,11 @@ static uint8_t var_found; > static bool securebooted = false; > static bool deployed = false; > > +static EFI_GUID global_guid = EFI_GLOBAL_VARIABLE; > + > +static uint16_t varauditmode[] = {'A', 'u', 'd', 'i', 't', 'M', 'o', 'd', 'e', '\0'}; > +static uint16_t vardeploymode[] = {'D', 'e', 'p', 'l', 'o', 'y', 'e', 'd', 'M', 'o', 'd', 'e', '\0'}; > + > static bool compare_guid(EFI_GUID *guid1, uint8_t *guid2) > { > bool ident = true; > @@ -429,6 +433,25 @@ static int securebootcert_init(fwts_framework *fw) > return FWTS_ABORTED; > } > > + if (fwts_lib_efi_runtime_load_module(fw) != FWTS_OK) { > + fwts_log_info(fw, "Cannot load efi_runtime module. Aborted."); > + return FWTS_ABORTED; > + } > + > + fd = fwts_lib_efi_runtime_open(); > + if (fd == -1) { > + fwts_log_info(fw, "Cannot open EFI test driver. Aborted."); > + return FWTS_ABORTED; > + } > + > + return FWTS_OK; > +} > + > +static int securebootcert_deinit(fwts_framework *fw) > +{ > + fwts_lib_efi_runtime_close(fd); > + fwts_lib_efi_runtime_unload_module(fw); > + > return FWTS_OK; > } > > @@ -492,14 +515,108 @@ static int securebootcert_test1(fwts_framework *fw) > return FWTS_OK; > } > > +static int securebootcert_setvar( > + fwts_framework *fw, > + const uint32_t attributes, > + uint16_t *varname, > + EFI_GUID *guid, > + uint8_t *data) > +{ > + long ioret; > + struct efi_setvariable setvariable; > + > + uint64_t status; > + uint64_t datasize = 1; > + > + setvariable.VariableName = varname; > + setvariable.VendorGuid = guid; > + setvariable.Attributes = attributes; > + setvariable.DataSize = datasize; > + setvariable.Data = data; > + setvariable.status = &status; > + ioret = ioctl(fd, EFI_RUNTIME_SET_VARIABLE, &setvariable); > + > + if (ioret == -1) { > + if (status == EFI_OUT_OF_RESOURCES) { > + fwts_uefi_print_status_info(fw, status); > + fwts_skipped(fw, > + "Run out of resources for SetVariable " > + "UEFI runtime interface: cannot test."); > + fwts_advice(fw, > + "Firmware may reclaim some resources " > + "after rebooting. Reboot and test " > + "again may be helpful to continue " > + "the test."); > + return FWTS_SKIP; > + } > + } > + > + if (status == EFI_SUCCESS) { > + fwts_failed(fw, LOG_LEVEL_HIGH, > + "UEFISecurebooCertVar", > + "Variable is ready only, return status of setvariable " > + "should not EFI_SUCCESS."); > + } else > + fwts_passed(fw, "Variable read-only test passed."); > + return FWTS_OK; > +} > + > +static int securebootcert_test2(fwts_framework *fw) > +{ > + int ret; > + uint8_t data = 0; > + static uint32_t attributes = FWTS_UEFI_VAR_NON_VOLATILE | > + FWTS_UEFI_VAR_BOOTSERVICE_ACCESS | > + FWTS_UEFI_VAR_RUNTIME_ACCESS; > + > + if (!(var_found & VAR_AUDITMODE_FOUND)) { > + fwts_skipped(fw, > + "No AuditMode variable found, skip the varaible test."); > + return FWTS_SKIP; > + } > + > + fwts_log_info(fw, "AuditMode variable read-only test, set to 0."); > + ret = securebootcert_setvar(fw, attributes, varauditmode, &global_guid, &data); > + if (ret != FWTS_OK) > + return ret; > + > + data = 1; > + fwts_log_info(fw, "AuditMode variable read-only test, set to 1."); > + ret = securebootcert_setvar(fw, attributes, varauditmode, &global_guid, &data); > + if (ret != FWTS_OK) > + return ret; > + > + if (!(var_found & VAR_AUDITMODE_FOUND)) { > + fwts_skipped(fw, > + "No DeployedMode variable found, skip the varaible test."); > + return FWTS_SKIP; > + } > + > + data = 0; > + fwts_log_info(fw, "DeployedMode variable read-only test, set to 0."); > + ret = securebootcert_setvar(fw, attributes, vardeploymode, &global_guid, &data); > + if (ret != FWTS_OK) > + return ret; > + > + data = 1; > + fwts_log_info(fw, "DeployedMode variable read-only test, set to 1."); > + ret = securebootcert_setvar(fw, attributes, vardeploymode, &global_guid, &data); > + if (ret != FWTS_OK) > + return ret; > + > + return FWTS_OK; > +} > + > static fwts_framework_minor_test securebootcert_tests[] = { > { securebootcert_test1, "UEFI secure boot test." }, > + { securebootcert_test2, "UEFI secure boot variable test." }, > { NULL, NULL } > }; > > static fwts_framework_ops securebootcert_ops = { > .description = "UEFI secure boot test.", > .init = securebootcert_init, > + .deinit = securebootcert_deinit, > .minor_tests = securebootcert_tests > }; > > Acked-by: Alex Hung <alex.hung@canonical.com>
On 08/01/18 07:24, Ivan Hu wrote: > UEFI spec 2.7 add the update of AuditMode and DeplyedMode variable, these two > global variables should be always becomes read-only after ExitBootServices() is > called. > > Add the testing read-only by setting variables, no EFI_SUCCESS return is > expected. > > Signed-off-by: Ivan Hu <ivan.hu@canonical.com> > --- > src/uefi/securebootcert/securebootcert.c | 131 +++++++++++++++++++++++++++++-- > 1 file changed, 124 insertions(+), 7 deletions(-) > > diff --git a/src/uefi/securebootcert/securebootcert.c b/src/uefi/securebootcert/securebootcert.c > index a74c55d..60fc489 100644 > --- a/src/uefi/securebootcert/securebootcert.c > +++ b/src/uefi/securebootcert/securebootcert.c > @@ -22,10 +22,16 @@ > > #include <stddef.h> > #include <inttypes.h> > +#include <sys/ioctl.h> > > #include "fwts_uefi.h" > #include "sbkeydefs.h" > > +#include "fwts_efi_runtime.h" > +#include "fwts_efi_module.h" > + > +static int fd; > + > typedef void (*securebootcert_func)(fwts_framework *fw, fwts_uefi_var *var, char *varname); > > typedef struct { > @@ -33,13 +39,6 @@ typedef struct { > securebootcert_func func; /* Function to dump this variable */ > } securebootcert_info; > > -typedef struct { > - uint32_t Data1; > - uint16_t Data2; > - uint16_t Data3; > - uint8_t Data4[8]; > -} __attribute__ ((packed)) EFI_GUID; > - > typedef struct _EFI_SIGNATURE_LIST { > EFI_GUID SignatureType; > uint32_t SignatureListSize; > @@ -70,6 +69,11 @@ static uint8_t var_found; > static bool securebooted = false; > static bool deployed = false; > > +static EFI_GUID global_guid = EFI_GLOBAL_VARIABLE; > + > +static uint16_t varauditmode[] = {'A', 'u', 'd', 'i', 't', 'M', 'o', 'd', 'e', '\0'}; > +static uint16_t vardeploymode[] = {'D', 'e', 'p', 'l', 'o', 'y', 'e', 'd', 'M', 'o', 'd', 'e', '\0'}; > + > static bool compare_guid(EFI_GUID *guid1, uint8_t *guid2) > { > bool ident = true; > @@ -429,6 +433,25 @@ static int securebootcert_init(fwts_framework *fw) > return FWTS_ABORTED; > } > > + if (fwts_lib_efi_runtime_load_module(fw) != FWTS_OK) { > + fwts_log_info(fw, "Cannot load efi_runtime module. Aborted."); > + return FWTS_ABORTED; > + } > + > + fd = fwts_lib_efi_runtime_open(); > + if (fd == -1) { > + fwts_log_info(fw, "Cannot open EFI test driver. Aborted."); > + return FWTS_ABORTED; > + } > + > + return FWTS_OK; > +} > + > +static int securebootcert_deinit(fwts_framework *fw) > +{ > + fwts_lib_efi_runtime_close(fd); > + fwts_lib_efi_runtime_unload_module(fw); > + > return FWTS_OK; > } > > @@ -492,14 +515,108 @@ static int securebootcert_test1(fwts_framework *fw) > return FWTS_OK; > } > > +static int securebootcert_setvar( > + fwts_framework *fw, > + const uint32_t attributes, > + uint16_t *varname, > + EFI_GUID *guid, > + uint8_t *data) > +{ > + long ioret; > + struct efi_setvariable setvariable; > + > + uint64_t status; > + uint64_t datasize = 1; > + > + setvariable.VariableName = varname; > + setvariable.VendorGuid = guid; > + setvariable.Attributes = attributes; > + setvariable.DataSize = datasize; > + setvariable.Data = data; > + setvariable.status = &status; > + ioret = ioctl(fd, EFI_RUNTIME_SET_VARIABLE, &setvariable); > + > + if (ioret == -1) { > + if (status == EFI_OUT_OF_RESOURCES) { > + fwts_uefi_print_status_info(fw, status); > + fwts_skipped(fw, > + "Run out of resources for SetVariable " > + "UEFI runtime interface: cannot test."); > + fwts_advice(fw, > + "Firmware may reclaim some resources " > + "after rebooting. Reboot and test " > + "again may be helpful to continue " > + "the test."); > + return FWTS_SKIP; > + } > + } > + > + if (status == EFI_SUCCESS) { > + fwts_failed(fw, LOG_LEVEL_HIGH, > + "UEFISecurebooCertVar", > + "Variable is ready only, return status of setvariable " > + "should not EFI_SUCCESS."); > + } else > + fwts_passed(fw, "Variable read-only test passed."); > + return FWTS_OK; > +} > + > +static int securebootcert_test2(fwts_framework *fw) > +{ > + int ret; > + uint8_t data = 0; > + static uint32_t attributes = FWTS_UEFI_VAR_NON_VOLATILE | > + FWTS_UEFI_VAR_BOOTSERVICE_ACCESS | > + FWTS_UEFI_VAR_RUNTIME_ACCESS; > + > + if (!(var_found & VAR_AUDITMODE_FOUND)) { > + fwts_skipped(fw, > + "No AuditMode variable found, skip the varaible test."); > + return FWTS_SKIP; > + } > + > + fwts_log_info(fw, "AuditMode variable read-only test, set to 0."); > + ret = securebootcert_setvar(fw, attributes, varauditmode, &global_guid, &data); > + if (ret != FWTS_OK) > + return ret; > + > + data = 1; > + fwts_log_info(fw, "AuditMode variable read-only test, set to 1."); > + ret = securebootcert_setvar(fw, attributes, varauditmode, &global_guid, &data); > + if (ret != FWTS_OK) > + return ret; > + > + if (!(var_found & VAR_AUDITMODE_FOUND)) { > + fwts_skipped(fw, > + "No DeployedMode variable found, skip the varaible test."); > + return FWTS_SKIP; > + } > + > + data = 0; > + fwts_log_info(fw, "DeployedMode variable read-only test, set to 0."); > + ret = securebootcert_setvar(fw, attributes, vardeploymode, &global_guid, &data); > + if (ret != FWTS_OK) > + return ret; > + > + data = 1; > + fwts_log_info(fw, "DeployedMode variable read-only test, set to 1."); > + ret = securebootcert_setvar(fw, attributes, vardeploymode, &global_guid, &data); > + if (ret != FWTS_OK) > + return ret; > + > + return FWTS_OK; > +} > + > static fwts_framework_minor_test securebootcert_tests[] = { > { securebootcert_test1, "UEFI secure boot test." }, > + { securebootcert_test2, "UEFI secure boot variable test." }, > { NULL, NULL } > }; > > static fwts_framework_ops securebootcert_ops = { > .description = "UEFI secure boot test.", > .init = securebootcert_init, > + .deinit = securebootcert_deinit, > .minor_tests = securebootcert_tests > }; > > Acked-by: Colin Ian King <colin.king@canonical.com>
diff --git a/src/uefi/securebootcert/securebootcert.c b/src/uefi/securebootcert/securebootcert.c index a74c55d..60fc489 100644 --- a/src/uefi/securebootcert/securebootcert.c +++ b/src/uefi/securebootcert/securebootcert.c @@ -22,10 +22,16 @@ #include <stddef.h> #include <inttypes.h> +#include <sys/ioctl.h> #include "fwts_uefi.h" #include "sbkeydefs.h" +#include "fwts_efi_runtime.h" +#include "fwts_efi_module.h" + +static int fd; + typedef void (*securebootcert_func)(fwts_framework *fw, fwts_uefi_var *var, char *varname); typedef struct { @@ -33,13 +39,6 @@ typedef struct { securebootcert_func func; /* Function to dump this variable */ } securebootcert_info; -typedef struct { - uint32_t Data1; - uint16_t Data2; - uint16_t Data3; - uint8_t Data4[8]; -} __attribute__ ((packed)) EFI_GUID; - typedef struct _EFI_SIGNATURE_LIST { EFI_GUID SignatureType; uint32_t SignatureListSize; @@ -70,6 +69,11 @@ static uint8_t var_found; static bool securebooted = false; static bool deployed = false; +static EFI_GUID global_guid = EFI_GLOBAL_VARIABLE; + +static uint16_t varauditmode[] = {'A', 'u', 'd', 'i', 't', 'M', 'o', 'd', 'e', '\0'}; +static uint16_t vardeploymode[] = {'D', 'e', 'p', 'l', 'o', 'y', 'e', 'd', 'M', 'o', 'd', 'e', '\0'}; + static bool compare_guid(EFI_GUID *guid1, uint8_t *guid2) { bool ident = true; @@ -429,6 +433,25 @@ static int securebootcert_init(fwts_framework *fw) return FWTS_ABORTED; } + if (fwts_lib_efi_runtime_load_module(fw) != FWTS_OK) { + fwts_log_info(fw, "Cannot load efi_runtime module. Aborted."); + return FWTS_ABORTED; + } + + fd = fwts_lib_efi_runtime_open(); + if (fd == -1) { + fwts_log_info(fw, "Cannot open EFI test driver. Aborted."); + return FWTS_ABORTED; + } + + return FWTS_OK; +} + +static int securebootcert_deinit(fwts_framework *fw) +{ + fwts_lib_efi_runtime_close(fd); + fwts_lib_efi_runtime_unload_module(fw); + return FWTS_OK; } @@ -492,14 +515,108 @@ static int securebootcert_test1(fwts_framework *fw) return FWTS_OK; } +static int securebootcert_setvar( + fwts_framework *fw, + const uint32_t attributes, + uint16_t *varname, + EFI_GUID *guid, + uint8_t *data) +{ + long ioret; + struct efi_setvariable setvariable; + + uint64_t status; + uint64_t datasize = 1; + + setvariable.VariableName = varname; + setvariable.VendorGuid = guid; + setvariable.Attributes = attributes; + setvariable.DataSize = datasize; + setvariable.Data = data; + setvariable.status = &status; + ioret = ioctl(fd, EFI_RUNTIME_SET_VARIABLE, &setvariable); + + if (ioret == -1) { + if (status == EFI_OUT_OF_RESOURCES) { + fwts_uefi_print_status_info(fw, status); + fwts_skipped(fw, + "Run out of resources for SetVariable " + "UEFI runtime interface: cannot test."); + fwts_advice(fw, + "Firmware may reclaim some resources " + "after rebooting. Reboot and test " + "again may be helpful to continue " + "the test."); + return FWTS_SKIP; + } + } + + if (status == EFI_SUCCESS) { + fwts_failed(fw, LOG_LEVEL_HIGH, + "UEFISecurebooCertVar", + "Variable is ready only, return status of setvariable " + "should not EFI_SUCCESS."); + } else + fwts_passed(fw, "Variable read-only test passed."); + return FWTS_OK; +} + +static int securebootcert_test2(fwts_framework *fw) +{ + int ret; + uint8_t data = 0; + static uint32_t attributes = FWTS_UEFI_VAR_NON_VOLATILE | + FWTS_UEFI_VAR_BOOTSERVICE_ACCESS | + FWTS_UEFI_VAR_RUNTIME_ACCESS; + + if (!(var_found & VAR_AUDITMODE_FOUND)) { + fwts_skipped(fw, + "No AuditMode variable found, skip the varaible test."); + return FWTS_SKIP; + } + + fwts_log_info(fw, "AuditMode variable read-only test, set to 0."); + ret = securebootcert_setvar(fw, attributes, varauditmode, &global_guid, &data); + if (ret != FWTS_OK) + return ret; + + data = 1; + fwts_log_info(fw, "AuditMode variable read-only test, set to 1."); + ret = securebootcert_setvar(fw, attributes, varauditmode, &global_guid, &data); + if (ret != FWTS_OK) + return ret; + + if (!(var_found & VAR_AUDITMODE_FOUND)) { + fwts_skipped(fw, + "No DeployedMode variable found, skip the varaible test."); + return FWTS_SKIP; + } + + data = 0; + fwts_log_info(fw, "DeployedMode variable read-only test, set to 0."); + ret = securebootcert_setvar(fw, attributes, vardeploymode, &global_guid, &data); + if (ret != FWTS_OK) + return ret; + + data = 1; + fwts_log_info(fw, "DeployedMode variable read-only test, set to 1."); + ret = securebootcert_setvar(fw, attributes, vardeploymode, &global_guid, &data); + if (ret != FWTS_OK) + return ret; + + return FWTS_OK; +} + static fwts_framework_minor_test securebootcert_tests[] = { { securebootcert_test1, "UEFI secure boot test." }, + { securebootcert_test2, "UEFI secure boot variable test." }, { NULL, NULL } }; static fwts_framework_ops securebootcert_ops = { .description = "UEFI secure boot test.", .init = securebootcert_init, + .deinit = securebootcert_deinit, .minor_tests = securebootcert_tests };
UEFI spec 2.7 add the update of AuditMode and DeplyedMode variable, these two global variables should be always becomes read-only after ExitBootServices() is called. Add the testing read-only by setting variables, no EFI_SUCCESS return is expected. Signed-off-by: Ivan Hu <ivan.hu@canonical.com> --- src/uefi/securebootcert/securebootcert.c | 131 +++++++++++++++++++++++++++++-- 1 file changed, 124 insertions(+), 7 deletions(-)