]> git.hungrycats.org Git - linux/commitdiff
efi: Make our variable validation list include the guid
authorPeter Jones <pjones@redhat.com>
Mon, 8 Feb 2016 19:48:14 +0000 (14:48 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 16 Mar 2016 15:41:37 +0000 (08:41 -0700)
commit 8282f5d9c17fe15a9e658c06e3f343efae1a2a2f upstream.

All the variables in this list so far are defined to be in the global
namespace in the UEFI spec, so this just further ensures we're
validating the variables we think we are.

Including the guid for entries will become more important in future
patches when we decide whether or not to allow deletion of variables
based on presence in this list.

Signed-off-by: Peter Jones <pjones@redhat.com>
Tested-by: Lee, Chun-Yi <jlee@suse.com>
Acked-by: Matthew Garrett <mjg59@coreos.com>
Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/firmware/efi/efivars.c
drivers/firmware/efi/vars.c
include/linux/efi.h

index 2953397de85d04fa34c8387f5967bb321de19ded..24ae2a694e9bbdcd51ed67e75eb48dff93709e13 100644 (file)
@@ -219,7 +219,8 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
        }
 
        if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
-           efivar_validate(new_var->VariableName, new_var->Data, new_var->DataSize) == false) {
+           efivar_validate(new_var->VendorGuid, new_var->VariableName,
+                           new_var->Data, new_var->DataSize) == false) {
                printk(KERN_ERR "efivars: Malformed variable content\n");
                return -EINVAL;
        }
@@ -334,7 +335,8 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
                return -EACCES;
 
        if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
-           efivar_validate(new_var->VariableName, new_var->Data, new_var->DataSize) == false) {
+           efivar_validate(new_var->VendorGuid, new_var->VariableName,
+                           new_var->Data, new_var->DataSize) == false) {
                printk(KERN_ERR "efivars: Malformed variable content\n");
                return -EINVAL;
        }
index 890aac38aabb4200c8587ea26577c3335bffc413..05f4dc3cdb466a13c47562726c5790499747a0c2 100644 (file)
@@ -165,31 +165,42 @@ validate_ascii_string(efi_char16_t *var_name, int match, u8 *buffer,
 }
 
 struct variable_validate {
+       efi_guid_t vendor;
        char *name;
        bool (*validate)(efi_char16_t *var_name, int match, u8 *data,
                         unsigned long len);
 };
 
+/*
+ * This is the list of variables we need to validate.
+ *
+ * If it has a validate() method that's not NULL, it'll go into the
+ * validation routine.  If not, it is assumed valid.
+ *
+ * Note that it's sorted by {vendor,name}, but globbed names must come after
+ * any other name with the same prefix.
+ */
 static const struct variable_validate variable_validate[] = {
-       { "BootNext", validate_uint16 },
-       { "BootOrder", validate_boot_order },
-       { "DriverOrder", validate_boot_order },
-       { "Boot*", validate_load_option },
-       { "Driver*", validate_load_option },
-       { "ConIn", validate_device_path },
-       { "ConInDev", validate_device_path },
-       { "ConOut", validate_device_path },
-       { "ConOutDev", validate_device_path },
-       { "ErrOut", validate_device_path },
-       { "ErrOutDev", validate_device_path },
-       { "Timeout", validate_uint16 },
-       { "Lang", validate_ascii_string },
-       { "PlatformLang", validate_ascii_string },
-       { "", NULL },
+       { EFI_GLOBAL_VARIABLE_GUID, "BootNext", validate_uint16 },
+       { EFI_GLOBAL_VARIABLE_GUID, "BootOrder", validate_boot_order },
+       { EFI_GLOBAL_VARIABLE_GUID, "Boot*", validate_load_option },
+       { EFI_GLOBAL_VARIABLE_GUID, "DriverOrder", validate_boot_order },
+       { EFI_GLOBAL_VARIABLE_GUID, "Driver*", validate_load_option },
+       { EFI_GLOBAL_VARIABLE_GUID, "ConIn", validate_device_path },
+       { EFI_GLOBAL_VARIABLE_GUID, "ConInDev", validate_device_path },
+       { EFI_GLOBAL_VARIABLE_GUID, "ConOut", validate_device_path },
+       { EFI_GLOBAL_VARIABLE_GUID, "ConOutDev", validate_device_path },
+       { EFI_GLOBAL_VARIABLE_GUID, "ErrOut", validate_device_path },
+       { EFI_GLOBAL_VARIABLE_GUID, "ErrOutDev", validate_device_path },
+       { EFI_GLOBAL_VARIABLE_GUID, "Lang", validate_ascii_string },
+       { EFI_GLOBAL_VARIABLE_GUID, "PlatformLang", validate_ascii_string },
+       { EFI_GLOBAL_VARIABLE_GUID, "Timeout", validate_uint16 },
+       { NULL_GUID, "", NULL },
 };
 
 bool
-efivar_validate(efi_char16_t *var_name, u8 *data, unsigned long data_size)
+efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data,
+               unsigned long data_size)
 {
        int i;
        unsigned long utf8_size;
@@ -203,9 +214,12 @@ efivar_validate(efi_char16_t *var_name, u8 *data, unsigned long data_size)
        ucs2_as_utf8(utf8_name, var_name, utf8_size);
        utf8_name[utf8_size] = '\0';
 
-       for (i = 0; variable_validate[i].validate != NULL; i++) {
+       for (i = 0; variable_validate[i].name[0] != '\0'; i++) {
                const char *name = variable_validate[i].name;
-               int match;
+               int match = 0;
+
+               if (efi_guidcmp(vendor, variable_validate[i].vendor))
+                       continue;
 
                for (match = 0; ; match++) {
                        char c = name[match];
@@ -807,7 +821,7 @@ int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes,
 
        *set = false;
 
-       if (efivar_validate(name, data, *size) == false)
+       if (efivar_validate(*vendor, name, data, *size) == false)
                return -EINVAL;
 
        /*
index 06cce30161c27bcddbd2566d76c56f65286d8d5e..eb07711cb0f60a9e0d35cdfad8325fac21e97d1e 100644 (file)
@@ -834,7 +834,8 @@ int efivar_entry_iter(int (*func)(struct efivar_entry *, void *),
 struct efivar_entry *efivar_entry_find(efi_char16_t *name, efi_guid_t guid,
                                       struct list_head *head, bool remove);
 
-bool efivar_validate(efi_char16_t *var_name, u8 *data, unsigned long len);
+bool efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data,
+                    unsigned long data_size);
 
 extern struct work_struct efivar_work;
 void efivar_run_worker(void);