|
|
@@ -318,7 +318,12 @@ EXPORT_SYMBOL_GPL(efivar_variable_is_removable);
|
|
|
static efi_status_t
|
|
|
check_var_size(u32 attributes, unsigned long size)
|
|
|
{
|
|
|
- const struct efivar_operations *fops = __efivars->ops;
|
|
|
+ const struct efivar_operations *fops;
|
|
|
+
|
|
|
+ if (!__efivars)
|
|
|
+ return EFI_UNSUPPORTED;
|
|
|
+
|
|
|
+ fops = __efivars->ops;
|
|
|
|
|
|
if (!fops->query_variable_store)
|
|
|
return EFI_UNSUPPORTED;
|
|
|
@@ -329,7 +334,12 @@ check_var_size(u32 attributes, unsigned long size)
|
|
|
static efi_status_t
|
|
|
check_var_size_nonblocking(u32 attributes, unsigned long size)
|
|
|
{
|
|
|
- const struct efivar_operations *fops = __efivars->ops;
|
|
|
+ const struct efivar_operations *fops;
|
|
|
+
|
|
|
+ if (!__efivars)
|
|
|
+ return EFI_UNSUPPORTED;
|
|
|
+
|
|
|
+ fops = __efivars->ops;
|
|
|
|
|
|
if (!fops->query_variable_store)
|
|
|
return EFI_UNSUPPORTED;
|
|
|
@@ -429,13 +439,18 @@ static void dup_variable_bug(efi_char16_t *str16, efi_guid_t *vendor_guid,
|
|
|
int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
|
|
|
void *data, bool duplicates, struct list_head *head)
|
|
|
{
|
|
|
- const struct efivar_operations *ops = __efivars->ops;
|
|
|
+ const struct efivar_operations *ops;
|
|
|
unsigned long variable_name_size = 1024;
|
|
|
efi_char16_t *variable_name;
|
|
|
efi_status_t status;
|
|
|
efi_guid_t vendor_guid;
|
|
|
int err = 0;
|
|
|
|
|
|
+ if (!__efivars)
|
|
|
+ return -EFAULT;
|
|
|
+
|
|
|
+ ops = __efivars->ops;
|
|
|
+
|
|
|
variable_name = kzalloc(variable_name_size, GFP_KERNEL);
|
|
|
if (!variable_name) {
|
|
|
printk(KERN_ERR "efivars: Memory allocation failed.\n");
|
|
|
@@ -583,12 +598,14 @@ static void efivar_entry_list_del_unlock(struct efivar_entry *entry)
|
|
|
*/
|
|
|
int __efivar_entry_delete(struct efivar_entry *entry)
|
|
|
{
|
|
|
- const struct efivar_operations *ops = __efivars->ops;
|
|
|
efi_status_t status;
|
|
|
|
|
|
- status = ops->set_variable(entry->var.VariableName,
|
|
|
- &entry->var.VendorGuid,
|
|
|
- 0, 0, NULL);
|
|
|
+ if (!__efivars)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ status = __efivars->ops->set_variable(entry->var.VariableName,
|
|
|
+ &entry->var.VendorGuid,
|
|
|
+ 0, 0, NULL);
|
|
|
|
|
|
return efi_status_to_err(status);
|
|
|
}
|
|
|
@@ -607,12 +624,17 @@ EXPORT_SYMBOL_GPL(__efivar_entry_delete);
|
|
|
*/
|
|
|
int efivar_entry_delete(struct efivar_entry *entry)
|
|
|
{
|
|
|
- const struct efivar_operations *ops = __efivars->ops;
|
|
|
+ const struct efivar_operations *ops;
|
|
|
efi_status_t status;
|
|
|
|
|
|
if (down_interruptible(&efivars_lock))
|
|
|
return -EINTR;
|
|
|
|
|
|
+ if (!__efivars) {
|
|
|
+ up(&efivars_lock);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ ops = __efivars->ops;
|
|
|
status = ops->set_variable(entry->var.VariableName,
|
|
|
&entry->var.VendorGuid,
|
|
|
0, 0, NULL);
|
|
|
@@ -650,13 +672,19 @@ EXPORT_SYMBOL_GPL(efivar_entry_delete);
|
|
|
int efivar_entry_set(struct efivar_entry *entry, u32 attributes,
|
|
|
unsigned long size, void *data, struct list_head *head)
|
|
|
{
|
|
|
- const struct efivar_operations *ops = __efivars->ops;
|
|
|
+ const struct efivar_operations *ops;
|
|
|
efi_status_t status;
|
|
|
efi_char16_t *name = entry->var.VariableName;
|
|
|
efi_guid_t vendor = entry->var.VendorGuid;
|
|
|
|
|
|
if (down_interruptible(&efivars_lock))
|
|
|
return -EINTR;
|
|
|
+
|
|
|
+ if (!__efivars) {
|
|
|
+ up(&efivars_lock);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ ops = __efivars->ops;
|
|
|
if (head && efivar_entry_find(name, vendor, head, false)) {
|
|
|
up(&efivars_lock);
|
|
|
return -EEXIST;
|
|
|
@@ -687,12 +715,17 @@ static int
|
|
|
efivar_entry_set_nonblocking(efi_char16_t *name, efi_guid_t vendor,
|
|
|
u32 attributes, unsigned long size, void *data)
|
|
|
{
|
|
|
- const struct efivar_operations *ops = __efivars->ops;
|
|
|
+ const struct efivar_operations *ops;
|
|
|
efi_status_t status;
|
|
|
|
|
|
if (down_trylock(&efivars_lock))
|
|
|
return -EBUSY;
|
|
|
|
|
|
+ if (!__efivars) {
|
|
|
+ up(&efivars_lock);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
status = check_var_size_nonblocking(attributes,
|
|
|
size + ucs2_strsize(name, 1024));
|
|
|
if (status != EFI_SUCCESS) {
|
|
|
@@ -700,6 +733,7 @@ efivar_entry_set_nonblocking(efi_char16_t *name, efi_guid_t vendor,
|
|
|
return -ENOSPC;
|
|
|
}
|
|
|
|
|
|
+ ops = __efivars->ops;
|
|
|
status = ops->set_variable_nonblocking(name, &vendor, attributes,
|
|
|
size, data);
|
|
|
|
|
|
@@ -727,9 +761,13 @@ efivar_entry_set_nonblocking(efi_char16_t *name, efi_guid_t vendor,
|
|
|
int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes,
|
|
|
bool block, unsigned long size, void *data)
|
|
|
{
|
|
|
- const struct efivar_operations *ops = __efivars->ops;
|
|
|
+ const struct efivar_operations *ops;
|
|
|
efi_status_t status;
|
|
|
|
|
|
+ if (!__efivars)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ ops = __efivars->ops;
|
|
|
if (!ops->query_variable_store)
|
|
|
return -ENOSYS;
|
|
|
|
|
|
@@ -829,13 +867,18 @@ EXPORT_SYMBOL_GPL(efivar_entry_find);
|
|
|
*/
|
|
|
int efivar_entry_size(struct efivar_entry *entry, unsigned long *size)
|
|
|
{
|
|
|
- const struct efivar_operations *ops = __efivars->ops;
|
|
|
+ const struct efivar_operations *ops;
|
|
|
efi_status_t status;
|
|
|
|
|
|
*size = 0;
|
|
|
|
|
|
if (down_interruptible(&efivars_lock))
|
|
|
return -EINTR;
|
|
|
+ if (!__efivars) {
|
|
|
+ up(&efivars_lock);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ ops = __efivars->ops;
|
|
|
status = ops->get_variable(entry->var.VariableName,
|
|
|
&entry->var.VendorGuid, NULL, size, NULL);
|
|
|
up(&efivars_lock);
|
|
|
@@ -861,12 +904,14 @@ EXPORT_SYMBOL_GPL(efivar_entry_size);
|
|
|
int __efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
|
|
|
unsigned long *size, void *data)
|
|
|
{
|
|
|
- const struct efivar_operations *ops = __efivars->ops;
|
|
|
efi_status_t status;
|
|
|
|
|
|
- status = ops->get_variable(entry->var.VariableName,
|
|
|
- &entry->var.VendorGuid,
|
|
|
- attributes, size, data);
|
|
|
+ if (!__efivars)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ status = __efivars->ops->get_variable(entry->var.VariableName,
|
|
|
+ &entry->var.VendorGuid,
|
|
|
+ attributes, size, data);
|
|
|
|
|
|
return efi_status_to_err(status);
|
|
|
}
|
|
|
@@ -882,14 +927,19 @@ EXPORT_SYMBOL_GPL(__efivar_entry_get);
|
|
|
int efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
|
|
|
unsigned long *size, void *data)
|
|
|
{
|
|
|
- const struct efivar_operations *ops = __efivars->ops;
|
|
|
efi_status_t status;
|
|
|
|
|
|
if (down_interruptible(&efivars_lock))
|
|
|
return -EINTR;
|
|
|
- status = ops->get_variable(entry->var.VariableName,
|
|
|
- &entry->var.VendorGuid,
|
|
|
- attributes, size, data);
|
|
|
+
|
|
|
+ if (!__efivars) {
|
|
|
+ up(&efivars_lock);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ status = __efivars->ops->get_variable(entry->var.VariableName,
|
|
|
+ &entry->var.VendorGuid,
|
|
|
+ attributes, size, data);
|
|
|
up(&efivars_lock);
|
|
|
|
|
|
return efi_status_to_err(status);
|
|
|
@@ -921,7 +971,7 @@ EXPORT_SYMBOL_GPL(efivar_entry_get);
|
|
|
int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes,
|
|
|
unsigned long *size, void *data, bool *set)
|
|
|
{
|
|
|
- const struct efivar_operations *ops = __efivars->ops;
|
|
|
+ const struct efivar_operations *ops;
|
|
|
efi_char16_t *name = entry->var.VariableName;
|
|
|
efi_guid_t *vendor = &entry->var.VendorGuid;
|
|
|
efi_status_t status;
|
|
|
@@ -940,6 +990,11 @@ int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes,
|
|
|
if (down_interruptible(&efivars_lock))
|
|
|
return -EINTR;
|
|
|
|
|
|
+ if (!__efivars) {
|
|
|
+ err = -EINVAL;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
/*
|
|
|
* Ensure that the available space hasn't shrunk below the safe level
|
|
|
*/
|
|
|
@@ -956,6 +1011,8 @@ int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ ops = __efivars->ops;
|
|
|
+
|
|
|
status = ops->set_variable(name, vendor, attributes, *size, data);
|
|
|
if (status != EFI_SUCCESS) {
|
|
|
err = efi_status_to_err(status);
|