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;
}
Example #2
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;
}