History

Merge tag 'efi-efivars-removal-for-v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi

Pull efivars sysfs interface removal from Ard Biesheuvel: "Remove the obsolete 'efivars' sysfs based interface to the EFI variable store, now that all users have moved to the efivarfs pseudo file system, which was created ~10 years ago to address some fundamental shortcomings in the sysfs based driver. Move the 'business logic' related to which EFI variables are important and may affect the boot flow from the efivars support layer into the efivarfs pseudo file system, so it is no longer exposed to other parts of the kernel" * tag 'efi-efivars-removal-for-v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi: efi: vars: Move efivar caching layer into efivarfs efi: vars: Switch to new wrapper layer efi: vars: Remove deprecated 'efivars' sysfs interface

Linus Torvalds committed 4 years ago

Commit ab17c0c2 parents 97a77ab 2d82e6218 files · +781 −1762Browse files

Unified · Split

18 files
  1. Documentation/x86/x86_64/uefi.rst +1 −1
  2. arch/arm/configs/milbeaut_m10v_defconfig +0 −1
  3. arch/ia64/configs/bigsur_defconfig +0 −1
  4. arch/ia64/configs/generic_defconfig +0 −1
  5. arch/ia64/configs/gensparse_defconfig +0 −1
  6. arch/ia64/configs/tiger_defconfig +0 −1
  7. arch/ia64/configs/zx1_defconfig +0 −1
  8. arch/x86/configs/i386_defconfig +0 −1
  9. arch/x86/configs/x86_64_defconfig +0 −1
  10. drivers/firmware/efi/Kconfig +0 −12
  11. drivers/firmware/efi/Makefile +0 −1
  12. drivers/firmware/efi/efi.c +1 −0
  13. drivers/firmware/efi/efivars.c +0 −660
  14. drivers/firmware/efi/vars.c +0 −1023
  15. fs/efivarfs/Makefile +1 −1
  16. fs/efivarfs/internal.h +40 −0
  17. fs/efivarfs/vars.c +738 −0
  18. include/linux/efi.h +0 −56
Documentation/x86/x86_64/uefi.rst+1−1
@@ -29,7 +29,7 @@ Mechanics · 28 unmodified lines
29 be selected::29 be selected::
30 30
31 CONFIG_EFI=y31 CONFIG_EFI=y
32 CONFIG_EFI_VARS=y or m # optional32 CONFIG_EFIVAR_FS=y or m # optional
33 33
34- Create a VFAT partition on the disk34- Create a VFAT partition on the disk
35- Copy the following to the VFAT partition:35- Copy the following to the VFAT partition:
arch/arm/configs/milbeaut_m10v_defconfig+0−1
@@ -44,7 +44,6 @@ CONFIG_ARM_CPUIDLE=y · 43 unmodified lines
44CONFIG_VFP=y44CONFIG_VFP=y
45CONFIG_NEON=y45CONFIG_NEON=y
46CONFIG_KERNEL_MODE_NEON=y46CONFIG_KERNEL_MODE_NEON=y
47CONFIG_EFI_VARS=m
48CONFIG_ARM_CRYPTO=y47CONFIG_ARM_CRYPTO=y
49CONFIG_CRYPTO_SHA1_ARM_NEON=m48CONFIG_CRYPTO_SHA1_ARM_NEON=m
50CONFIG_CRYPTO_SHA1_ARM_CE=m49CONFIG_CRYPTO_SHA1_ARM_CE=m
arch/ia64/configs/bigsur_defconfig+0−1
@@ -10,7 +10,6 @@ CONFIG_SMP=y · 9 unmodified lines
10CONFIG_NR_CPUS=210CONFIG_NR_CPUS=2
11CONFIG_PREEMPT=y11CONFIG_PREEMPT=y
12CONFIG_IA64_PALINFO=y12CONFIG_IA64_PALINFO=y
13CONFIG_EFI_VARS=y
14CONFIG_BINFMT_MISC=m13CONFIG_BINFMT_MISC=m
15CONFIG_ACPI_BUTTON=m14CONFIG_ACPI_BUTTON=m
16CONFIG_ACPI_FAN=m15CONFIG_ACPI_FAN=m
arch/ia64/configs/generic_defconfig+0−1
@@ -21,7 +21,6 @@ CONFIG_IA64_MCA_RECOVERY=y · 20 unmodified lines
21CONFIG_IA64_PALINFO=y21CONFIG_IA64_PALINFO=y
22CONFIG_KEXEC=y22CONFIG_KEXEC=y
23CONFIG_CRASH_DUMP=y23CONFIG_CRASH_DUMP=y
24CONFIG_EFI_VARS=y
25CONFIG_BINFMT_MISC=m24CONFIG_BINFMT_MISC=m
26CONFIG_ACPI_BUTTON=m25CONFIG_ACPI_BUTTON=m
27CONFIG_ACPI_FAN=m26CONFIG_ACPI_FAN=m
arch/ia64/configs/gensparse_defconfig+0−1
@@ -18,7 +18,6 @@ CONFIG_HOTPLUG_CPU=y · 17 unmodified lines
18CONFIG_SPARSEMEM_MANUAL=y18CONFIG_SPARSEMEM_MANUAL=y
19CONFIG_IA64_MCA_RECOVERY=y19CONFIG_IA64_MCA_RECOVERY=y
20CONFIG_IA64_PALINFO=y20CONFIG_IA64_PALINFO=y
21CONFIG_EFI_VARS=y
22CONFIG_BINFMT_MISC=m21CONFIG_BINFMT_MISC=m
23CONFIG_ACPI_BUTTON=m22CONFIG_ACPI_BUTTON=m
24CONFIG_ACPI_FAN=m23CONFIG_ACPI_FAN=m
arch/ia64/configs/tiger_defconfig+0−1
@@ -23,7 +23,6 @@ CONFIG_FORCE_CPEI_RETARGET=y · 22 unmodified lines
23CONFIG_IA64_MCA_RECOVERY=y23CONFIG_IA64_MCA_RECOVERY=y
24CONFIG_IA64_PALINFO=y24CONFIG_IA64_PALINFO=y
25CONFIG_KEXEC=y25CONFIG_KEXEC=y
26CONFIG_EFI_VARS=y
27CONFIG_BINFMT_MISC=m26CONFIG_BINFMT_MISC=m
28CONFIG_ACPI_BUTTON=m27CONFIG_ACPI_BUTTON=m
29CONFIG_ACPI_FAN=m28CONFIG_ACPI_FAN=m
arch/ia64/configs/zx1_defconfig+0−1
@@ -12,7 +12,6 @@ CONFIG_FLATMEM_MANUAL=y · 11 unmodified lines
12CONFIG_IA64_MCA_RECOVERY=y12CONFIG_IA64_MCA_RECOVERY=y
13CONFIG_IA64_PALINFO=y13CONFIG_IA64_PALINFO=y
14CONFIG_CRASH_DUMP=y14CONFIG_CRASH_DUMP=y
15CONFIG_EFI_VARS=y
16CONFIG_BINFMT_MISC=y15CONFIG_BINFMT_MISC=y
17CONFIG_HOTPLUG_PCI=y16CONFIG_HOTPLUG_PCI=y
18CONFIG_HOTPLUG_PCI_ACPI=y17CONFIG_HOTPLUG_PCI_ACPI=y
arch/x86/configs/i386_defconfig+0−1
@@ -135,7 +135,6 @@ CONFIG_DEVTMPFS=y · 134 unmodified lines
135CONFIG_DEVTMPFS_MOUNT=y135CONFIG_DEVTMPFS_MOUNT=y
136CONFIG_DEBUG_DEVRES=y136CONFIG_DEBUG_DEVRES=y
137CONFIG_CONNECTOR=y137CONFIG_CONNECTOR=y
138CONFIG_EFI_VARS=y
139CONFIG_EFI_CAPSULE_LOADER=y138CONFIG_EFI_CAPSULE_LOADER=y
140CONFIG_BLK_DEV_LOOP=y139CONFIG_BLK_DEV_LOOP=y
141CONFIG_VIRTIO_BLK=y140CONFIG_VIRTIO_BLK=y
arch/x86/configs/x86_64_defconfig+0−1
@@ -134,7 +134,6 @@ CONFIG_DEVTMPFS=y · 133 unmodified lines
134CONFIG_DEVTMPFS_MOUNT=y134CONFIG_DEVTMPFS_MOUNT=y
135CONFIG_DEBUG_DEVRES=y135CONFIG_DEBUG_DEVRES=y
136CONFIG_CONNECTOR=y136CONFIG_CONNECTOR=y
137CONFIG_EFI_VARS=y
138CONFIG_BLK_DEV_LOOP=y137CONFIG_BLK_DEV_LOOP=y
139CONFIG_VIRTIO_BLK=y138CONFIG_VIRTIO_BLK=y
140CONFIG_BLK_DEV_SD=y139CONFIG_BLK_DEV_SD=y
drivers/firmware/efi/Kconfig+0−12
@@ -2,18 +2,6 @@ · 1 unmodified line
2menu "EFI (Extensible Firmware Interface) Support"2menu "EFI (Extensible Firmware Interface) Support"
3 depends on EFI3 depends on EFI
4 4
5config EFI_VARS
6 tristate "EFI Variable Support via sysfs"
7 depends on EFI && (X86 || IA64)
8 default n
9 help
10 If you say Y here, you are able to get EFI (Extensible Firmware
11 Interface) variable information via sysfs. You may read,
12 write, create, and destroy EFI variables through this interface.
13 Note that this driver is only retained for compatibility with
14 legacy users: new users should use the efivarfs filesystem
15 instead.
16
17config EFI_ESRT5config EFI_ESRT
18 bool6 bool
19 depends on EFI && !IA647 depends on EFI && !IA64
drivers/firmware/efi/Makefile+0−1
@@ -17,7 +17,6 @@ ifneq ($(CONFIG_EFI_CAPSULE_LOADER),) · 16 unmodified lines
17obj-$(CONFIG_EFI) += capsule.o17obj-$(CONFIG_EFI) += capsule.o
18endif18endif
19obj-$(CONFIG_EFI_PARAMS_FROM_FDT) += fdtparams.o19obj-$(CONFIG_EFI_PARAMS_FROM_FDT) += fdtparams.o
20obj-$(CONFIG_EFI_VARS) += efivars.o
21obj-$(CONFIG_EFI_ESRT) += esrt.o20obj-$(CONFIG_EFI_ESRT) += esrt.o
22obj-$(CONFIG_EFI_VARS_PSTORE) += efi-pstore.o21obj-$(CONFIG_EFI_VARS_PSTORE) += efi-pstore.o
23obj-$(CONFIG_UEFI_CPER) += cper.o22obj-$(CONFIG_UEFI_CPER) += cper.o
drivers/firmware/efi/efi.c+1−0
@@ -899,6 +899,7 @@ int efi_status_to_err(efi_status_t status) · 898 unmodified lines
899 899
900 return err;900 return err;
901}901}
902EXPORT_SYMBOL_GPL(efi_status_to_err);
902 903
903static DEFINE_SPINLOCK(efi_mem_reserve_persistent_lock);904static DEFINE_SPINLOCK(efi_mem_reserve_persistent_lock);
904static struct linux_efi_memreserve *efi_memreserve_root __ro_after_init;905static struct linux_efi_memreserve *efi_memreserve_root __ro_after_init;
drivers/firmware/efi/efivars.c+0−660
@@ -1,660 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Originally from efivars.c,
4 *
5 * Copyright (C) 2001,2003,2004 Dell <Matt_Domsch@dell.com>
6 * Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com>
7 *
8 * This code takes all variables accessible from EFI runtime and
9 * exports them via sysfs
10 */
11
12#include <linux/efi.h>
13#include <linux/module.h>
14#include <linux/slab.h>
15#include <linux/ucs2_string.h>
16#include <linux/compat.h>
17
18#define EFIVARS_VERSION "0.08"
19#define EFIVARS_DATE "2004-May-17"
20
21MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>");
22MODULE_DESCRIPTION("sysfs interface to EFI Variables");
23MODULE_LICENSE("GPL");
24MODULE_VERSION(EFIVARS_VERSION);
25
26static LIST_HEAD(efivar_sysfs_list);
27
28static struct kset *efivars_kset;
29
30static struct bin_attribute *efivars_new_var;
31static struct bin_attribute *efivars_del_var;
32
33struct compat_efi_variable {
34 efi_char16_t VariableName[EFI_VAR_NAME_LEN/sizeof(efi_char16_t)];
35 efi_guid_t VendorGuid;
36 __u32 DataSize;
37 __u8 Data[1024];
38 __u32 Status;
39 __u32 Attributes;
40} __packed;
41
42struct efivar_attribute {
43 struct attribute attr;
44 ssize_t (*show) (struct efivar_entry *entry, char *buf);
45 ssize_t (*store)(struct efivar_entry *entry, const char *buf, size_t count);
46};
47
48#define EFIVAR_ATTR(_name, _mode, _show, _store) \
49struct efivar_attribute efivar_attr_##_name = { \
50 .attr = {.name = __stringify(_name), .mode = _mode}, \
51 .show = _show, \
52 .store = _store, \
53};
54
55#define to_efivar_attr(_attr) container_of(_attr, struct efivar_attribute, attr)
56#define to_efivar_entry(obj) container_of(obj, struct efivar_entry, kobj)
57
58/*
59 * Prototype for sysfs creation function
60 */
61static int
62efivar_create_sysfs_entry(struct efivar_entry *new_var);
63
64static ssize_t
65efivar_guid_read(struct efivar_entry *entry, char *buf)
66{
67 struct efi_variable *var = &entry->var;
68 char *str = buf;
69
70 if (!entry || !buf)
71 return 0;
72
73 efi_guid_to_str(&var->VendorGuid, str);
74 str += strlen(str);
75 str += sprintf(str, "\n");
76
77 return str - buf;
78}
79
80static ssize_t
81efivar_attr_read(struct efivar_entry *entry, char *buf)
82{
83 struct efi_variable *var = &entry->var;
84 unsigned long size = sizeof(var->Data);
85 char *str = buf;
86 int ret;
87
88 if (!entry || !buf)
89 return -EINVAL;
90
91 ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data);
92 var->DataSize = size;
93 if (ret)
94 return -EIO;
95
96 if (var->Attributes & EFI_VARIABLE_NON_VOLATILE)
97 str += sprintf(str, "EFI_VARIABLE_NON_VOLATILE\n");
98 if (var->Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS)
99 str += sprintf(str, "EFI_VARIABLE_BOOTSERVICE_ACCESS\n");
100 if (var->Attributes & EFI_VARIABLE_RUNTIME_ACCESS)
101 str += sprintf(str, "EFI_VARIABLE_RUNTIME_ACCESS\n");
102 if (var->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD)
103 str += sprintf(str, "EFI_VARIABLE_HARDWARE_ERROR_RECORD\n");
104 if (var->Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)
105 str += sprintf(str,
106 "EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS\n");
107 if (var->Attributes &
108 EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)
109 str += sprintf(str,
110 "EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS\n");
111 if (var->Attributes & EFI_VARIABLE_APPEND_WRITE)
112 str += sprintf(str, "EFI_VARIABLE_APPEND_WRITE\n");
113 return str - buf;
114}
115
116static ssize_t
117efivar_size_read(struct efivar_entry *entry, char *buf)
118{
119 struct efi_variable *var = &entry->var;
120 unsigned long size = sizeof(var->Data);
121 char *str = buf;
122 int ret;
123
124 if (!entry || !buf)
125 return -EINVAL;
126
127 ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data);
128 var->DataSize = size;
129 if (ret)
130 return -EIO;
131
132 str += sprintf(str, "0x%lx\n", var->DataSize);
133 return str - buf;
134}
135
136static ssize_t
137efivar_data_read(struct efivar_entry *entry, char *buf)
138{
139 struct efi_variable *var = &entry->var;
140 unsigned long size = sizeof(var->Data);
141 int ret;
142
143 if (!entry || !buf)
144 return -EINVAL;
145
146 ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data);
147 var->DataSize = size;
148 if (ret)
149 return -EIO;
150
151 memcpy(buf, var->Data, var->DataSize);
152 return var->DataSize;
153}
154
155static inline int
156sanity_check(struct efi_variable *var, efi_char16_t *name, efi_guid_t vendor,
157 unsigned long size, u32 attributes, u8 *data)
158{
159 /*
160 * If only updating the variable data, then the name
161 * and guid should remain the same
162 */
163 if (memcmp(name, var->VariableName, sizeof(var->VariableName)) ||
164 efi_guidcmp(vendor, var->VendorGuid)) {
165 printk(KERN_ERR "efivars: Cannot edit the wrong variable!\n");
166 return -EINVAL;
167 }
168
169 if ((size <= 0) || (attributes == 0)){
170 printk(KERN_ERR "efivars: DataSize & Attributes must be valid!\n");
171 return -EINVAL;
172 }
173
174 if ((attributes & ~EFI_VARIABLE_MASK) != 0 ||
175 efivar_validate(vendor, name, data, size) == false) {
176 printk(KERN_ERR "efivars: Malformed variable content\n");
177 return -EINVAL;
178 }
179
180 return 0;
181}
182
183static void
184copy_out_compat(struct efi_variable *dst, struct compat_efi_variable *src)
185{
186 memcpy(dst->VariableName, src->VariableName, EFI_VAR_NAME_LEN);
187 memcpy(dst->Data, src->Data, sizeof(src->Data));
188
189 dst->VendorGuid = src->VendorGuid;
190 dst->DataSize = src->DataSize;
191 dst->Attributes = src->Attributes;
192}
193
194/*
195 * We allow each variable to be edited via rewriting the
196 * entire efi variable structure.
197 */
198static ssize_t
199efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
200{
201 struct efi_variable *new_var, *var = &entry->var;
202 efi_char16_t *name;
203 unsigned long size;
204 efi_guid_t vendor;
205 u32 attributes;
206 u8 *data;
207 int err;
208
209 if (!entry || !buf)
210 return -EINVAL;
211
212 if (in_compat_syscall()) {
213 struct compat_efi_variable *compat;
214
215 if (count != sizeof(*compat))
216 return -EINVAL;
217
218 compat = (struct compat_efi_variable *)buf;
219 attributes = compat->Attributes;
220 vendor = compat->VendorGuid;
221 name = compat->VariableName;
222 size = compat->DataSize;
223 data = compat->Data;
224
225 err = sanity_check(var, name, vendor, size, attributes, data);
226 if (err)
227 return err;
228
229 copy_out_compat(&entry->var, compat);
230 } else {
231 if (count != sizeof(struct efi_variable))
232 return -EINVAL;
233
234 new_var = (struct efi_variable *)buf;
235
236 attributes = new_var->Attributes;
237 vendor = new_var->VendorGuid;
238 name = new_var->VariableName;
239 size = new_var->DataSize;
240 data = new_var->Data;
241
242 err = sanity_check(var, name, vendor, size, attributes, data);
243 if (err)
244 return err;
245
246 memcpy(&entry->var, new_var, count);
247 }
248
249 err = efivar_entry_set(entry, attributes, size, data, NULL);
250 if (err) {
251 printk(KERN_WARNING "efivars: set_variable() failed: status=%d\n", err);
252 return -EIO;
253 }
254
255 return count;
256}
257
258static ssize_t
259efivar_show_raw(struct efivar_entry *entry, char *buf)
260{
261 struct efi_variable *var = &entry->var;
262 struct compat_efi_variable *compat;
263 unsigned long datasize = sizeof(var->Data);
264 size_t size;
265 int ret;
266
267 if (!entry || !buf)
268 return 0;
269
270 ret = efivar_entry_get(entry, &var->Attributes, &datasize, var->Data);
271 var->DataSize = datasize;
272 if (ret)
273 return -EIO;
274
275 if (in_compat_syscall()) {
276 compat = (struct compat_efi_variable *)buf;
277
278 size = sizeof(*compat);
279 memcpy(compat->VariableName, var->VariableName,
280 EFI_VAR_NAME_LEN);
281 memcpy(compat->Data, var->Data, sizeof(compat->Data));
282
283 compat->VendorGuid = var->VendorGuid;
284 compat->DataSize = var->DataSize;
285 compat->Attributes = var->Attributes;
286 } else {
287 size = sizeof(*var);
288 memcpy(buf, var, size);
289 }
290
291 return size;
292}
293
294/*
295 * Generic read/write functions that call the specific functions of
296 * the attributes...
297 */
298static ssize_t efivar_attr_show(struct kobject *kobj, struct attribute *attr,
299 char *buf)
300{
301 struct efivar_entry *var = to_efivar_entry(kobj);
302 struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
303 ssize_t ret = -EIO;
304
305 if (!capable(CAP_SYS_ADMIN))
306 return -EACCES;
307
308 if (efivar_attr->show) {
309 ret = efivar_attr->show(var, buf);
310 }
311 return ret;
312}
313
314static ssize_t efivar_attr_store(struct kobject *kobj, struct attribute *attr,
315 const char *buf, size_t count)
316{
317 struct efivar_entry *var = to_efivar_entry(kobj);
318 struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
319 ssize_t ret = -EIO;
320
321 if (!capable(CAP_SYS_ADMIN))
322 return -EACCES;
323
324 if (efivar_attr->store)
325 ret = efivar_attr->store(var, buf, count);
326
327 return ret;
328}
329
330static const struct sysfs_ops efivar_attr_ops = {
331 .show = efivar_attr_show,
332 .store = efivar_attr_store,
333};
334
335static void efivar_release(struct kobject *kobj)
336{
337 struct efivar_entry *var = to_efivar_entry(kobj);
338 kfree(var);
339}
340
341static EFIVAR_ATTR(guid, 0400, efivar_guid_read, NULL);
342static EFIVAR_ATTR(attributes, 0400, efivar_attr_read, NULL);
343static EFIVAR_ATTR(size, 0400, efivar_size_read, NULL);
344static EFIVAR_ATTR(data, 0400, efivar_data_read, NULL);
345static EFIVAR_ATTR(raw_var, 0600, efivar_show_raw, efivar_store_raw);
346
347static struct attribute *def_attrs[] = {
348 &efivar_attr_guid.attr,
349 &efivar_attr_size.attr,
350 &efivar_attr_attributes.attr,
351 &efivar_attr_data.attr,
352 &efivar_attr_raw_var.attr,
353 NULL,
354};
355ATTRIBUTE_GROUPS(def);
356
357static struct kobj_type efivar_ktype = {
358 .release = efivar_release,
359 .sysfs_ops = &efivar_attr_ops,
360 .default_groups = def_groups,
361};
362
363static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
364 struct bin_attribute *bin_attr,
365 char *buf, loff_t pos, size_t count)
366{
367 struct compat_efi_variable *compat = (struct compat_efi_variable *)buf;
368 struct efi_variable *new_var = (struct efi_variable *)buf;
369 struct efivar_entry *new_entry;
370 bool need_compat = in_compat_syscall();
371 efi_char16_t *name;
372 unsigned long size;
373 u32 attributes;
374 u8 *data;
375 int err;
376
377 if (!capable(CAP_SYS_ADMIN))
378 return -EACCES;
379
380 if (need_compat) {
381 if (count != sizeof(*compat))
382 return -EINVAL;
383
384 attributes = compat->Attributes;
385 name = compat->VariableName;
386 size = compat->DataSize;
387 data = compat->Data;
388 } else {
389 if (count != sizeof(*new_var))
390 return -EINVAL;
391
392 attributes = new_var->Attributes;
393 name = new_var->VariableName;
394 size = new_var->DataSize;
395 data = new_var->Data;
396 }
397
398 if ((attributes & ~EFI_VARIABLE_MASK) != 0 ||
399 efivar_validate(new_var->VendorGuid, name, data,
400 size) == false) {
401 printk(KERN_ERR "efivars: Malformed variable content\n");
402 return -EINVAL;
403 }
404
405 new_entry = kzalloc(sizeof(*new_entry), GFP_KERNEL);
406 if (!new_entry)
407 return -ENOMEM;
408
409 if (need_compat)
410 copy_out_compat(&new_entry->var, compat);
411 else
412 memcpy(&new_entry->var, new_var, sizeof(*new_var));
413
414 err = efivar_entry_set(new_entry, attributes, size,
415 data, &efivar_sysfs_list);
416 if (err) {
417 if (err == -EEXIST)
418 err = -EINVAL;
419 goto out;
420 }
421
422 if (efivar_create_sysfs_entry(new_entry)) {
423 printk(KERN_WARNING "efivars: failed to create sysfs entry.\n");
424 kfree(new_entry);
425 }
426 return count;
427
428out:
429 kfree(new_entry);
430 return err;
431}
432
433static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
434 struct bin_attribute *bin_attr,
435 char *buf, loff_t pos, size_t count)
436{
437 struct efi_variable *del_var = (struct efi_variable *)buf;
438 struct compat_efi_variable *compat;
439 struct efivar_entry *entry;
440 efi_char16_t *name;
441 efi_guid_t vendor;
442 int err = 0;
443
444 if (!capable(CAP_SYS_ADMIN))
445 return -EACCES;
446
447 if (in_compat_syscall()) {
448 if (count != sizeof(*compat))
449 return -EINVAL;
450
451 compat = (struct compat_efi_variable *)buf;
452 name = compat->VariableName;
453 vendor = compat->VendorGuid;
454 } else {
455 if (count != sizeof(*del_var))
456 return -EINVAL;
457
458 name = del_var->VariableName;
459 vendor = del_var->VendorGuid;
460 }
461
462 if (efivar_entry_iter_begin())
463 return -EINTR;
464 entry = efivar_entry_find(name, vendor, &efivar_sysfs_list, true);
465 if (!entry)
466 err = -EINVAL;
467 else if (__efivar_entry_delete(entry))
468 err = -EIO;
469
470 efivar_entry_iter_end();
471
472 if (err)
473 return err;
474
475 efivar_unregister(entry);
476
477 /* It's dead Jim.... */
478 return count;
479}
480
481/**
482 * efivar_create_sysfs_entry - create a new entry in sysfs
483 * @new_var: efivar entry to create
484 *
485 * Returns 0 on success, negative error code on failure
486 */
487static int
488efivar_create_sysfs_entry(struct efivar_entry *new_var)
489{
490 int short_name_size;
491 char *short_name;
492 unsigned long utf8_name_size;
493 efi_char16_t *variable_name = new_var->var.VariableName;
494 int ret;
495
496 /*
497 * Length of the variable bytes in UTF8, plus the '-' separator,
498 * plus the GUID, plus trailing NUL
499 */
500 utf8_name_size = ucs2_utf8size(variable_name);
501 short_name_size = utf8_name_size + 1 + EFI_VARIABLE_GUID_LEN + 1;
502
503 short_name = kmalloc(short_name_size, GFP_KERNEL);
504 if (!short_name)
505 return -ENOMEM;
506
507 ucs2_as_utf8(short_name, variable_name, short_name_size);
508
509 /* This is ugly, but necessary to separate one vendor's
510 private variables from another's. */
511 short_name[utf8_name_size] = '-';
512 efi_guid_to_str(&new_var->var.VendorGuid,
513 short_name + utf8_name_size + 1);
514
515 new_var->kobj.kset = efivars_kset;
516
517 ret = kobject_init_and_add(&new_var->kobj, &efivar_ktype,
518 NULL, "%s", short_name);
519 kfree(short_name);
520 if (ret) {
521 kobject_put(&new_var->kobj);
522 return ret;
523 }
524
525 kobject_uevent(&new_var->kobj, KOBJ_ADD);
526 __efivar_entry_add(new_var, &efivar_sysfs_list);
527
528 return 0;
529}
530
531static int
532create_efivars_bin_attributes(void)
533{
534 struct bin_attribute *attr;
535 int error;
536
537 /* new_var */
538 attr = kzalloc(sizeof(*attr), GFP_KERNEL);
539 if (!attr)
540 return -ENOMEM;
541
542 attr->attr.name = "new_var";
543 attr->attr.mode = 0200;
544 attr->write = efivar_create;
545 efivars_new_var = attr;
546
547 /* del_var */
548 attr = kzalloc(sizeof(*attr), GFP_KERNEL);
549 if (!attr) {
550 error = -ENOMEM;
551 goto out_free;
552 }
553 attr->attr.name = "del_var";
554 attr->attr.mode = 0200;
555 attr->write = efivar_delete;
556 efivars_del_var = attr;
557
558 sysfs_bin_attr_init(efivars_new_var);
559 sysfs_bin_attr_init(efivars_del_var);
560
561 /* Register */
562 error = sysfs_create_bin_file(&efivars_kset->kobj, efivars_new_var);
563 if (error) {
564 printk(KERN_ERR "efivars: unable to create new_var sysfs file"
565 " due to error %d\n", error);
566 goto out_free;
567 }
568
569 error = sysfs_create_bin_file(&efivars_kset->kobj, efivars_del_var);
570 if (error) {
571 printk(KERN_ERR "efivars: unable to create del_var sysfs file"
572 " due to error %d\n", error);
573 sysfs_remove_bin_file(&efivars_kset->kobj, efivars_new_var);
574 goto out_free;
575 }
576
577 return 0;
578out_free:
579 kfree(efivars_del_var);
580 efivars_del_var = NULL;
581 kfree(efivars_new_var);
582 efivars_new_var = NULL;
583 return error;
584}
585
586static int efivars_sysfs_callback(efi_char16_t *name, efi_guid_t vendor,
587 unsigned long name_size, void *data)
588{
589 struct efivar_entry *entry;
590
591 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
592 if (!entry)
593 return -ENOMEM;
594
595 memcpy(entry->var.VariableName, name, name_size);
596 memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t));
597
598 efivar_create_sysfs_entry(entry);
599
600 return 0;
601}
602
603static int efivar_sysfs_destroy(struct efivar_entry *entry, void *data)
604{
605 efivar_entry_remove(entry);
606 efivar_unregister(entry);
607 return 0;
608}
609
610static void efivars_sysfs_exit(void)
611{
612 /* Remove all entries and destroy */
613 int err;
614
615 err = efivar_entry_iter(efivar_sysfs_destroy, &efivar_sysfs_list, NULL);
616 if (err) {
617 pr_err("efivars: Failed to destroy sysfs entries\n");
618 return;
619 }
620
621 if (efivars_new_var)
622 sysfs_remove_bin_file(&efivars_kset->kobj, efivars_new_var);
623 if (efivars_del_var)
624 sysfs_remove_bin_file(&efivars_kset->kobj, efivars_del_var);
625 kfree(efivars_new_var);
626 kfree(efivars_del_var);
627 kset_unregister(efivars_kset);
628}
629
630static int efivars_sysfs_init(void)
631{
632 struct kobject *parent_kobj = efivars_kobject();
633 int error = 0;
634
635 /* No efivars has been registered yet */
636 if (!parent_kobj || !efivar_supports_writes())
637 return 0;
638
639 printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,
640 EFIVARS_DATE);
641
642 efivars_kset = kset_create_and_add("vars", NULL, parent_kobj);
643 if (!efivars_kset) {
644 printk(KERN_ERR "efivars: Subsystem registration failed.\n");
645 return -ENOMEM;
646 }
647
648 efivar_init(efivars_sysfs_callback, NULL, true, &efivar_sysfs_list);
649
650 error = create_efivars_bin_attributes();
651 if (error) {
652 efivars_sysfs_exit();
653 return error;
654 }
655
656 return 0;
657}
658
659module_init(efivars_sysfs_init);
660module_exit(efivars_sysfs_exit);
drivers/firmware/efi/vars.c+0−1023
@@ -6,298 +6,20 @@ · 5 unmodified lines
6 * Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com>6 * Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com>
7 */7 */
8 8
9#include <linux/capability.h>
10#include <linux/types.h>9#include <linux/types.h>
11#include <linux/errno.h>10#include <linux/errno.h>
12#include <linux/init.h>11#include <linux/init.h>
13#include <linux/mm.h>
14#include <linux/module.h>12#include <linux/module.h>
15#include <linux/string.h>13#include <linux/string.h>
16#include <linux/smp.h>14#include <linux/smp.h>
17#include <linux/efi.h>15#include <linux/efi.h>
18#include <linux/sysfs.h>
19#include <linux/device.h>
20#include <linux/slab.h>
21#include <linux/ctype.h>
22#include <linux/ucs2_string.h>16#include <linux/ucs2_string.h>
23 17
24/* Private pointer to registered efivars */18/* Private pointer to registered efivars */
25static struct efivars *__efivars;19static struct efivars *__efivars;
26 20
27/*
28 * efivars_lock protects three things:
29 * 1) efivarfs_list and efivars_sysfs_list
30 * 2) ->ops calls
31 * 3) (un)registration of __efivars
32 */
33static DEFINE_SEMAPHORE(efivars_lock);21static DEFINE_SEMAPHORE(efivars_lock);
34 22
35static bool
36validate_device_path(efi_char16_t *var_name, int match, u8 *buffer,
37 unsigned long len)
38{
39 struct efi_generic_dev_path *node;
40 int offset = 0;
41
42 node = (struct efi_generic_dev_path *)buffer;
43
44 if (len < sizeof(*node))
45 return false;
46
47 while (offset <= len - sizeof(*node) &&
48 node->length >= sizeof(*node) &&
49 node->length <= len - offset) {
50 offset += node->length;
51
52 if ((node->type == EFI_DEV_END_PATH ||
53 node->type == EFI_DEV_END_PATH2) &&
54 node->sub_type == EFI_DEV_END_ENTIRE)
55 return true;
56
57 node = (struct efi_generic_dev_path *)(buffer + offset);
58 }
59
60 /*
61 * If we're here then either node->length pointed past the end
62 * of the buffer or we reached the end of the buffer without
63 * finding a device path end node.
64 */
65 return false;
66}
67
68static bool
69validate_boot_order(efi_char16_t *var_name, int match, u8 *buffer,
70 unsigned long len)
71{
72 /* An array of 16-bit integers */
73 if ((len % 2) != 0)
74 return false;
75
76 return true;
77}
78
79static bool
80validate_load_option(efi_char16_t *var_name, int match, u8 *buffer,
81 unsigned long len)
82{
83 u16 filepathlength;
84 int i, desclength = 0, namelen;
85
86 namelen = ucs2_strnlen(var_name, EFI_VAR_NAME_LEN);
87
88 /* Either "Boot" or "Driver" followed by four digits of hex */
89 for (i = match; i < match+4; i++) {
90 if (var_name[i] > 127 ||
91 hex_to_bin(var_name[i] & 0xff) < 0)
92 return true;
93 }
94
95 /* Reject it if there's 4 digits of hex and then further content */
96 if (namelen > match + 4)
97 return false;
98
99 /* A valid entry must be at least 8 bytes */
100 if (len < 8)
101 return false;
102
103 filepathlength = buffer[4] | buffer[5] << 8;
104
105 /*
106 * There's no stored length for the description, so it has to be
107 * found by hand
108 */
109 desclength = ucs2_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2;
110
111 /* Each boot entry must have a descriptor */
112 if (!desclength)
113 return false;
114
115 /*
116 * If the sum of the length of the description, the claimed filepath
117 * length and the original header are greater than the length of the
118 * variable, it's malformed
119 */
120 if ((desclength + filepathlength + 6) > len)
121 return false;
122
123 /*
124 * And, finally, check the filepath
125 */
126 return validate_device_path(var_name, match, buffer + desclength + 6,
127 filepathlength);
128}
129
130static bool
131validate_uint16(efi_char16_t *var_name, int match, u8 *buffer,
132 unsigned long len)
133{
134 /* A single 16-bit integer */
135 if (len != 2)
136 return false;
137
138 return true;
139}
140
141static bool
142validate_ascii_string(efi_char16_t *var_name, int match, u8 *buffer,
143 unsigned long len)
144{
145 int i;
146
147 for (i = 0; i < len; i++) {
148 if (buffer[i] > 127)
149 return false;
150
151 if (buffer[i] == 0)
152 return true;
153 }
154
155 return false;
156}
157
158struct variable_validate {
159 efi_guid_t vendor;
160 char *name;
161 bool (*validate)(efi_char16_t *var_name, int match, u8 *data,
162 unsigned long len);
163};
164
165/*
166 * This is the list of variables we need to validate, as well as the
167 * whitelist for what we think is safe not to default to immutable.
168 *
169 * If it has a validate() method that's not NULL, it'll go into the
170 * validation routine. If not, it is assumed valid, but still used for
171 * whitelisting.
172 *
173 * Note that it's sorted by {vendor,name}, but globbed names must come after
174 * any other name with the same prefix.
175 */
176static const struct variable_validate variable_validate[] = {
177 { EFI_GLOBAL_VARIABLE_GUID, "BootNext", validate_uint16 },
178 { EFI_GLOBAL_VARIABLE_GUID, "BootOrder", validate_boot_order },
179 { EFI_GLOBAL_VARIABLE_GUID, "Boot*", validate_load_option },
180 { EFI_GLOBAL_VARIABLE_GUID, "DriverOrder", validate_boot_order },
181 { EFI_GLOBAL_VARIABLE_GUID, "Driver*", validate_load_option },
182 { EFI_GLOBAL_VARIABLE_GUID, "ConIn", validate_device_path },
183 { EFI_GLOBAL_VARIABLE_GUID, "ConInDev", validate_device_path },
184 { EFI_GLOBAL_VARIABLE_GUID, "ConOut", validate_device_path },
185 { EFI_GLOBAL_VARIABLE_GUID, "ConOutDev", validate_device_path },
186 { EFI_GLOBAL_VARIABLE_GUID, "ErrOut", validate_device_path },
187 { EFI_GLOBAL_VARIABLE_GUID, "ErrOutDev", validate_device_path },
188 { EFI_GLOBAL_VARIABLE_GUID, "Lang", validate_ascii_string },
189 { EFI_GLOBAL_VARIABLE_GUID, "OsIndications", NULL },
190 { EFI_GLOBAL_VARIABLE_GUID, "PlatformLang", validate_ascii_string },
191 { EFI_GLOBAL_VARIABLE_GUID, "Timeout", validate_uint16 },
192 { LINUX_EFI_CRASH_GUID, "*", NULL },
193 { NULL_GUID, "", NULL },
194};
195
196/*
197 * Check if @var_name matches the pattern given in @match_name.
198 *
199 * @var_name: an array of @len non-NUL characters.
200 * @match_name: a NUL-terminated pattern string, optionally ending in "*". A
201 * final "*" character matches any trailing characters @var_name,
202 * including the case when there are none left in @var_name.
203 * @match: on output, the number of non-wildcard characters in @match_name
204 * that @var_name matches, regardless of the return value.
205 * @return: whether @var_name fully matches @match_name.
206 */
207static bool
208variable_matches(const char *var_name, size_t len, const char *match_name,
209 int *match)
210{
211 for (*match = 0; ; (*match)++) {
212 char c = match_name[*match];
213
214 switch (c) {
215 case '*':
216 /* Wildcard in @match_name means we've matched. */
217 return true;
218
219 case '\0':
220 /* @match_name has ended. Has @var_name too? */
221 return (*match == len);
222
223 default:
224 /*
225 * We've reached a non-wildcard char in @match_name.
226 * Continue only if there's an identical character in
227 * @var_name.
228 */
229 if (*match < len && c == var_name[*match])
230 continue;
231 return false;
232 }
233 }
234}
235
236bool
237efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data,
238 unsigned long data_size)
239{
240 int i;
241 unsigned long utf8_size;
242 u8 *utf8_name;
243
244 utf8_size = ucs2_utf8size(var_name);
245 utf8_name = kmalloc(utf8_size + 1, GFP_KERNEL);
246 if (!utf8_name)
247 return false;
248
249 ucs2_as_utf8(utf8_name, var_name, utf8_size);
250 utf8_name[utf8_size] = '\0';
251
252 for (i = 0; variable_validate[i].name[0] != '\0'; i++) {
253 const char *name = variable_validate[i].name;
254 int match = 0;
255
256 if (efi_guidcmp(vendor, variable_validate[i].vendor))
257 continue;
258
259 if (variable_matches(utf8_name, utf8_size+1, name, &match)) {
260 if (variable_validate[i].validate == NULL)
261 break;
262 kfree(utf8_name);
263 return variable_validate[i].validate(var_name, match,
264 data, data_size);
265 }
266 }
267 kfree(utf8_name);
268 return true;
269}
270EXPORT_SYMBOL_GPL(efivar_validate);
271
272bool
273efivar_variable_is_removable(efi_guid_t vendor, const char *var_name,
274 size_t len)
275{
276 int i;
277 bool found = false;
278 int match = 0;
279
280 /*
281 * Check if our variable is in the validated variables list
282 */
283 for (i = 0; variable_validate[i].name[0] != '\0'; i++) {
284 if (efi_guidcmp(variable_validate[i].vendor, vendor))
285 continue;
286
287 if (variable_matches(var_name, len,
288 variable_validate[i].name, &match)) {
289 found = true;
290 break;
291 }
292 }
293
294 /*
295 * If it's in our list, it is removable.
296 */
297 return found;
298}
299EXPORT_SYMBOL_GPL(efivar_variable_is_removable);
300
301efi_status_t check_var_size(u32 attributes, unsigned long size)23efi_status_t check_var_size(u32 attributes, unsigned long size)
302{24{
303 const struct efivar_operations *fops;25 const struct efivar_operations *fops;
@@ -324,751 +46,6 @@ efi_status_t check_var_size_nonblocking(u32 attributes, unsigned long size) · 20 unmodified lines
324}46}
325EXPORT_SYMBOL_NS_GPL(check_var_size_nonblocking, EFIVAR);47EXPORT_SYMBOL_NS_GPL(check_var_size_nonblocking, EFIVAR);
326 48
327static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor,
328 struct list_head *head)
329{
330 struct efivar_entry *entry, *n;
331 unsigned long strsize1, strsize2;
332 bool found = false;
333
334 strsize1 = ucs2_strsize(variable_name, 1024);
335 list_for_each_entry_safe(entry, n, head, list) {
336 strsize2 = ucs2_strsize(entry->var.VariableName, 1024);
337 if (strsize1 == strsize2 &&
338 !memcmp(variable_name, &(entry->var.VariableName),
339 strsize2) &&
340 !efi_guidcmp(entry->var.VendorGuid,
341 *vendor)) {
342 found = true;
343 break;
344 }
345 }
346 return found;
347}
348
349/*
350 * Returns the size of variable_name, in bytes, including the
351 * terminating NULL character, or variable_name_size if no NULL
352 * character is found among the first variable_name_size bytes.
353 */
354static unsigned long var_name_strnsize(efi_char16_t *variable_name,
355 unsigned long variable_name_size)
356{
357 unsigned long len;
358 efi_char16_t c;
359
360 /*
361 * The variable name is, by definition, a NULL-terminated
362 * string, so make absolutely sure that variable_name_size is
363 * the value we expect it to be. If not, return the real size.
364 */
365 for (len = 2; len <= variable_name_size; len += sizeof(c)) {
366 c = variable_name[(len / sizeof(c)) - 1];
367 if (!c)
368 break;
369 }
370
371 return min(len, variable_name_size);
372}
373
374/*
375 * Print a warning when duplicate EFI variables are encountered and
376 * disable the sysfs workqueue since the firmware is buggy.
377 */
378static void dup_variable_bug(efi_char16_t *str16, efi_guid_t *vendor_guid,
379 unsigned long len16)
380{
381 size_t i, len8 = len16 / sizeof(efi_char16_t);
382 char *str8;
383
384 str8 = kzalloc(len8, GFP_KERNEL);
385 if (!str8)
386 return;
387
388 for (i = 0; i < len8; i++)
389 str8[i] = str16[i];
390
391 printk(KERN_WARNING "efivars: duplicate variable: %s-%pUl\n",
392 str8, vendor_guid);
393 kfree(str8);
394}
395
396/**
397 * efivar_init - build the initial list of EFI variables
398 * @func: callback function to invoke for every variable
399 * @data: function-specific data to pass to @func
400 * @duplicates: error if we encounter duplicates on @head?
401 * @head: initialised head of variable list
402 *
403 * Get every EFI variable from the firmware and invoke @func. @func
404 * should call efivar_entry_add() to build the list of variables.
405 *
406 * Returns 0 on success, or a kernel error code on failure.
407 */
408int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
409 void *data, bool duplicates, struct list_head *head)
410{
411 const struct efivar_operations *ops;
412 unsigned long variable_name_size = 1024;
413 efi_char16_t *variable_name;
414 efi_status_t status;
415 efi_guid_t vendor_guid;
416 int err = 0;
417
418 if (!__efivars)
419 return -EFAULT;
420
421 ops = __efivars->ops;
422
423 variable_name = kzalloc(variable_name_size, GFP_KERNEL);
424 if (!variable_name) {
425 printk(KERN_ERR "efivars: Memory allocation failed.\n");
426 return -ENOMEM;
427 }
428
429 if (down_interruptible(&efivars_lock)) {
430 err = -EINTR;
431 goto free;
432 }
433
434 /*
435 * Per EFI spec, the maximum storage allocated for both
436 * the variable name and variable data is 1024 bytes.
437 */
438
439 do {
440 variable_name_size = 1024;
441
442 status = ops->get_next_variable(&variable_name_size,
443 variable_name,
444 &vendor_guid);
445 switch (status) {
446 case EFI_SUCCESS:
447 variable_name_size = var_name_strnsize(variable_name,
448 variable_name_size);
449
450 /*
451 * Some firmware implementations return the
452 * same variable name on multiple calls to
453 * get_next_variable(). Terminate the loop
454 * immediately as there is no guarantee that
455 * we'll ever see a different variable name,
456 * and may end up looping here forever.
457 */
458 if (duplicates &&
459 variable_is_present(variable_name, &vendor_guid,
460 head)) {
461 dup_variable_bug(variable_name, &vendor_guid,
462 variable_name_size);
463 status = EFI_NOT_FOUND;
464 } else {
465 err = func(variable_name, vendor_guid,
466 variable_name_size, data);
467 if (err)
468 status = EFI_NOT_FOUND;
469 }
470 break;
471 case EFI_UNSUPPORTED:
472 err = -EOPNOTSUPP;
473 status = EFI_NOT_FOUND;
474 break;
475 case EFI_NOT_FOUND:
476 break;
477 default:
478 printk(KERN_WARNING "efivars: get_next_variable: status=%lx\n",
479 status);
480 status = EFI_NOT_FOUND;
481 break;
482 }
483
484 } while (status != EFI_NOT_FOUND);
485
486 up(&efivars_lock);
487free:
488 kfree(variable_name);
489
490 return err;
491}
492EXPORT_SYMBOL_GPL(efivar_init);
493
494/**
495 * efivar_entry_add - add entry to variable list
496 * @entry: entry to add to list
497 * @head: list head
498 *
499 * Returns 0 on success, or a kernel error code on failure.
500 */
501int efivar_entry_add(struct efivar_entry *entry, struct list_head *head)
502{
503 if (down_interruptible(&efivars_lock))
504 return -EINTR;
505 list_add(&entry->list, head);
506 up(&efivars_lock);
507
508 return 0;
509}
510EXPORT_SYMBOL_GPL(efivar_entry_add);
511
512/**
513 * __efivar_entry_add - add entry to variable list
514 * @entry: entry to add to list
515 * @head: list head
516 */
517void __efivar_entry_add(struct efivar_entry *entry, struct list_head *head)
518{
519 list_add(&entry->list, head);
520}
521EXPORT_SYMBOL_GPL(__efivar_entry_add);
522
523/**
524 * efivar_entry_remove - remove entry from variable list
525 * @entry: entry to remove from list
526 */
527void efivar_entry_remove(struct efivar_entry *entry)
528{
529 list_del(&entry->list);
530}
531EXPORT_SYMBOL_GPL(efivar_entry_remove);
532
533/*
534 * efivar_entry_list_del_unlock - remove entry from variable list
535 * @entry: entry to remove
536 *
537 * Remove @entry from the variable list and release the list lock.
538 *
539 * NOTE: slightly weird locking semantics here - we expect to be
540 * called with the efivars lock already held, and we release it before
541 * returning. This is because this function is usually called after
542 * set_variable() while the lock is still held.
543 */
544static void efivar_entry_list_del_unlock(struct efivar_entry *entry)
545{
546 list_del(&entry->list);
547 up(&efivars_lock);
548}
549
550/**
551 * __efivar_entry_delete - delete an EFI variable
552 * @entry: entry containing EFI variable to delete
553 *
554 * Delete the variable from the firmware but leave @entry on the
555 * variable list.
556 *
557 * This function differs from efivar_entry_delete() because it does
558 * not remove @entry from the variable list. Also, it is safe to be
559 * called from within a efivar_entry_iter_begin() and
560 * efivar_entry_iter_end() region, unlike efivar_entry_delete().
561 *
562 * Returns 0 on success, or a converted EFI status code if
563 * set_variable() fails.
564 */
565int __efivar_entry_delete(struct efivar_entry *entry)
566{
567 efi_status_t status;
568
569 if (!__efivars)
570 return -EINVAL;
571
572 status = __efivars->ops->set_variable(entry->var.VariableName,
573 &entry->var.VendorGuid,
574 0, 0, NULL);
575
576 return efi_status_to_err(status);
577}
578EXPORT_SYMBOL_GPL(__efivar_entry_delete);
579
580/**
581 * efivar_entry_delete - delete variable and remove entry from list
582 * @entry: entry containing variable to delete
583 *
584 * Delete the variable from the firmware and remove @entry from the
585 * variable list. It is the caller's responsibility to free @entry
586 * once we return.
587 *
588 * Returns 0 on success, -EINTR if we can't grab the semaphore,
589 * converted EFI status code if set_variable() fails.
590 */
591int efivar_entry_delete(struct efivar_entry *entry)
592{
593 const struct efivar_operations *ops;
594 efi_status_t status;
595
596 if (down_interruptible(&efivars_lock))
597 return -EINTR;
598
599 if (!__efivars) {
600 up(&efivars_lock);
601 return -EINVAL;
602 }
603 ops = __efivars->ops;
604 status = ops->set_variable(entry->var.VariableName,
605 &entry->var.VendorGuid,
606 0, 0, NULL);
607 if (!(status == EFI_SUCCESS || status == EFI_NOT_FOUND)) {
608 up(&efivars_lock);
609 return efi_status_to_err(status);
610 }
611
612 efivar_entry_list_del_unlock(entry);
613 return 0;
614}
615EXPORT_SYMBOL_GPL(efivar_entry_delete);
616
617/**
618 * efivar_entry_set - call set_variable()
619 * @entry: entry containing the EFI variable to write
620 * @attributes: variable attributes
621 * @size: size of @data buffer
622 * @data: buffer containing variable data
623 * @head: head of variable list
624 *
625 * Calls set_variable() for an EFI variable. If creating a new EFI
626 * variable, this function is usually followed by efivar_entry_add().
627 *
628 * Before writing the variable, the remaining EFI variable storage
629 * space is checked to ensure there is enough room available.
630 *
631 * If @head is not NULL a lookup is performed to determine whether
632 * the entry is already on the list.
633 *
634 * Returns 0 on success, -EINTR if we can't grab the semaphore,
635 * -EEXIST if a lookup is performed and the entry already exists on
636 * the list, or a converted EFI status code if set_variable() fails.
637 */
638int efivar_entry_set(struct efivar_entry *entry, u32 attributes,
639 unsigned long size, void *data, struct list_head *head)
640{
641 const struct efivar_operations *ops;
642 efi_status_t status;
643 efi_char16_t *name = entry->var.VariableName;
644 efi_guid_t vendor = entry->var.VendorGuid;
645
646 if (down_interruptible(&efivars_lock))
647 return -EINTR;
648
649 if (!__efivars) {
650 up(&efivars_lock);
651 return -EINVAL;
652 }
653 ops = __efivars->ops;
654 if (head && efivar_entry_find(name, vendor, head, false)) {
655 up(&efivars_lock);
656 return -EEXIST;
657 }
658
659 status = check_var_size(attributes, size + ucs2_strsize(name, 1024));
660 if (status == EFI_SUCCESS || status == EFI_UNSUPPORTED)
661 status = ops->set_variable(name, &vendor,
662 attributes, size, data);
663
664 up(&efivars_lock);
665
666 return efi_status_to_err(status);
667
668}
669EXPORT_SYMBOL_GPL(efivar_entry_set);
670
671/*
672 * efivar_entry_set_nonblocking - call set_variable_nonblocking()
673 *
674 * This function is guaranteed to not block and is suitable for calling
675 * from crash/panic handlers.
676 *
677 * Crucially, this function will not block if it cannot acquire
678 * efivars_lock. Instead, it returns -EBUSY.
679 */
680static int
681efivar_entry_set_nonblocking(efi_char16_t *name, efi_guid_t vendor,
682 u32 attributes, unsigned long size, void *data)
683{
684 const struct efivar_operations *ops;
685 efi_status_t status;
686
687 if (down_trylock(&efivars_lock))
688 return -EBUSY;
689
690 if (!__efivars) {
691 up(&efivars_lock);
692 return -EINVAL;
693 }
694
695 status = check_var_size_nonblocking(attributes,
696 size + ucs2_strsize(name, 1024));
697 if (status != EFI_SUCCESS) {
698 up(&efivars_lock);
699 return -ENOSPC;
700 }
701
702 ops = __efivars->ops;
703 status = ops->set_variable_nonblocking(name, &vendor, attributes,
704 size, data);
705
706 up(&efivars_lock);
707 return efi_status_to_err(status);
708}
709
710/**
711 * efivar_entry_set_safe - call set_variable() if enough space in firmware
712 * @name: buffer containing the variable name
713 * @vendor: variable vendor guid
714 * @attributes: variable attributes
715 * @block: can we block in this context?
716 * @size: size of @data buffer
717 * @data: buffer containing variable data
718 *
719 * Ensures there is enough free storage in the firmware for this variable, and
720 * if so, calls set_variable(). If creating a new EFI variable, this function
721 * is usually followed by efivar_entry_add().
722 *
723 * Returns 0 on success, -ENOSPC if the firmware does not have enough
724 * space for set_variable() to succeed, or a converted EFI status code
725 * if set_variable() fails.
726 */
727int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes,
728 bool block, unsigned long size, void *data)
729{
730 const struct efivar_operations *ops;
731 efi_status_t status;
732 unsigned long varsize;
733
734 if (!__efivars)
735 return -EINVAL;
736
737 ops = __efivars->ops;
738 if (!ops->query_variable_store)
739 return -ENOSYS;
740
741 /*
742 * If the EFI variable backend provides a non-blocking
743 * ->set_variable() operation and we're in a context where we
744 * cannot block, then we need to use it to avoid live-locks,
745 * since the implication is that the regular ->set_variable()
746 * will block.
747 *
748 * If no ->set_variable_nonblocking() is provided then
749 * ->set_variable() is assumed to be non-blocking.
750 */
751 if (!block && ops->set_variable_nonblocking)
752 return efivar_entry_set_nonblocking(name, vendor, attributes,
753 size, data);
754
755 varsize = size + ucs2_strsize(name, 1024);
756 if (!block) {
757 if (down_trylock(&efivars_lock))
758 return -EBUSY;
759 status = check_var_size_nonblocking(attributes, varsize);
760 } else {
761 if (down_interruptible(&efivars_lock))
762 return -EINTR;
763 status = check_var_size(attributes, varsize);
764 }
765
766 if (status != EFI_SUCCESS) {
767 up(&efivars_lock);
768 return -ENOSPC;
769 }
770
771 status = ops->set_variable(name, &vendor, attributes, size, data);
772
773 up(&efivars_lock);
774
775 return efi_status_to_err(status);
776}
777EXPORT_SYMBOL_GPL(efivar_entry_set_safe);
778
779/**
780 * efivar_entry_find - search for an entry
781 * @name: the EFI variable name
782 * @guid: the EFI variable vendor's guid
783 * @head: head of the variable list
784 * @remove: should we remove the entry from the list?
785 *
786 * Search for an entry on the variable list that has the EFI variable
787 * name @name and vendor guid @guid. If an entry is found on the list
788 * and @remove is true, the entry is removed from the list.
789 *
790 * The caller MUST call efivar_entry_iter_begin() and
791 * efivar_entry_iter_end() before and after the invocation of this
792 * function, respectively.
793 *
794 * Returns the entry if found on the list, %NULL otherwise.
795 */
796struct efivar_entry *efivar_entry_find(efi_char16_t *name, efi_guid_t guid,
797 struct list_head *head, bool remove)
798{
799 struct efivar_entry *entry, *n;
800 int strsize1, strsize2;
801 bool found = false;
802
803 list_for_each_entry_safe(entry, n, head, list) {
804 strsize1 = ucs2_strsize(name, 1024);
805 strsize2 = ucs2_strsize(entry->var.VariableName, 1024);
806 if (strsize1 == strsize2 &&
807 !memcmp(name, &(entry->var.VariableName), strsize1) &&
808 !efi_guidcmp(guid, entry->var.VendorGuid)) {
809 found = true;
810 break;
811 }
812 }
813
814 if (!found)
815 return NULL;
816
817 if (remove)
818 list_del(&entry->list);
819
820 return entry;
821}
822EXPORT_SYMBOL_GPL(efivar_entry_find);
823
824/**
825 * efivar_entry_size - obtain the size of a variable
826 * @entry: entry for this variable
827 * @size: location to store the variable's size
828 */
829int efivar_entry_size(struct efivar_entry *entry, unsigned long *size)
830{
831 const struct efivar_operations *ops;
832 efi_status_t status;
833
834 *size = 0;
835
836 if (down_interruptible(&efivars_lock))
837 return -EINTR;
838 if (!__efivars) {
839 up(&efivars_lock);
840 return -EINVAL;
841 }
842 ops = __efivars->ops;
843 status = ops->get_variable(entry->var.VariableName,
844 &entry->var.VendorGuid, NULL, size, NULL);
845 up(&efivars_lock);
846
847 if (status != EFI_BUFFER_TOO_SMALL)
848 return efi_status_to_err(status);
849
850 return 0;
851}
852EXPORT_SYMBOL_GPL(efivar_entry_size);
853
854/**
855 * __efivar_entry_get - call get_variable()
856 * @entry: read data for this variable
857 * @attributes: variable attributes
858 * @size: size of @data buffer
859 * @data: buffer to store variable data
860 *
861 * The caller MUST call efivar_entry_iter_begin() and
862 * efivar_entry_iter_end() before and after the invocation of this
863 * function, respectively.
864 */
865int __efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
866 unsigned long *size, void *data)
867{
868 efi_status_t status;
869
870 if (!__efivars)
871 return -EINVAL;
872
873 status = __efivars->ops->get_variable(entry->var.VariableName,
874 &entry->var.VendorGuid,
875 attributes, size, data);
876
877 return efi_status_to_err(status);
878}
879EXPORT_SYMBOL_GPL(__efivar_entry_get);
880
881/**
882 * efivar_entry_get - call get_variable()
883 * @entry: read data for this variable
884 * @attributes: variable attributes
885 * @size: size of @data buffer
886 * @data: buffer to store variable data
887 */
888int efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
889 unsigned long *size, void *data)
890{
891 efi_status_t status;
892
893 if (down_interruptible(&efivars_lock))
894 return -EINTR;
895
896 if (!__efivars) {
897 up(&efivars_lock);
898 return -EINVAL;
899 }
900
901 status = __efivars->ops->get_variable(entry->var.VariableName,
902 &entry->var.VendorGuid,
903 attributes, size, data);
904 up(&efivars_lock);
905
906 return efi_status_to_err(status);
907}
908EXPORT_SYMBOL_GPL(efivar_entry_get);
909
910/**
911 * efivar_entry_set_get_size - call set_variable() and get new size (atomic)
912 * @entry: entry containing variable to set and get
913 * @attributes: attributes of variable to be written
914 * @size: size of data buffer
915 * @data: buffer containing data to write
916 * @set: did the set_variable() call succeed?
917 *
918 * This is a pretty special (complex) function. See efivarfs_file_write().
919 *
920 * Atomically call set_variable() for @entry and if the call is
921 * successful, return the new size of the variable from get_variable()
922 * in @size. The success of set_variable() is indicated by @set.
923 *
924 * Returns 0 on success, -EINVAL if the variable data is invalid,
925 * -ENOSPC if the firmware does not have enough available space, or a
926 * converted EFI status code if either of set_variable() or
927 * get_variable() fail.
928 *
929 * If the EFI variable does not exist when calling set_variable()
930 * (EFI_NOT_FOUND), @entry is removed from the variable list.
931 */
932int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes,
933 unsigned long *size, void *data, bool *set)
934{
935 const struct efivar_operations *ops;
936 efi_char16_t *name = entry->var.VariableName;
937 efi_guid_t *vendor = &entry->var.VendorGuid;
938 efi_status_t status;
939 int err;
940
941 *set = false;
942
943 if (efivar_validate(*vendor, name, data, *size) == false)
944 return -EINVAL;
945
946 /*
947 * The lock here protects the get_variable call, the conditional
948 * set_variable call, and removal of the variable from the efivars
949 * list (in the case of an authenticated delete).
950 */
951 if (down_interruptible(&efivars_lock))
952 return -EINTR;
953
954 if (!__efivars) {
955 err = -EINVAL;
956 goto out;
957 }
958
959 /*
960 * Ensure that the available space hasn't shrunk below the safe level
961 */
962 status = check_var_size(attributes, *size + ucs2_strsize(name, 1024));
963 if (status != EFI_SUCCESS) {
964 if (status != EFI_UNSUPPORTED) {
965 err = efi_status_to_err(status);
966 goto out;
967 }
968
969 if (*size > 65536) {
970 err = -ENOSPC;
971 goto out;
972 }
973 }
974
975 ops = __efivars->ops;
976
977 status = ops->set_variable(name, vendor, attributes, *size, data);
978 if (status != EFI_SUCCESS) {
979 err = efi_status_to_err(status);
980 goto out;
981 }
982
983 *set = true;
984
985 /*
986 * Writing to the variable may have caused a change in size (which
987 * could either be an append or an overwrite), or the variable to be
988 * deleted. Perform a GetVariable() so we can tell what actually
989 * happened.
990 */
991 *size = 0;
992 status = ops->get_variable(entry->var.VariableName,
993 &entry->var.VendorGuid,
994 NULL, size, NULL);
995
996 if (status == EFI_NOT_FOUND)
997 efivar_entry_list_del_unlock(entry);
998 else
999 up(&efivars_lock);
1000
1001 if (status && status != EFI_BUFFER_TOO_SMALL)
1002 return efi_status_to_err(status);
1003
1004 return 0;
1005
1006out:
1007 up(&efivars_lock);
1008 return err;
1009
1010}
1011EXPORT_SYMBOL_GPL(efivar_entry_set_get_size);
1012
1013/**
1014 * efivar_entry_iter_begin - begin iterating the variable list
1015 *
1016 * Lock the variable list to prevent entry insertion and removal until
1017 * efivar_entry_iter_end() is called. This function is usually used in
1018 * conjunction with __efivar_entry_iter() or efivar_entry_iter().
1019 */
1020int efivar_entry_iter_begin(void)
1021{
1022 return down_interruptible(&efivars_lock);
1023}
1024EXPORT_SYMBOL_GPL(efivar_entry_iter_begin);
1025
1026/**
1027 * efivar_entry_iter_end - finish iterating the variable list
1028 *
1029 * Unlock the variable list and allow modifications to the list again.
1030 */
1031void efivar_entry_iter_end(void)
1032{
1033 up(&efivars_lock);
1034}
1035EXPORT_SYMBOL_GPL(efivar_entry_iter_end);
1036
1037/**
1038 * efivar_entry_iter - iterate over variable list
1039 * @func: callback function
1040 * @head: head of variable list
1041 * @data: function-specific data to pass to callback
1042 *
1043 * Iterate over the list of EFI variables and call @func with every
1044 * entry on the list. It is safe for @func to remove entries in the
1045 * list via efivar_entry_delete() while iterating.
1046 *
1047 * Some notes for the callback function:
1048 * - a non-zero return value indicates an error and terminates the loop
1049 * - @func is called from atomic context
1050 */
1051int efivar_entry_iter(int (*func)(struct efivar_entry *, void *),
1052 struct list_head *head, void *data)
1053{
1054 struct efivar_entry *entry, *n;
1055 int err = 0;
1056
1057 err = efivar_entry_iter_begin();
1058 if (err)
1059 return err;
1060
1061 list_for_each_entry_safe(entry, n, head, list) {
1062 err = func(entry, data);
1063 if (err)
1064 break;
1065 }
1066 efivar_entry_iter_end();
1067
1068 return err;
1069}
1070EXPORT_SYMBOL_GPL(efivar_entry_iter);
1071
1072/**49/**
1073 * efivars_kobject - get the kobject for the registered efivars50 * efivars_kobject - get the kobject for the registered efivars
1074 *51 *
fs/efivarfs/Makefile+1−1
@@ -5,4 +5,4 @@ · 4 unmodified lines
5 5
6obj-$(CONFIG_EFIVAR_FS) += efivarfs.o6obj-$(CONFIG_EFIVAR_FS) += efivarfs.o
7 7
8efivarfs-objs := inode.o file.o super.o8efivarfs-objs := inode.o file.o super.o vars.o
fs/efivarfs/internal.h+40−0
@@ -7,6 +7,46 @@ · 6 unmodified lines
7#define EFIVAR_FS_INTERNAL_H7#define EFIVAR_FS_INTERNAL_H
8 8
9#include <linux/list.h>9#include <linux/list.h>
10#include <linux/efi.h>
11
12struct efi_variable {
13 efi_char16_t VariableName[EFI_VAR_NAME_LEN/sizeof(efi_char16_t)];
14 efi_guid_t VendorGuid;
15 unsigned long DataSize;
16 __u8 Data[1024];
17 efi_status_t Status;
18 __u32 Attributes;
19} __attribute__((packed));
20
21struct efivar_entry {
22 struct efi_variable var;
23 struct list_head list;
24 struct kobject kobj;
25};
26
27int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
28 void *data, bool duplicates, struct list_head *head);
29
30int efivar_entry_add(struct efivar_entry *entry, struct list_head *head);
31void __efivar_entry_add(struct efivar_entry *entry, struct list_head *head);
32void efivar_entry_remove(struct efivar_entry *entry);
33int efivar_entry_delete(struct efivar_entry *entry);
34
35int efivar_entry_size(struct efivar_entry *entry, unsigned long *size);
36int __efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
37 unsigned long *size, void *data);
38int efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
39 unsigned long *size, void *data);
40int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes,
41 unsigned long *size, void *data, bool *set);
42
43int efivar_entry_iter(int (*func)(struct efivar_entry *, void *),
44 struct list_head *head, void *data);
45
46bool efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data,
47 unsigned long data_size);
48bool efivar_variable_is_removable(efi_guid_t vendor, const char *name,
49 size_t len);
10 50
11extern const struct file_operations efivarfs_file_operations;51extern const struct file_operations efivarfs_file_operations;
12extern const struct inode_operations efivarfs_dir_inode_operations;52extern const struct inode_operations efivarfs_dir_inode_operations;
fs/efivarfs/vars.c+738−0
@@ -0,0 +1,738 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Originally from efivars.c
4 *
5 * Copyright (C) 2001,2003,2004 Dell <Matt_Domsch@dell.com>
6 * Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com>
7 */
8
9#include <linux/capability.h>
10#include <linux/types.h>
11#include <linux/errno.h>
12#include <linux/init.h>
13#include <linux/mm.h>
14#include <linux/module.h>
15#include <linux/string.h>
16#include <linux/smp.h>
17#include <linux/efi.h>
18#include <linux/device.h>
19#include <linux/slab.h>
20#include <linux/ctype.h>
21#include <linux/ucs2_string.h>
22
23#include "internal.h"
24
25MODULE_IMPORT_NS(EFIVAR);
26
27static bool
28validate_device_path(efi_char16_t *var_name, int match, u8 *buffer,
29 unsigned long len)
30{
31 struct efi_generic_dev_path *node;
32 int offset = 0;
33
34 node = (struct efi_generic_dev_path *)buffer;
35
36 if (len < sizeof(*node))
37 return false;
38
39 while (offset <= len - sizeof(*node) &&
40 node->length >= sizeof(*node) &&
41 node->length <= len - offset) {
42 offset += node->length;
43
44 if ((node->type == EFI_DEV_END_PATH ||
45 node->type == EFI_DEV_END_PATH2) &&
46 node->sub_type == EFI_DEV_END_ENTIRE)
47 return true;
48
49 node = (struct efi_generic_dev_path *)(buffer + offset);
50 }
51
52 /*
53 * If we're here then either node->length pointed past the end
54 * of the buffer or we reached the end of the buffer without
55 * finding a device path end node.
56 */
57 return false;
58}
59
60static bool
61validate_boot_order(efi_char16_t *var_name, int match, u8 *buffer,
62 unsigned long len)
63{
64 /* An array of 16-bit integers */
65 if ((len % 2) != 0)
66 return false;
67
68 return true;
69}
70
71static bool
72validate_load_option(efi_char16_t *var_name, int match, u8 *buffer,
73 unsigned long len)
74{
75 u16 filepathlength;
76 int i, desclength = 0, namelen;
77
78 namelen = ucs2_strnlen(var_name, EFI_VAR_NAME_LEN);
79
80 /* Either "Boot" or "Driver" followed by four digits of hex */
81 for (i = match; i < match+4; i++) {
82 if (var_name[i] > 127 ||
83 hex_to_bin(var_name[i] & 0xff) < 0)
84 return true;
85 }
86
87 /* Reject it if there's 4 digits of hex and then further content */
88 if (namelen > match + 4)
89 return false;
90
91 /* A valid entry must be at least 8 bytes */
92 if (len < 8)
93 return false;
94
95 filepathlength = buffer[4] | buffer[5] << 8;
96
97 /*
98 * There's no stored length for the description, so it has to be
99 * found by hand
100 */
101 desclength = ucs2_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2;
102
103 /* Each boot entry must have a descriptor */
104 if (!desclength)
105 return false;
106
107 /*
108 * If the sum of the length of the description, the claimed filepath
109 * length and the original header are greater than the length of the
110 * variable, it's malformed
111 */
112 if ((desclength + filepathlength + 6) > len)
113 return false;
114
115 /*
116 * And, finally, check the filepath
117 */
118 return validate_device_path(var_name, match, buffer + desclength + 6,
119 filepathlength);
120}
121
122static bool
123validate_uint16(efi_char16_t *var_name, int match, u8 *buffer,
124 unsigned long len)
125{
126 /* A single 16-bit integer */
127 if (len != 2)
128 return false;
129
130 return true;
131}
132
133static bool
134validate_ascii_string(efi_char16_t *var_name, int match, u8 *buffer,
135 unsigned long len)
136{
137 int i;
138
139 for (i = 0; i < len; i++) {
140 if (buffer[i] > 127)
141 return false;
142
143 if (buffer[i] == 0)
144 return true;
145 }
146
147 return false;
148}
149
150struct variable_validate {
151 efi_guid_t vendor;
152 char *name;
153 bool (*validate)(efi_char16_t *var_name, int match, u8 *data,
154 unsigned long len);
155};
156
157/*
158 * This is the list of variables we need to validate, as well as the
159 * whitelist for what we think is safe not to default to immutable.
160 *
161 * If it has a validate() method that's not NULL, it'll go into the
162 * validation routine. If not, it is assumed valid, but still used for
163 * whitelisting.
164 *
165 * Note that it's sorted by {vendor,name}, but globbed names must come after
166 * any other name with the same prefix.
167 */
168static const struct variable_validate variable_validate[] = {
169 { EFI_GLOBAL_VARIABLE_GUID, "BootNext", validate_uint16 },
170 { EFI_GLOBAL_VARIABLE_GUID, "BootOrder", validate_boot_order },
171 { EFI_GLOBAL_VARIABLE_GUID, "Boot*", validate_load_option },
172 { EFI_GLOBAL_VARIABLE_GUID, "DriverOrder", validate_boot_order },
173 { EFI_GLOBAL_VARIABLE_GUID, "Driver*", validate_load_option },
174 { EFI_GLOBAL_VARIABLE_GUID, "ConIn", validate_device_path },
175 { EFI_GLOBAL_VARIABLE_GUID, "ConInDev", validate_device_path },
176 { EFI_GLOBAL_VARIABLE_GUID, "ConOut", validate_device_path },
177 { EFI_GLOBAL_VARIABLE_GUID, "ConOutDev", validate_device_path },
178 { EFI_GLOBAL_VARIABLE_GUID, "ErrOut", validate_device_path },
179 { EFI_GLOBAL_VARIABLE_GUID, "ErrOutDev", validate_device_path },
180 { EFI_GLOBAL_VARIABLE_GUID, "Lang", validate_ascii_string },
181 { EFI_GLOBAL_VARIABLE_GUID, "OsIndications", NULL },
182 { EFI_GLOBAL_VARIABLE_GUID, "PlatformLang", validate_ascii_string },
183 { EFI_GLOBAL_VARIABLE_GUID, "Timeout", validate_uint16 },
184 { LINUX_EFI_CRASH_GUID, "*", NULL },
185 { NULL_GUID, "", NULL },
186};
187
188/*
189 * Check if @var_name matches the pattern given in @match_name.
190 *
191 * @var_name: an array of @len non-NUL characters.
192 * @match_name: a NUL-terminated pattern string, optionally ending in "*". A
193 * final "*" character matches any trailing characters @var_name,
194 * including the case when there are none left in @var_name.
195 * @match: on output, the number of non-wildcard characters in @match_name
196 * that @var_name matches, regardless of the return value.
197 * @return: whether @var_name fully matches @match_name.
198 */
199static bool
200variable_matches(const char *var_name, size_t len, const char *match_name,
201 int *match)
202{
203 for (*match = 0; ; (*match)++) {
204 char c = match_name[*match];
205
206 switch (c) {
207 case '*':
208 /* Wildcard in @match_name means we've matched. */
209 return true;
210
211 case '\0':
212 /* @match_name has ended. Has @var_name too? */
213 return (*match == len);
214
215 default:
216 /*
217 * We've reached a non-wildcard char in @match_name.
218 * Continue only if there's an identical character in
219 * @var_name.
220 */
221 if (*match < len && c == var_name[*match])
222 continue;
223 return false;
224 }
225 }
226}
227
228bool
229efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data,
230 unsigned long data_size)
231{
232 int i;
233 unsigned long utf8_size;
234 u8 *utf8_name;
235
236 utf8_size = ucs2_utf8size(var_name);
237 utf8_name = kmalloc(utf8_size + 1, GFP_KERNEL);
238 if (!utf8_name)
239 return false;
240
241 ucs2_as_utf8(utf8_name, var_name, utf8_size);
242 utf8_name[utf8_size] = '\0';
243
244 for (i = 0; variable_validate[i].name[0] != '\0'; i++) {
245 const char *name = variable_validate[i].name;
246 int match = 0;
247
248 if (efi_guidcmp(vendor, variable_validate[i].vendor))
249 continue;
250
251 if (variable_matches(utf8_name, utf8_size+1, name, &match)) {
252 if (variable_validate[i].validate == NULL)
253 break;
254 kfree(utf8_name);
255 return variable_validate[i].validate(var_name, match,
256 data, data_size);
257 }
258 }
259 kfree(utf8_name);
260 return true;
261}
262
263bool
264efivar_variable_is_removable(efi_guid_t vendor, const char *var_name,
265 size_t len)
266{
267 int i;
268 bool found = false;
269 int match = 0;
270
271 /*
272 * Check if our variable is in the validated variables list
273 */
274 for (i = 0; variable_validate[i].name[0] != '\0'; i++) {
275 if (efi_guidcmp(variable_validate[i].vendor, vendor))
276 continue;
277
278 if (variable_matches(var_name, len,
279 variable_validate[i].name, &match)) {
280 found = true;
281 break;
282 }
283 }
284
285 /*
286 * If it's in our list, it is removable.
287 */
288 return found;
289}
290
291static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor,
292 struct list_head *head)
293{
294 struct efivar_entry *entry, *n;
295 unsigned long strsize1, strsize2;
296 bool found = false;
297
298 strsize1 = ucs2_strsize(variable_name, 1024);
299 list_for_each_entry_safe(entry, n, head, list) {
300 strsize2 = ucs2_strsize(entry->var.VariableName, 1024);
301 if (strsize1 == strsize2 &&
302 !memcmp(variable_name, &(entry->var.VariableName),
303 strsize2) &&
304 !efi_guidcmp(entry->var.VendorGuid,
305 *vendor)) {
306 found = true;
307 break;
308 }
309 }
310 return found;
311}
312
313/*
314 * Returns the size of variable_name, in bytes, including the
315 * terminating NULL character, or variable_name_size if no NULL
316 * character is found among the first variable_name_size bytes.
317 */
318static unsigned long var_name_strnsize(efi_char16_t *variable_name,
319 unsigned long variable_name_size)
320{
321 unsigned long len;
322 efi_char16_t c;
323
324 /*
325 * The variable name is, by definition, a NULL-terminated
326 * string, so make absolutely sure that variable_name_size is
327 * the value we expect it to be. If not, return the real size.
328 */
329 for (len = 2; len <= variable_name_size; len += sizeof(c)) {
330 c = variable_name[(len / sizeof(c)) - 1];
331 if (!c)
332 break;
333 }
334
335 return min(len, variable_name_size);
336}
337
338/*
339 * Print a warning when duplicate EFI variables are encountered and
340 * disable the sysfs workqueue since the firmware is buggy.
341 */
342static void dup_variable_bug(efi_char16_t *str16, efi_guid_t *vendor_guid,
343 unsigned long len16)
344{
345 size_t i, len8 = len16 / sizeof(efi_char16_t);
346 char *str8;
347
348 str8 = kzalloc(len8, GFP_KERNEL);
349 if (!str8)
350 return;
351
352 for (i = 0; i < len8; i++)
353 str8[i] = str16[i];
354
355 printk(KERN_WARNING "efivars: duplicate variable: %s-%pUl\n",
356 str8, vendor_guid);
357 kfree(str8);
358}
359
360/**
361 * efivar_init - build the initial list of EFI variables
362 * @func: callback function to invoke for every variable
363 * @data: function-specific data to pass to @func
364 * @duplicates: error if we encounter duplicates on @head?
365 * @head: initialised head of variable list
366 *
367 * Get every EFI variable from the firmware and invoke @func. @func
368 * should call efivar_entry_add() to build the list of variables.
369 *
370 * Returns 0 on success, or a kernel error code on failure.
371 */
372int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
373 void *data, bool duplicates, struct list_head *head)
374{
375 unsigned long variable_name_size = 1024;
376 efi_char16_t *variable_name;
377 efi_status_t status;
378 efi_guid_t vendor_guid;
379 int err = 0;
380
381 variable_name = kzalloc(variable_name_size, GFP_KERNEL);
382 if (!variable_name) {
383 printk(KERN_ERR "efivars: Memory allocation failed.\n");
384 return -ENOMEM;
385 }
386
387 err = efivar_lock();
388 if (err)
389 goto free;
390
391 /*
392 * Per EFI spec, the maximum storage allocated for both
393 * the variable name and variable data is 1024 bytes.
394 */
395
396 do {
397 variable_name_size = 1024;
398
399 status = efivar_get_next_variable(&variable_name_size,
400 variable_name,
401 &vendor_guid);
402 switch (status) {
403 case EFI_SUCCESS:
404 variable_name_size = var_name_strnsize(variable_name,
405 variable_name_size);
406
407 /*
408 * Some firmware implementations return the
409 * same variable name on multiple calls to
410 * get_next_variable(). Terminate the loop
411 * immediately as there is no guarantee that
412 * we'll ever see a different variable name,
413 * and may end up looping here forever.
414 */
415 if (duplicates &&
416 variable_is_present(variable_name, &vendor_guid,
417 head)) {
418 dup_variable_bug(variable_name, &vendor_guid,
419 variable_name_size);
420 status = EFI_NOT_FOUND;
421 } else {
422 err = func(variable_name, vendor_guid,
423 variable_name_size, data);
424 if (err)
425 status = EFI_NOT_FOUND;
426 }
427 break;
428 case EFI_UNSUPPORTED:
429 err = -EOPNOTSUPP;
430 status = EFI_NOT_FOUND;
431 break;
432 case EFI_NOT_FOUND:
433 break;
434 default:
435 printk(KERN_WARNING "efivars: get_next_variable: status=%lx\n",
436 status);
437 status = EFI_NOT_FOUND;
438 break;
439 }
440
441 } while (status != EFI_NOT_FOUND);
442
443 efivar_unlock();
444free:
445 kfree(variable_name);
446
447 return err;
448}
449
450/**
451 * efivar_entry_add - add entry to variable list
452 * @entry: entry to add to list
453 * @head: list head
454 *
455 * Returns 0 on success, or a kernel error code on failure.
456 */
457int efivar_entry_add(struct efivar_entry *entry, struct list_head *head)
458{
459 int err;
460
461 err = efivar_lock();
462 if (err)
463 return err;
464 list_add(&entry->list, head);
465 efivar_unlock();
466
467 return 0;
468}
469
470/**
471 * __efivar_entry_add - add entry to variable list
472 * @entry: entry to add to list
473 * @head: list head
474 */
475void __efivar_entry_add(struct efivar_entry *entry, struct list_head *head)
476{
477 list_add(&entry->list, head);
478}
479
480/**
481 * efivar_entry_remove - remove entry from variable list
482 * @entry: entry to remove from list
483 *
484 * Returns 0 on success, or a kernel error code on failure.
485 */
486void efivar_entry_remove(struct efivar_entry *entry)
487{
488 list_del(&entry->list);
489}
490
491/*
492 * efivar_entry_list_del_unlock - remove entry from variable list
493 * @entry: entry to remove
494 *
495 * Remove @entry from the variable list and release the list lock.
496 *
497 * NOTE: slightly weird locking semantics here - we expect to be
498 * called with the efivars lock already held, and we release it before
499 * returning. This is because this function is usually called after
500 * set_variable() while the lock is still held.
501 */
502static void efivar_entry_list_del_unlock(struct efivar_entry *entry)
503{
504 list_del(&entry->list);
505 efivar_unlock();
506}
507
508/**
509 * efivar_entry_delete - delete variable and remove entry from list
510 * @entry: entry containing variable to delete
511 *
512 * Delete the variable from the firmware and remove @entry from the
513 * variable list. It is the caller's responsibility to free @entry
514 * once we return.
515 *
516 * Returns 0 on success, -EINTR if we can't grab the semaphore,
517 * converted EFI status code if set_variable() fails.
518 */
519int efivar_entry_delete(struct efivar_entry *entry)
520{
521 efi_status_t status;
522 int err;
523
524 err = efivar_lock();
525 if (err)
526 return err;
527
528 status = efivar_set_variable_locked(entry->var.VariableName,
529 &entry->var.VendorGuid,
530 0, 0, NULL, false);
531 if (!(status == EFI_SUCCESS || status == EFI_NOT_FOUND)) {
532 efivar_unlock();
533 return efi_status_to_err(status);
534 }
535
536 efivar_entry_list_del_unlock(entry);
537 return 0;
538}
539
540/**
541 * efivar_entry_size - obtain the size of a variable
542 * @entry: entry for this variable
543 * @size: location to store the variable's size
544 */
545int efivar_entry_size(struct efivar_entry *entry, unsigned long *size)
546{
547 efi_status_t status;
548 int err;
549
550 *size = 0;
551
552 err = efivar_lock();
553 if (err)
554 return err;
555
556 status = efivar_get_variable(entry->var.VariableName,
557 &entry->var.VendorGuid, NULL, size, NULL);
558 efivar_unlock();
559
560 if (status != EFI_BUFFER_TOO_SMALL)
561 return efi_status_to_err(status);
562
563 return 0;
564}
565
566/**
567 * __efivar_entry_get - call get_variable()
568 * @entry: read data for this variable
569 * @attributes: variable attributes
570 * @size: size of @data buffer
571 * @data: buffer to store variable data
572 *
573 * The caller MUST call efivar_entry_iter_begin() and
574 * efivar_entry_iter_end() before and after the invocation of this
575 * function, respectively.
576 */
577int __efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
578 unsigned long *size, void *data)
579{
580 efi_status_t status;
581
582 status = efivar_get_variable(entry->var.VariableName,
583 &entry->var.VendorGuid,
584 attributes, size, data);
585
586 return efi_status_to_err(status);
587}
588
589/**
590 * efivar_entry_get - call get_variable()
591 * @entry: read data for this variable
592 * @attributes: variable attributes
593 * @size: size of @data buffer
594 * @data: buffer to store variable data
595 */
596int efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
597 unsigned long *size, void *data)
598{
599 int err;
600
601 err = efivar_lock();
602 if (err)
603 return err;
604 err = __efivar_entry_get(entry, attributes, size, data);
605 efivar_unlock();
606
607 return 0;
608}
609
610/**
611 * efivar_entry_set_get_size - call set_variable() and get new size (atomic)
612 * @entry: entry containing variable to set and get
613 * @attributes: attributes of variable to be written
614 * @size: size of data buffer
615 * @data: buffer containing data to write
616 * @set: did the set_variable() call succeed?
617 *
618 * This is a pretty special (complex) function. See efivarfs_file_write().
619 *
620 * Atomically call set_variable() for @entry and if the call is
621 * successful, return the new size of the variable from get_variable()
622 * in @size. The success of set_variable() is indicated by @set.
623 *
624 * Returns 0 on success, -EINVAL if the variable data is invalid,
625 * -ENOSPC if the firmware does not have enough available space, or a
626 * converted EFI status code if either of set_variable() or
627 * get_variable() fail.
628 *
629 * If the EFI variable does not exist when calling set_variable()
630 * (EFI_NOT_FOUND), @entry is removed from the variable list.
631 */
632int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes,
633 unsigned long *size, void *data, bool *set)
634{
635 efi_char16_t *name = entry->var.VariableName;
636 efi_guid_t *vendor = &entry->var.VendorGuid;
637 efi_status_t status;
638 int err;
639
640 *set = false;
641
642 if (efivar_validate(*vendor, name, data, *size) == false)
643 return -EINVAL;
644
645 /*
646 * The lock here protects the get_variable call, the conditional
647 * set_variable call, and removal of the variable from the efivars
648 * list (in the case of an authenticated delete).
649 */
650 err = efivar_lock();
651 if (err)
652 return err;
653
654 /*
655 * Ensure that the available space hasn't shrunk below the safe level
656 */
657 status = check_var_size(attributes, *size + ucs2_strsize(name, 1024));
658 if (status != EFI_SUCCESS) {
659 if (status != EFI_UNSUPPORTED) {
660 err = efi_status_to_err(status);
661 goto out;
662 }
663
664 if (*size > 65536) {
665 err = -ENOSPC;
666 goto out;
667 }
668 }
669
670 status = efivar_set_variable_locked(name, vendor, attributes, *size,
671 data, false);
672 if (status != EFI_SUCCESS) {
673 err = efi_status_to_err(status);
674 goto out;
675 }
676
677 *set = true;
678
679 /*
680 * Writing to the variable may have caused a change in size (which
681 * could either be an append or an overwrite), or the variable to be
682 * deleted. Perform a GetVariable() so we can tell what actually
683 * happened.
684 */
685 *size = 0;
686 status = efivar_get_variable(entry->var.VariableName,
687 &entry->var.VendorGuid,
688 NULL, size, NULL);
689
690 if (status == EFI_NOT_FOUND)
691 efivar_entry_list_del_unlock(entry);
692 else
693 efivar_unlock();
694
695 if (status && status != EFI_BUFFER_TOO_SMALL)
696 return efi_status_to_err(status);
697
698 return 0;
699
700out:
701 efivar_unlock();
702 return err;
703
704}
705
706/**
707 * efivar_entry_iter - iterate over variable list
708 * @func: callback function
709 * @head: head of variable list
710 * @data: function-specific data to pass to callback
711 *
712 * Iterate over the list of EFI variables and call @func with every
713 * entry on the list. It is safe for @func to remove entries in the
714 * list via efivar_entry_delete() while iterating.
715 *
716 * Some notes for the callback function:
717 * - a non-zero return value indicates an error and terminates the loop
718 * - @func is called from atomic context
719 */
720int efivar_entry_iter(int (*func)(struct efivar_entry *, void *),
721 struct list_head *head, void *data)
722{
723 struct efivar_entry *entry, *n;
724 int err = 0;
725
726 err = efivar_lock();
727 if (err)
728 return err;
729
730 list_for_each_entry_safe(entry, n, head, list) {
731 err = func(entry, data);
732 if (err)
733 break;
734 }
735 efivar_unlock();
736
737 return err;
738}
include/linux/efi.h+0−56
@@ -1030,27 +1030,6 @@ struct efivars { · 1029 unmodified lines
1030 1030
1031#define EFI_VAR_NAME_LEN 10241031#define EFI_VAR_NAME_LEN 1024
1032 1032
1033struct efi_variable {
1034 efi_char16_t VariableName[EFI_VAR_NAME_LEN/sizeof(efi_char16_t)];
1035 efi_guid_t VendorGuid;
1036 unsigned long DataSize;
1037 __u8 Data[1024];
1038 efi_status_t Status;
1039 __u32 Attributes;
1040} __attribute__((packed));
1041
1042struct efivar_entry {
1043 struct efi_variable var;
1044 struct list_head list;
1045 struct kobject kobj;
1046};
1047
1048static inline void
1049efivar_unregister(struct efivar_entry *var)
1050{
1051 kobject_put(&var->kobj);
1052}
1053
1054int efivars_register(struct efivars *efivars,1033int efivars_register(struct efivars *efivars,
1055 const struct efivar_operations *ops,1034 const struct efivar_operations *ops,
1056 struct kobject *kobject);1035 struct kobject *kobject);
@@ -1058,41 +1037,6 @@ int efivars_unregister(struct efivars *efivars); · 1 unmodified line
1058struct kobject *efivars_kobject(void);1037struct kobject *efivars_kobject(void);
1059 1038
1060int efivar_supports_writes(void);1039int efivar_supports_writes(void);
1061int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
1062 void *data, bool duplicates, struct list_head *head);
1063
1064int efivar_entry_add(struct efivar_entry *entry, struct list_head *head);
1065void __efivar_entry_add(struct efivar_entry *entry, struct list_head *head);
1066void efivar_entry_remove(struct efivar_entry *entry);
1067
1068int __efivar_entry_delete(struct efivar_entry *entry);
1069int efivar_entry_delete(struct efivar_entry *entry);
1070
1071int efivar_entry_size(struct efivar_entry *entry, unsigned long *size);
1072int __efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
1073 unsigned long *size, void *data);
1074int efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
1075 unsigned long *size, void *data);
1076int efivar_entry_set(struct efivar_entry *entry, u32 attributes,
1077 unsigned long size, void *data, struct list_head *head);
1078int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes,
1079 unsigned long *size, void *data, bool *set);
1080int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes,
1081 bool block, unsigned long size, void *data);
1082
1083int efivar_entry_iter_begin(void);
1084void efivar_entry_iter_end(void);
1085
1086int efivar_entry_iter(int (*func)(struct efivar_entry *, void *),
1087 struct list_head *head, void *data);
1088
1089struct efivar_entry *efivar_entry_find(efi_char16_t *name, efi_guid_t guid,
1090 struct list_head *head, bool remove);
1091
1092bool efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data,
1093 unsigned long data_size);
1094bool efivar_variable_is_removable(efi_guid_t vendor, const char *name,
1095 size_t len);
1096 1040
1097int efivar_lock(void);1041int efivar_lock(void);
1098int efivar_trylock(void);1042int efivar_trylock(void);