[PATCH 3.12 47/58] efi: Do variable name validation tests in utf8

2016-03-16 Thread Jiri Slaby
From: Peter Jones 

3.12-stable review patch.  If anyone has any objections, please let me know.

===

commit 3dcb1f55dfc7631695e69df4a0d589ce5274bd07 upstream.

Actually translate from ucs2 to utf8 before doing the test, and then
test against our other utf8 data, instead of fudging it.

Signed-off-by: Peter Jones 
Acked-by: Matthew Garrett 
Tested-by: Lee, Chun-Yi 
Signed-off-by: Matt Fleming 
Signed-off-by: Jiri Slaby 
---
 drivers/firmware/efi/efivars.c |  4 +--
 drivers/firmware/efi/vars.c| 58 +-
 include/linux/efi.h|  6 +++--
 3 files changed, 40 insertions(+), 28 deletions(-)

diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
index 0d33f42de731..b4d5eeb78ffd 100644
--- a/drivers/firmware/efi/efivars.c
+++ b/drivers/firmware/efi/efivars.c
@@ -219,7 +219,7 @@ 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, new_var->Data, new_var->DataSize) == 
false) {
+   efivar_validate(new_var->VariableName, new_var->Data, 
new_var->DataSize) == false) {
printk(KERN_ERR "efivars: Malformed variable content\n");
return -EINVAL;
}
@@ -334,7 +334,7 @@ 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, new_var->Data, new_var->DataSize) == 
false) {
+   efivar_validate(new_var->VariableName, new_var->Data, 
new_var->DataSize) == false) {
printk(KERN_ERR "efivars: Malformed variable content\n");
return -EINVAL;
}
diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
index e6125522860a..aad48b99553f 100644
--- a/drivers/firmware/efi/vars.c
+++ b/drivers/firmware/efi/vars.c
@@ -42,7 +42,7 @@ DECLARE_WORK(efivar_work, NULL);
 EXPORT_SYMBOL_GPL(efivar_work);
 
 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)
 {
struct efi_generic_dev_path *node;
@@ -75,7 +75,7 @@ validate_device_path(struct efi_variable *var, int match, u8 
*buffer,
 }
 
 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)
 {
/* An array of 16-bit integers */
@@ -86,18 +86,18 @@ validate_boot_order(struct efi_variable *var, int match, u8 
*buffer,
 }
 
 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)
 {
u16 filepathlength;
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 */
for (i = match; i < match+4; i++) {
-   if (var->VariableName[i] > 127 ||
-   hex_to_bin(var->VariableName[i] & 0xff) < 0)
+   if (var_name[i] > 127 ||
+   hex_to_bin(var_name[i] & 0xff) < 0)
return true;
}
 
@@ -132,12 +132,12 @@ validate_load_option(struct efi_variable *var, int match, 
u8 *buffer,
/*
 * 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);
 }
 
 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)
 {
/* A single 16-bit integer */
@@ -148,7 +148,7 @@ validate_uint16(struct efi_variable *var, int match, u8 
*buffer,
 }
 
 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)
 {
int i;
@@ -166,7 +166,7 @@ validate_ascii_string(struct efi_variable *var, int match, 
u8 *buffer,
 
 struct variable_validate {
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);
 };
 
@@ -189,10 +189,19 @@ static const struct variable_validate variable_validate[] 
= {
 };
 
 bool
-efivar_validate(struct efi_variable *var, u8 

[PATCH 3.12 47/58] efi: Do variable name validation tests in utf8

2016-03-16 Thread Jiri Slaby
From: Peter Jones 

3.12-stable review patch.  If anyone has any objections, please let me know.

===

commit 3dcb1f55dfc7631695e69df4a0d589ce5274bd07 upstream.

Actually translate from ucs2 to utf8 before doing the test, and then
test against our other utf8 data, instead of fudging it.

Signed-off-by: Peter Jones 
Acked-by: Matthew Garrett 
Tested-by: Lee, Chun-Yi 
Signed-off-by: Matt Fleming 
Signed-off-by: Jiri Slaby 
---
 drivers/firmware/efi/efivars.c |  4 +--
 drivers/firmware/efi/vars.c| 58 +-
 include/linux/efi.h|  6 +++--
 3 files changed, 40 insertions(+), 28 deletions(-)

diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
index 0d33f42de731..b4d5eeb78ffd 100644
--- a/drivers/firmware/efi/efivars.c
+++ b/drivers/firmware/efi/efivars.c
@@ -219,7 +219,7 @@ 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, new_var->Data, new_var->DataSize) == 
false) {
+   efivar_validate(new_var->VariableName, new_var->Data, 
new_var->DataSize) == false) {
printk(KERN_ERR "efivars: Malformed variable content\n");
return -EINVAL;
}
@@ -334,7 +334,7 @@ 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, new_var->Data, new_var->DataSize) == 
false) {
+   efivar_validate(new_var->VariableName, new_var->Data, 
new_var->DataSize) == false) {
printk(KERN_ERR "efivars: Malformed variable content\n");
return -EINVAL;
}
diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
index e6125522860a..aad48b99553f 100644
--- a/drivers/firmware/efi/vars.c
+++ b/drivers/firmware/efi/vars.c
@@ -42,7 +42,7 @@ DECLARE_WORK(efivar_work, NULL);
 EXPORT_SYMBOL_GPL(efivar_work);
 
 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)
 {
struct efi_generic_dev_path *node;
@@ -75,7 +75,7 @@ validate_device_path(struct efi_variable *var, int match, u8 
*buffer,
 }
 
 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)
 {
/* An array of 16-bit integers */
@@ -86,18 +86,18 @@ validate_boot_order(struct efi_variable *var, int match, u8 
*buffer,
 }
 
 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)
 {
u16 filepathlength;
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 */
for (i = match; i < match+4; i++) {
-   if (var->VariableName[i] > 127 ||
-   hex_to_bin(var->VariableName[i] & 0xff) < 0)
+   if (var_name[i] > 127 ||
+   hex_to_bin(var_name[i] & 0xff) < 0)
return true;
}
 
@@ -132,12 +132,12 @@ validate_load_option(struct efi_variable *var, int match, 
u8 *buffer,
/*
 * 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);
 }
 
 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)
 {
/* A single 16-bit integer */
@@ -148,7 +148,7 @@ validate_uint16(struct efi_variable *var, int match, u8 
*buffer,
 }
 
 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)
 {
int i;
@@ -166,7 +166,7 @@ validate_ascii_string(struct efi_variable *var, int match, 
u8 *buffer,
 
 struct variable_validate {
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);
 };
 
@@ -189,10 +189,19 @@ static const struct variable_validate variable_validate[] 
= {
 };
 
 bool
-efivar_validate(struct efi_variable *var, u8 *data, unsigned long len)
+efivar_validate(efi_char16_t *var_name, u8 *data, unsigned long data_size)
 {