aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware/efi
diff options
context:
space:
mode:
authorPeter Jones <pjones@redhat.com>2016-02-08 14:48:13 -0500
committerMatt Fleming <matt@codeblueprint.co.uk>2016-02-10 08:19:30 -0500
commit3dcb1f55dfc7631695e69df4a0d589ce5274bd07 (patch)
treed8fb231f3d559a2b6e7be404c6ab09dcced8a757 /drivers/firmware/efi
parente0d64e6a880e64545ad7d55786aa84ab76bac475 (diff)
efi: Do variable name validation tests in utf8
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 <pjones@redhat.com> Acked-by: Matthew Garrett <mjg59@coreos.com> Tested-by: Lee, Chun-Yi <jlee@suse.com> Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
Diffstat (limited to 'drivers/firmware/efi')
-rw-r--r--drivers/firmware/efi/vars.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
index 70a0fb10517f..5c5fde3e6c37 100644
--- a/drivers/firmware/efi/vars.c
+++ b/drivers/firmware/efi/vars.c
@@ -189,10 +189,19 @@ static const struct variable_validate variable_validate[] = {
189}; 189};
190 190
191bool 191bool
192efivar_validate(efi_char16_t *var_name, u8 *data, unsigned long len) 192efivar_validate(efi_char16_t *var_name, u8 *data, unsigned long data_size)
193{ 193{
194 int i; 194 int i;
195 u16 *unicode_name = var_name; 195 unsigned long utf8_size;
196 u8 *utf8_name;
197
198 utf8_size = ucs2_utf8size(var_name);
199 utf8_name = kmalloc(utf8_size + 1, GFP_KERNEL);
200 if (!utf8_name)
201 return false;
202
203 ucs2_as_utf8(utf8_name, var_name, utf8_size);
204 utf8_name[utf8_size] = '\0';
196 205
197 for (i = 0; variable_validate[i].validate != NULL; i++) { 206 for (i = 0; variable_validate[i].validate != NULL; i++) {
198 const char *name = variable_validate[i].name; 207 const char *name = variable_validate[i].name;
@@ -200,28 +209,29 @@ efivar_validate(efi_char16_t *var_name, u8 *data, unsigned long len)
200 209
201 for (match = 0; ; match++) { 210 for (match = 0; ; match++) {
202 char c = name[match]; 211 char c = name[match];
203 u16 u = unicode_name[match]; 212 char u = utf8_name[match];
204
205 /* All special variables are plain ascii */
206 if (u > 127)
207 return true;
208 213
209 /* Wildcard in the matching name means we've matched */ 214 /* Wildcard in the matching name means we've matched */
210 if (c == '*') 215 if (c == '*') {
216 kfree(utf8_name);
211 return variable_validate[i].validate(var_name, 217 return variable_validate[i].validate(var_name,
212 match, data, len); 218 match, data, data_size);
219 }
213 220
214 /* Case sensitive match */ 221 /* Case sensitive match */
215 if (c != u) 222 if (c != u)
216 break; 223 break;
217 224
218 /* Reached the end of the string while matching */ 225 /* Reached the end of the string while matching */
219 if (!c) 226 if (!c) {
227 kfree(utf8_name);
220 return variable_validate[i].validate(var_name, 228 return variable_validate[i].validate(var_name,
221 match, data, len); 229 match, data, data_size);
230 }
222 } 231 }
223 } 232 }
224 233
234 kfree(utf8_name);
225 return true; 235 return true;
226} 236}
227EXPORT_SYMBOL_GPL(efivar_validate); 237EXPORT_SYMBOL_GPL(efivar_validate);