static int efivars_sysfs_callback(efi_char16_t *name, efi_guid_t vendor, unsigned long name_size, void *data) { struct efivar_entry *entry; entry = kzalloc(sizeof(*entry), GFP_KERNEL); if (!entry) return -ENOMEM; memcpy(entry->var.VariableName, name, name_size); memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t)); efivar_create_sysfs_entry(entry); return 0; }
static ssize_t efivar_create(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t count) { struct efi_variable *new_var = (struct efi_variable *)buf; struct efivar_entry *new_entry; int err; if (!capable(CAP_SYS_ADMIN)) return -EACCES; if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 || efivar_validate(new_var, new_var->Data, new_var->DataSize) == false) { printk(KERN_ERR "efivars: Malformed variable content\n"); return -EINVAL; } new_entry = kzalloc(sizeof(*new_entry), GFP_KERNEL); if (!new_entry) return -ENOMEM; memcpy(&new_entry->var, new_var, sizeof(*new_var)); err = efivar_entry_set(new_entry, new_var->Attributes, new_var->DataSize, new_var->Data, &efivar_sysfs_list); if (err) { if (err == -EEXIST) err = -EINVAL; goto out; } if (efivar_create_sysfs_entry(new_entry)) { printk(KERN_WARNING "efivars: failed to create sysfs entry.\n"); kfree(new_entry); } return count; out: kfree(new_entry); return err; }
static void efivar_update_sysfs_entries(struct work_struct *work) { struct efivar_entry *entry; int err; /* Add new sysfs entries */ while (1) { entry = kzalloc(sizeof(*entry), GFP_KERNEL); if (!entry) return; err = efivar_init(efivar_update_sysfs_entry, entry, true, false, &efivar_sysfs_list); if (!err) break; efivar_create_sysfs_entry(entry); } kfree(entry); }
static ssize_t efivar_create(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t count) { struct compat_efi_variable *compat = (struct compat_efi_variable *)buf; struct efi_variable *new_var = (struct efi_variable *)buf; struct efivar_entry *new_entry; bool need_compat = is_compat(); efi_char16_t *name; unsigned long size; u32 attributes; u8 *data; int err; if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (need_compat) { if (count != sizeof(*compat)) return -EINVAL; attributes = compat->Attributes; name = compat->VariableName; size = compat->DataSize; data = compat->Data; } else { if (count != sizeof(*new_var)) return -EINVAL; attributes = new_var->Attributes; name = new_var->VariableName; size = new_var->DataSize; data = new_var->Data; } if ((attributes & ~EFI_VARIABLE_MASK) != 0 || efivar_validate(new_var->VendorGuid, name, data, size) == false) { printk(KERN_ERR "efivars: Malformed variable content\n"); return -EINVAL; } new_entry = kzalloc(sizeof(*new_entry), GFP_KERNEL); if (!new_entry) return -ENOMEM; if (need_compat) copy_out_compat(&new_entry->var, compat); else memcpy(&new_entry->var, new_var, sizeof(*new_var)); err = efivar_entry_set(new_entry, attributes, size, data, &efivar_sysfs_list); if (err) { if (err == -EEXIST) err = -EINVAL; goto out; } if (efivar_create_sysfs_entry(new_entry)) { printk(KERN_WARNING "efivars: failed to create sysfs entry.\n"); kfree(new_entry); } return count; out: kfree(new_entry); return err; }