diff options
author | Peter Jones <pjones@redhat.com> | 2016-02-08 14:48:13 -0500 |
---|---|---|
committer | Matt Fleming <matt@codeblueprint.co.uk> | 2016-02-10 08:19:30 -0500 |
commit | 3dcb1f55dfc7631695e69df4a0d589ce5274bd07 (patch) | |
tree | d8fb231f3d559a2b6e7be404c6ab09dcced8a757 /drivers/firmware/efi | |
parent | e0d64e6a880e64545ad7d55786aa84ab76bac475 (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.c | 32 |
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 | ||
191 | bool | 191 | bool |
192 | efivar_validate(efi_char16_t *var_name, u8 *data, unsigned long len) | 192 | efivar_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 | } |
227 | EXPORT_SYMBOL_GPL(efivar_validate); | 237 | EXPORT_SYMBOL_GPL(efivar_validate); |