Commit a5d92ad3 authored by Matt Fleming's avatar Matt Fleming

efivars: Stop passing a struct argument to efivar_validate()

In preparation for compat support, we can't assume that user variable
object is represented by a 'struct efi_variable'. Convert the validation
functions to take the variable name as an argument, which is the only
piece of the struct that was ever used anyway.

Cc: Mike Waychison <mikew@google.com>
Signed-off-by: default avatarMatt Fleming <matt.fleming@intel.com>
parent e003bbee
...@@ -231,7 +231,7 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) ...@@ -231,7 +231,7 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
} }
if ((attributes & ~EFI_VARIABLE_MASK) != 0 || if ((attributes & ~EFI_VARIABLE_MASK) != 0 ||
efivar_validate(new_var, data, size) == false) { efivar_validate(name, data, size) == false) {
printk(KERN_ERR "efivars: Malformed variable content\n"); printk(KERN_ERR "efivars: Malformed variable content\n");
return -EINVAL; return -EINVAL;
} }
...@@ -339,6 +339,7 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, ...@@ -339,6 +339,7 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
{ {
struct efi_variable *new_var = (struct efi_variable *)buf; struct efi_variable *new_var = (struct efi_variable *)buf;
struct efivar_entry *new_entry; struct efivar_entry *new_entry;
efi_char16_t *name;
unsigned long size; unsigned long size;
u32 attributes; u32 attributes;
u8 *data; u8 *data;
...@@ -351,11 +352,12 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, ...@@ -351,11 +352,12 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
return -EINVAL; return -EINVAL;
attributes = new_var->Attributes; attributes = new_var->Attributes;
name = new_var->VariableName;
size = new_var->DataSize; size = new_var->DataSize;
data = new_var->Data; data = new_var->Data;
if ((attributes & ~EFI_VARIABLE_MASK) != 0 || if ((attributes & ~EFI_VARIABLE_MASK) != 0 ||
efivar_validate(new_var, data, size) == false) { efivar_validate(name, data, size) == false) {
printk(KERN_ERR "efivars: Malformed variable content\n"); printk(KERN_ERR "efivars: Malformed variable content\n");
return -EINVAL; return -EINVAL;
} }
......
...@@ -42,7 +42,7 @@ DECLARE_WORK(efivar_work, NULL); ...@@ -42,7 +42,7 @@ DECLARE_WORK(efivar_work, NULL);
EXPORT_SYMBOL_GPL(efivar_work); EXPORT_SYMBOL_GPL(efivar_work);
static bool static bool
validate_device_path(struct efi_variable *var, int match, u8 *buffer, validate_device_path(efi_char16_t *var_name, int match, u8 *buffer,
unsigned long len) unsigned long len)
{ {
struct efi_generic_dev_path *node; struct efi_generic_dev_path *node;
...@@ -75,7 +75,7 @@ validate_device_path(struct efi_variable *var, int match, u8 *buffer, ...@@ -75,7 +75,7 @@ validate_device_path(struct efi_variable *var, int match, u8 *buffer,
} }
static bool static bool
validate_boot_order(struct efi_variable *var, int match, u8 *buffer, validate_boot_order(efi_char16_t *var_name, int match, u8 *buffer,
unsigned long len) unsigned long len)
{ {
/* An array of 16-bit integers */ /* An array of 16-bit integers */
...@@ -86,18 +86,18 @@ validate_boot_order(struct efi_variable *var, int match, u8 *buffer, ...@@ -86,18 +86,18 @@ validate_boot_order(struct efi_variable *var, int match, u8 *buffer,
} }
static bool static bool
validate_load_option(struct efi_variable *var, int match, u8 *buffer, validate_load_option(efi_char16_t *var_name, int match, u8 *buffer,
unsigned long len) unsigned long len)
{ {
u16 filepathlength; u16 filepathlength;
int i, desclength = 0, namelen; int i, desclength = 0, namelen;
namelen = ucs2_strnlen(var->VariableName, sizeof(var->VariableName)); namelen = ucs2_strnlen(var_name, EFI_VAR_NAME_LEN);
/* Either "Boot" or "Driver" followed by four digits of hex */ /* Either "Boot" or "Driver" followed by four digits of hex */
for (i = match; i < match+4; i++) { for (i = match; i < match+4; i++) {
if (var->VariableName[i] > 127 || if (var_name[i] > 127 ||
hex_to_bin(var->VariableName[i] & 0xff) < 0) hex_to_bin(var_name[i] & 0xff) < 0)
return true; return true;
} }
...@@ -132,12 +132,12 @@ validate_load_option(struct efi_variable *var, int match, u8 *buffer, ...@@ -132,12 +132,12 @@ validate_load_option(struct efi_variable *var, int match, u8 *buffer,
/* /*
* And, finally, check the filepath * And, finally, check the filepath
*/ */
return validate_device_path(var, match, buffer + desclength + 6, return validate_device_path(var_name, match, buffer + desclength + 6,
filepathlength); filepathlength);
} }
static bool static bool
validate_uint16(struct efi_variable *var, int match, u8 *buffer, validate_uint16(efi_char16_t *var_name, int match, u8 *buffer,
unsigned long len) unsigned long len)
{ {
/* A single 16-bit integer */ /* A single 16-bit integer */
...@@ -148,7 +148,7 @@ validate_uint16(struct efi_variable *var, int match, u8 *buffer, ...@@ -148,7 +148,7 @@ validate_uint16(struct efi_variable *var, int match, u8 *buffer,
} }
static bool static bool
validate_ascii_string(struct efi_variable *var, int match, u8 *buffer, validate_ascii_string(efi_char16_t *var_name, int match, u8 *buffer,
unsigned long len) unsigned long len)
{ {
int i; int i;
...@@ -166,7 +166,7 @@ validate_ascii_string(struct efi_variable *var, int match, u8 *buffer, ...@@ -166,7 +166,7 @@ validate_ascii_string(struct efi_variable *var, int match, u8 *buffer,
struct variable_validate { struct variable_validate {
char *name; char *name;
bool (*validate)(struct efi_variable *var, int match, u8 *data, bool (*validate)(efi_char16_t *var_name, int match, u8 *data,
unsigned long len); unsigned long len);
}; };
...@@ -189,10 +189,10 @@ static const struct variable_validate variable_validate[] = { ...@@ -189,10 +189,10 @@ static const struct variable_validate variable_validate[] = {
}; };
bool bool
efivar_validate(struct efi_variable *var, u8 *data, unsigned long len) efivar_validate(efi_char16_t *var_name, u8 *data, unsigned long len)
{ {
int i; int i;
u16 *unicode_name = var->VariableName; u16 *unicode_name = var_name;
for (i = 0; variable_validate[i].validate != NULL; i++) { for (i = 0; variable_validate[i].validate != NULL; i++) {
const char *name = variable_validate[i].name; const char *name = variable_validate[i].name;
...@@ -208,7 +208,7 @@ efivar_validate(struct efi_variable *var, u8 *data, unsigned long len) ...@@ -208,7 +208,7 @@ efivar_validate(struct efi_variable *var, u8 *data, unsigned long len)
/* Wildcard in the matching name means we've matched */ /* Wildcard in the matching name means we've matched */
if (c == '*') if (c == '*')
return variable_validate[i].validate(var, return variable_validate[i].validate(var_name,
match, data, len); match, data, len);
/* Case sensitive match */ /* Case sensitive match */
...@@ -217,7 +217,7 @@ efivar_validate(struct efi_variable *var, u8 *data, unsigned long len) ...@@ -217,7 +217,7 @@ efivar_validate(struct efi_variable *var, u8 *data, unsigned long len)
/* Reached the end of the string while matching */ /* Reached the end of the string while matching */
if (!c) if (!c)
return variable_validate[i].validate(var, return variable_validate[i].validate(var_name,
match, data, len); match, data, len);
} }
} }
...@@ -805,7 +805,7 @@ int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes, ...@@ -805,7 +805,7 @@ int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes,
*set = false; *set = false;
if (efivar_validate(&entry->var, data, *size) == false) if (efivar_validate(name, data, *size) == false)
return -EINVAL; return -EINVAL;
/* /*
......
...@@ -1039,8 +1039,10 @@ struct efivars { ...@@ -1039,8 +1039,10 @@ struct efivars {
* and we use a page for reading/writing. * and we use a page for reading/writing.
*/ */
#define EFI_VAR_NAME_LEN 1024
struct efi_variable { struct efi_variable {
efi_char16_t VariableName[1024/sizeof(efi_char16_t)]; efi_char16_t VariableName[EFI_VAR_NAME_LEN/sizeof(efi_char16_t)];
efi_guid_t VendorGuid; efi_guid_t VendorGuid;
unsigned long DataSize; unsigned long DataSize;
__u8 Data[1024]; __u8 Data[1024];
...@@ -1122,7 +1124,7 @@ int efivar_entry_iter(int (*func)(struct efivar_entry *, void *), ...@@ -1122,7 +1124,7 @@ 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 efivar_entry *efivar_entry_find(efi_char16_t *name, efi_guid_t guid,
struct list_head *head, bool remove); struct list_head *head, bool remove);
bool efivar_validate(struct efi_variable *var, u8 *data, unsigned long len); bool efivar_validate(efi_char16_t *var_name, u8 *data, unsigned long len);
extern struct work_struct efivar_work; extern struct work_struct efivar_work;
void efivar_run_worker(void); void efivar_run_worker(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment