aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2014-03-16 08:14:49 -0400
committerMatt Fleming <matt.fleming@intel.com>2014-04-17 08:53:28 -0400
commitbafc84d539c0ffa916037840df54428623abc3e6 (patch)
tree906244e36c50e316662ab28f25386ae60a209786 /drivers/firmware
parentb738c6ea49b4e98e6ca0651da82a610f996a16ae (diff)
efivars: Use local variables instead of a pointer dereference
In order to support a compat interface we need to stop passing pointers to structures around, since the type of structure is going to depend on whether the current task is a compat task. Cc: Mike Waychison <mikew@google.com> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/efi/efivars.c48
1 files changed, 35 insertions, 13 deletions
diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
index 50ea412a25e6..06ec6ee1c58a 100644
--- a/drivers/firmware/efi/efivars.c
+++ b/drivers/firmware/efi/efivars.c
@@ -197,37 +197,48 @@ static ssize_t
197efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) 197efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
198{ 198{
199 struct efi_variable *new_var, *var = &entry->var; 199 struct efi_variable *new_var, *var = &entry->var;
200 efi_char16_t *name;
201 unsigned long size;
202 efi_guid_t vendor;
203 u32 attributes;
204 u8 *data;
200 int err; 205 int err;
201 206
202 if (count != sizeof(struct efi_variable)) 207 if (count != sizeof(struct efi_variable))
203 return -EINVAL; 208 return -EINVAL;
204 209
205 new_var = (struct efi_variable *)buf; 210 new_var = (struct efi_variable *)buf;
211
212 attributes = new_var->Attributes;
213 vendor = new_var->VendorGuid;
214 name = new_var->VariableName;
215 size = new_var->DataSize;
216 data = new_var->Data;
217
206 /* 218 /*
207 * If only updating the variable data, then the name 219 * If only updating the variable data, then the name
208 * and guid should remain the same 220 * and guid should remain the same
209 */ 221 */
210 if (memcmp(new_var->VariableName, var->VariableName, sizeof(var->VariableName)) || 222 if (memcmp(name, var->VariableName, sizeof(var->VariableName)) ||
211 efi_guidcmp(new_var->VendorGuid, var->VendorGuid)) { 223 efi_guidcmp(vendor, var->VendorGuid)) {
212 printk(KERN_ERR "efivars: Cannot edit the wrong variable!\n"); 224 printk(KERN_ERR "efivars: Cannot edit the wrong variable!\n");
213 return -EINVAL; 225 return -EINVAL;
214 } 226 }
215 227
216 if ((new_var->DataSize <= 0) || (new_var->Attributes == 0)){ 228 if ((size <= 0) || (attributes == 0)){
217 printk(KERN_ERR "efivars: DataSize & Attributes must be valid!\n"); 229 printk(KERN_ERR "efivars: DataSize & Attributes must be valid!\n");
218 return -EINVAL; 230 return -EINVAL;
219 } 231 }
220 232
221 if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 || 233 if ((attributes & ~EFI_VARIABLE_MASK) != 0 ||
222 efivar_validate(new_var, new_var->Data, new_var->DataSize) == false) { 234 efivar_validate(new_var, data, size) == false) {
223 printk(KERN_ERR "efivars: Malformed variable content\n"); 235 printk(KERN_ERR "efivars: Malformed variable content\n");
224 return -EINVAL; 236 return -EINVAL;
225 } 237 }
226 238
227 memcpy(&entry->var, new_var, count); 239 memcpy(&entry->var, new_var, count);
228 240
229 err = efivar_entry_set(entry, new_var->Attributes, 241 err = efivar_entry_set(entry, attributes, size, data, NULL);
230 new_var->DataSize, new_var->Data, NULL);
231 if (err) { 242 if (err) {
232 printk(KERN_WARNING "efivars: set_variable() failed: status=%d\n", err); 243 printk(KERN_WARNING "efivars: set_variable() failed: status=%d\n", err);
233 return -EIO; 244 return -EIO;
@@ -328,13 +339,20 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
328{ 339{
329 struct efi_variable *new_var = (struct efi_variable *)buf; 340 struct efi_variable *new_var = (struct efi_variable *)buf;
330 struct efivar_entry *new_entry; 341 struct efivar_entry *new_entry;
342 unsigned long size;
343 u32 attributes;
344 u8 *data;
331 int err; 345 int err;
332 346
333 if (!capable(CAP_SYS_ADMIN)) 347 if (!capable(CAP_SYS_ADMIN))
334 return -EACCES; 348 return -EACCES;
335 349
336 if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 || 350 attributes = new_var->Attributes;
337 efivar_validate(new_var, new_var->Data, new_var->DataSize) == false) { 351 size = new_var->DataSize;
352 data = new_var->Data;
353
354 if ((attributes & ~EFI_VARIABLE_MASK) != 0 ||
355 efivar_validate(new_var, data, size) == false) {
338 printk(KERN_ERR "efivars: Malformed variable content\n"); 356 printk(KERN_ERR "efivars: Malformed variable content\n");
339 return -EINVAL; 357 return -EINVAL;
340 } 358 }
@@ -345,8 +363,8 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
345 363
346 memcpy(&new_entry->var, new_var, sizeof(*new_var)); 364 memcpy(&new_entry->var, new_var, sizeof(*new_var));
347 365
348 err = efivar_entry_set(new_entry, new_var->Attributes, new_var->DataSize, 366 err = efivar_entry_set(new_entry, attributes, size,
349 new_var->Data, &efivar_sysfs_list); 367 data, &efivar_sysfs_list);
350 if (err) { 368 if (err) {
351 if (err == -EEXIST) 369 if (err == -EEXIST)
352 err = -EINVAL; 370 err = -EINVAL;
@@ -370,14 +388,18 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
370{ 388{
371 struct efi_variable *del_var = (struct efi_variable *)buf; 389 struct efi_variable *del_var = (struct efi_variable *)buf;
372 struct efivar_entry *entry; 390 struct efivar_entry *entry;
391 efi_char16_t *name;
392 efi_guid_t vendor;
373 int err = 0; 393 int err = 0;
374 394
375 if (!capable(CAP_SYS_ADMIN)) 395 if (!capable(CAP_SYS_ADMIN))
376 return -EACCES; 396 return -EACCES;
377 397
398 name = del_var->VariableName;
399 vendor = del_var->VendorGuid;
400
378 efivar_entry_iter_begin(); 401 efivar_entry_iter_begin();
379 entry = efivar_entry_find(del_var->VariableName, del_var->VendorGuid, 402 entry = efivar_entry_find(name, vendor, &efivar_sysfs_list, true);
380 &efivar_sysfs_list, true);
381 if (!entry) 403 if (!entry)
382 err = -EINVAL; 404 err = -EINVAL;
383 else if (__efivar_entry_delete(entry)) 405 else if (__efivar_entry_delete(entry))