1 /*
2  * EFI Variables - efivars.c
3  *
4  * Copyright (C) 2001,2003,2004 Dell <Matt_Domsch@dell.com>
5  * Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com>
6  *
7  * This code takes all variables accessible from EFI runtime and
8  *  exports them via sysfs
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  *
24  * Changelog:
25  *
26  *  17 May 2004 - Matt Domsch <Matt_Domsch@dell.com>
27  *   remove check for efi_enabled in exit
28  *   add MODULE_VERSION
29  *
30  *  26 Apr 2004 - Matt Domsch <Matt_Domsch@dell.com>
31  *   minor bug fixes
32  *
33  *  21 Apr 2004 - Matt Tolentino <matthew.e.tolentino@intel.com)
34  *   converted driver to export variable information via sysfs
35  *   and moved to drivers/firmware directory
36  *   bumped revision number to v0.07 to reflect conversion & move
37  *
38  *  10 Dec 2002 - Matt Domsch <Matt_Domsch@dell.com>
39  *   fix locking per Peter Chubb's findings
40  *
41  *  25 Mar 2002 - Matt Domsch <Matt_Domsch@dell.com>
42  *   move uuid_unparse() to include/asm-ia64/efi.h:efi_guid_unparse()
43  *
44  *  12 Feb 2002 - Matt Domsch <Matt_Domsch@dell.com>
45  *   use list_for_each_safe when deleting vars.
46  *   remove ifdef CONFIG_SMP around include <linux/smp.h>
47  *   v0.04 release to linux-ia64@linuxia64.org
48  *
49  *  20 April 2001 - Matt Domsch <Matt_Domsch@dell.com>
50  *   Moved vars from /proc/efi to /proc/efi/vars, and made
51  *   efi.c own the /proc/efi directory.
52  *   v0.03 release to linux-ia64@linuxia64.org
53  *
54  *  26 March 2001 - Matt Domsch <Matt_Domsch@dell.com>
55  *   At the request of Stephane, moved ownership of /proc/efi
56  *   to efi.c, and now efivars lives under /proc/efi/vars.
57  *
58  *  12 March 2001 - Matt Domsch <Matt_Domsch@dell.com>
59  *   Feedback received from Stephane Eranian incorporated.
60  *   efivar_write() checks copy_from_user() return value.
61  *   efivar_read/write() returns proper errno.
62  *   v0.02 release to linux-ia64@linuxia64.org
63  *
64  *  26 February 2001 - Matt Domsch <Matt_Domsch@dell.com>
65  *   v0.01 release to linux-ia64@linuxia64.org
66  */
67 
68 #include <linux/capability.h>
69 #include <linux/types.h>
70 #include <linux/errno.h>
71 #include <linux/init.h>
72 #include <linux/mm.h>
73 #include <linux/module.h>
74 #include <linux/string.h>
75 #include <linux/smp.h>
76 #include <linux/efi.h>
77 #include <linux/sysfs.h>
78 #include <linux/kobject.h>
79 #include <linux/device.h>
80 #include <linux/slab.h>
81 #include <linux/pstore.h>
82 
83 #include <asm/uaccess.h>
84 
85 #define EFIVARS_VERSION "0.08"
86 #define EFIVARS_DATE "2004-May-17"
87 
88 MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>");
89 MODULE_DESCRIPTION("sysfs interface to EFI Variables");
90 MODULE_LICENSE("GPL");
91 MODULE_VERSION(EFIVARS_VERSION);
92 
93 #define DUMP_NAME_LEN 52
94 
95 static bool efivars_pstore_disable =
96 	IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE);
97 
98 module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644);
99 
100 /*
101  * The maximum size of VariableName + Data = 1024
102  * Therefore, it's reasonable to save that much
103  * space in each part of the structure,
104  * and we use a page for reading/writing.
105  */
106 
107 struct efi_variable {
108 	efi_char16_t  VariableName[1024/sizeof(efi_char16_t)];
109 	efi_guid_t    VendorGuid;
110 	unsigned long DataSize;
111 	__u8          Data[1024];
112 	efi_status_t  Status;
113 	__u32         Attributes;
114 } __attribute__((packed));
115 
116 
117 struct efivar_entry {
118 	struct efivars *efivars;
119 	struct efi_variable var;
120 	struct list_head list;
121 	struct kobject kobj;
122 };
123 
124 struct efivar_attribute {
125 	struct attribute attr;
126 	ssize_t (*show) (struct efivar_entry *entry, char *buf);
127 	ssize_t (*store)(struct efivar_entry *entry, const char *buf, size_t count);
128 };
129 
130 static struct efivars __efivars;
131 static struct efivar_operations ops;
132 
133 #define PSTORE_EFI_ATTRIBUTES \
134 	(EFI_VARIABLE_NON_VOLATILE | \
135 	 EFI_VARIABLE_BOOTSERVICE_ACCESS | \
136 	 EFI_VARIABLE_RUNTIME_ACCESS)
137 
138 #define EFIVAR_ATTR(_name, _mode, _show, _store) \
139 struct efivar_attribute efivar_attr_##_name = { \
140 	.attr = {.name = __stringify(_name), .mode = _mode}, \
141 	.show = _show, \
142 	.store = _store, \
143 };
144 
145 #define to_efivar_attr(_attr) container_of(_attr, struct efivar_attribute, attr)
146 #define to_efivar_entry(obj)  container_of(obj, struct efivar_entry, kobj)
147 
148 /*
149  * Prototype for sysfs creation function
150  */
151 static int
152 efivar_create_sysfs_entry(struct efivars *efivars,
153 			  unsigned long variable_name_size,
154 			  efi_char16_t *variable_name,
155 			  efi_guid_t *vendor_guid);
156 
157 /*
158  * Prototype for workqueue functions updating sysfs entry
159  */
160 
161 static void efivar_update_sysfs_entries(struct work_struct *);
162 static DECLARE_WORK(efivar_work, efivar_update_sysfs_entries);
163 
164 /* Return the number of unicode characters in data */
165 static unsigned long
utf16_strnlen(efi_char16_t * s,size_t maxlength)166 utf16_strnlen(efi_char16_t *s, size_t maxlength)
167 {
168 	unsigned long length = 0;
169 
170 	while (*s++ != 0 && length < maxlength)
171 		length++;
172 	return length;
173 }
174 
175 static inline unsigned long
utf16_strlen(efi_char16_t * s)176 utf16_strlen(efi_char16_t *s)
177 {
178 	return utf16_strnlen(s, ~0UL);
179 }
180 
181 /*
182  * Return the number of bytes is the length of this string
183  * Note: this is NOT the same as the number of unicode characters
184  */
185 static inline unsigned long
utf16_strsize(efi_char16_t * data,unsigned long maxlength)186 utf16_strsize(efi_char16_t *data, unsigned long maxlength)
187 {
188 	return utf16_strnlen(data, maxlength/sizeof(efi_char16_t)) * sizeof(efi_char16_t);
189 }
190 
191 static inline int
utf16_strncmp(const efi_char16_t * a,const efi_char16_t * b,size_t len)192 utf16_strncmp(const efi_char16_t *a, const efi_char16_t *b, size_t len)
193 {
194 	while (1) {
195 		if (len == 0)
196 			return 0;
197 		if (*a < *b)
198 			return -1;
199 		if (*a > *b)
200 			return 1;
201 		if (*a == 0) /* implies *b == 0 */
202 			return 0;
203 		a++;
204 		b++;
205 		len--;
206 	}
207 }
208 
209 static bool
validate_device_path(struct efi_variable * var,int match,u8 * buffer,unsigned long len)210 validate_device_path(struct efi_variable *var, int match, u8 *buffer,
211 		     unsigned long len)
212 {
213 	struct efi_generic_dev_path *node;
214 	int offset = 0;
215 
216 	node = (struct efi_generic_dev_path *)buffer;
217 
218 	if (len < sizeof(*node))
219 		return false;
220 
221 	while (offset <= len - sizeof(*node) &&
222 	       node->length >= sizeof(*node) &&
223 		node->length <= len - offset) {
224 		offset += node->length;
225 
226 		if ((node->type == EFI_DEV_END_PATH ||
227 		     node->type == EFI_DEV_END_PATH2) &&
228 		    node->sub_type == EFI_DEV_END_ENTIRE)
229 			return true;
230 
231 		node = (struct efi_generic_dev_path *)(buffer + offset);
232 	}
233 
234 	/*
235 	 * If we're here then either node->length pointed past the end
236 	 * of the buffer or we reached the end of the buffer without
237 	 * finding a device path end node.
238 	 */
239 	return false;
240 }
241 
242 static bool
validate_boot_order(struct efi_variable * var,int match,u8 * buffer,unsigned long len)243 validate_boot_order(struct efi_variable *var, int match, u8 *buffer,
244 		    unsigned long len)
245 {
246 	/* An array of 16-bit integers */
247 	if ((len % 2) != 0)
248 		return false;
249 
250 	return true;
251 }
252 
253 static bool
validate_load_option(struct efi_variable * var,int match,u8 * buffer,unsigned long len)254 validate_load_option(struct efi_variable *var, int match, u8 *buffer,
255 		     unsigned long len)
256 {
257 	u16 filepathlength;
258 	int i, desclength = 0, namelen;
259 
260 	namelen = utf16_strnlen(var->VariableName, sizeof(var->VariableName));
261 
262 	/* Either "Boot" or "Driver" followed by four digits of hex */
263 	for (i = match; i < match+4; i++) {
264 		if (var->VariableName[i] > 127 ||
265 		    hex_to_bin(var->VariableName[i] & 0xff) < 0)
266 			return true;
267 	}
268 
269 	/* Reject it if there's 4 digits of hex and then further content */
270 	if (namelen > match + 4)
271 		return false;
272 
273 	/* A valid entry must be at least 8 bytes */
274 	if (len < 8)
275 		return false;
276 
277 	filepathlength = buffer[4] | buffer[5] << 8;
278 
279 	/*
280 	 * There's no stored length for the description, so it has to be
281 	 * found by hand
282 	 */
283 	desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2;
284 
285 	/* Each boot entry must have a descriptor */
286 	if (!desclength)
287 		return false;
288 
289 	/*
290 	 * If the sum of the length of the description, the claimed filepath
291 	 * length and the original header are greater than the length of the
292 	 * variable, it's malformed
293 	 */
294 	if ((desclength + filepathlength + 6) > len)
295 		return false;
296 
297 	/*
298 	 * And, finally, check the filepath
299 	 */
300 	return validate_device_path(var, match, buffer + desclength + 6,
301 				    filepathlength);
302 }
303 
304 static bool
validate_uint16(struct efi_variable * var,int match,u8 * buffer,unsigned long len)305 validate_uint16(struct efi_variable *var, int match, u8 *buffer,
306 		unsigned long len)
307 {
308 	/* A single 16-bit integer */
309 	if (len != 2)
310 		return false;
311 
312 	return true;
313 }
314 
315 static bool
validate_ascii_string(struct efi_variable * var,int match,u8 * buffer,unsigned long len)316 validate_ascii_string(struct efi_variable *var, int match, u8 *buffer,
317 		      unsigned long len)
318 {
319 	int i;
320 
321 	for (i = 0; i < len; i++) {
322 		if (buffer[i] > 127)
323 			return false;
324 
325 		if (buffer[i] == 0)
326 			return true;
327 	}
328 
329 	return false;
330 }
331 
332 struct variable_validate {
333 	char *name;
334 	bool (*validate)(struct efi_variable *var, int match, u8 *data,
335 			 unsigned long len);
336 };
337 
338 static const struct variable_validate variable_validate[] = {
339 	{ "BootNext", validate_uint16 },
340 	{ "BootOrder", validate_boot_order },
341 	{ "DriverOrder", validate_boot_order },
342 	{ "Boot*", validate_load_option },
343 	{ "Driver*", validate_load_option },
344 	{ "ConIn", validate_device_path },
345 	{ "ConInDev", validate_device_path },
346 	{ "ConOut", validate_device_path },
347 	{ "ConOutDev", validate_device_path },
348 	{ "ErrOut", validate_device_path },
349 	{ "ErrOutDev", validate_device_path },
350 	{ "Timeout", validate_uint16 },
351 	{ "Lang", validate_ascii_string },
352 	{ "PlatformLang", validate_ascii_string },
353 	{ "", NULL },
354 };
355 
356 static bool
validate_var(struct efi_variable * var,u8 * data,unsigned long len)357 validate_var(struct efi_variable *var, u8 *data, unsigned long len)
358 {
359 	int i;
360 	u16 *unicode_name = var->VariableName;
361 
362 	for (i = 0; variable_validate[i].validate != NULL; i++) {
363 		const char *name = variable_validate[i].name;
364 		int match;
365 
366 		for (match = 0; ; match++) {
367 			char c = name[match];
368 			u16 u = unicode_name[match];
369 
370 			/* All special variables are plain ascii */
371 			if (u > 127)
372 				return true;
373 
374 			/* Wildcard in the matching name means we've matched */
375 			if (c == '*')
376 				return variable_validate[i].validate(var,
377 							     match, data, len);
378 
379 			/* Case sensitive match */
380 			if (c != u)
381 				break;
382 
383 			/* Reached the end of the string while matching */
384 			if (!c)
385 				return variable_validate[i].validate(var,
386 							     match, data, len);
387 		}
388 	}
389 
390 	return true;
391 }
392 
393 static efi_status_t
get_var_data_locked(struct efivars * efivars,struct efi_variable * var)394 get_var_data_locked(struct efivars *efivars, struct efi_variable *var)
395 {
396 	efi_status_t status;
397 
398 	var->DataSize = 1024;
399 	status = efivars->ops->get_variable(var->VariableName,
400 					    &var->VendorGuid,
401 					    &var->Attributes,
402 					    &var->DataSize,
403 					    var->Data);
404 	return status;
405 }
406 
407 static efi_status_t
get_var_data(struct efivars * efivars,struct efi_variable * var)408 get_var_data(struct efivars *efivars, struct efi_variable *var)
409 {
410 	efi_status_t status;
411 	unsigned long flags;
412 
413 	spin_lock_irqsave(&efivars->lock, flags);
414 	status = get_var_data_locked(efivars, var);
415 	spin_unlock_irqrestore(&efivars->lock, flags);
416 
417 	if (status != EFI_SUCCESS) {
418 		printk(KERN_WARNING "efivars: get_variable() failed 0x%lx!\n",
419 			status);
420 	}
421 	return status;
422 }
423 
424 static efi_status_t
check_var_size_locked(struct efivars * efivars,u32 attributes,unsigned long size)425 check_var_size_locked(struct efivars *efivars, u32 attributes,
426 			unsigned long size)
427 {
428 	const struct efivar_operations *fops = efivars->ops;
429 
430 	if (!efivars->ops->query_variable_store)
431 		return EFI_UNSUPPORTED;
432 
433 	return fops->query_variable_store(attributes, size);
434 }
435 
436 static ssize_t
efivar_guid_read(struct efivar_entry * entry,char * buf)437 efivar_guid_read(struct efivar_entry *entry, char *buf)
438 {
439 	struct efi_variable *var = &entry->var;
440 	char *str = buf;
441 
442 	if (!entry || !buf)
443 		return 0;
444 
445 	efi_guid_unparse(&var->VendorGuid, str);
446 	str += strlen(str);
447 	str += sprintf(str, "\n");
448 
449 	return str - buf;
450 }
451 
452 static ssize_t
efivar_attr_read(struct efivar_entry * entry,char * buf)453 efivar_attr_read(struct efivar_entry *entry, char *buf)
454 {
455 	struct efi_variable *var = &entry->var;
456 	char *str = buf;
457 	efi_status_t status;
458 
459 	if (!entry || !buf)
460 		return -EINVAL;
461 
462 	status = get_var_data(entry->efivars, var);
463 	if (status != EFI_SUCCESS)
464 		return -EIO;
465 
466 	if (var->Attributes & EFI_VARIABLE_NON_VOLATILE)
467 		str += sprintf(str, "EFI_VARIABLE_NON_VOLATILE\n");
468 	if (var->Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS)
469 		str += sprintf(str, "EFI_VARIABLE_BOOTSERVICE_ACCESS\n");
470 	if (var->Attributes & EFI_VARIABLE_RUNTIME_ACCESS)
471 		str += sprintf(str, "EFI_VARIABLE_RUNTIME_ACCESS\n");
472 	if (var->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD)
473 		str += sprintf(str, "EFI_VARIABLE_HARDWARE_ERROR_RECORD\n");
474 	if (var->Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)
475 		str += sprintf(str,
476 			"EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS\n");
477 	if (var->Attributes &
478 			EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)
479 		str += sprintf(str,
480 			"EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS\n");
481 	if (var->Attributes & EFI_VARIABLE_APPEND_WRITE)
482 		str += sprintf(str, "EFI_VARIABLE_APPEND_WRITE\n");
483 	return str - buf;
484 }
485 
486 static ssize_t
efivar_size_read(struct efivar_entry * entry,char * buf)487 efivar_size_read(struct efivar_entry *entry, char *buf)
488 {
489 	struct efi_variable *var = &entry->var;
490 	char *str = buf;
491 	efi_status_t status;
492 
493 	if (!entry || !buf)
494 		return -EINVAL;
495 
496 	status = get_var_data(entry->efivars, var);
497 	if (status != EFI_SUCCESS)
498 		return -EIO;
499 
500 	str += sprintf(str, "0x%lx\n", var->DataSize);
501 	return str - buf;
502 }
503 
504 static ssize_t
efivar_data_read(struct efivar_entry * entry,char * buf)505 efivar_data_read(struct efivar_entry *entry, char *buf)
506 {
507 	struct efi_variable *var = &entry->var;
508 	efi_status_t status;
509 
510 	if (!entry || !buf)
511 		return -EINVAL;
512 
513 	status = get_var_data(entry->efivars, var);
514 	if (status != EFI_SUCCESS)
515 		return -EIO;
516 
517 	memcpy(buf, var->Data, var->DataSize);
518 	return var->DataSize;
519 }
520 /*
521  * We allow each variable to be edited via rewriting the
522  * entire efi variable structure.
523  */
524 static ssize_t
efivar_store_raw(struct efivar_entry * entry,const char * buf,size_t count)525 efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
526 {
527 	struct efi_variable *new_var, *var = &entry->var;
528 	struct efivars *efivars = entry->efivars;
529 	efi_status_t status = EFI_NOT_FOUND;
530 
531 	if (count != sizeof(struct efi_variable))
532 		return -EINVAL;
533 
534 	new_var = (struct efi_variable *)buf;
535 	/*
536 	 * If only updating the variable data, then the name
537 	 * and guid should remain the same
538 	 */
539 	if (memcmp(new_var->VariableName, var->VariableName, sizeof(var->VariableName)) ||
540 		efi_guidcmp(new_var->VendorGuid, var->VendorGuid)) {
541 		printk(KERN_ERR "efivars: Cannot edit the wrong variable!\n");
542 		return -EINVAL;
543 	}
544 
545 	if ((new_var->DataSize <= 0) || (new_var->Attributes == 0)){
546 		printk(KERN_ERR "efivars: DataSize & Attributes must be valid!\n");
547 		return -EINVAL;
548 	}
549 
550 	if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
551 	    validate_var(new_var, new_var->Data, new_var->DataSize) == false) {
552 		printk(KERN_ERR "efivars: Malformed variable content\n");
553 		return -EINVAL;
554 	}
555 
556 	spin_lock_irq(&efivars->lock);
557 
558 	status = check_var_size_locked(efivars, new_var->Attributes,
559 	       new_var->DataSize + utf16_strsize(new_var->VariableName, 1024));
560 
561 	if (status == EFI_SUCCESS || status == EFI_UNSUPPORTED)
562 		status = efivars->ops->set_variable(new_var->VariableName,
563 						    &new_var->VendorGuid,
564 						    new_var->Attributes,
565 						    new_var->DataSize,
566 						    new_var->Data);
567 
568 	spin_unlock_irq(&efivars->lock);
569 
570 	if (status != EFI_SUCCESS) {
571 		printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
572 			status);
573 		return -EIO;
574 	}
575 
576 	memcpy(&entry->var, new_var, count);
577 	return count;
578 }
579 
580 static ssize_t
efivar_show_raw(struct efivar_entry * entry,char * buf)581 efivar_show_raw(struct efivar_entry *entry, char *buf)
582 {
583 	struct efi_variable *var = &entry->var;
584 	efi_status_t status;
585 
586 	if (!entry || !buf)
587 		return 0;
588 
589 	status = get_var_data(entry->efivars, var);
590 	if (status != EFI_SUCCESS)
591 		return -EIO;
592 
593 	memcpy(buf, var, sizeof(*var));
594 	return sizeof(*var);
595 }
596 
597 /*
598  * Generic read/write functions that call the specific functions of
599  * the attributes...
600  */
efivar_attr_show(struct kobject * kobj,struct attribute * attr,char * buf)601 static ssize_t efivar_attr_show(struct kobject *kobj, struct attribute *attr,
602 				char *buf)
603 {
604 	struct efivar_entry *var = to_efivar_entry(kobj);
605 	struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
606 	ssize_t ret = -EIO;
607 
608 	if (!capable(CAP_SYS_ADMIN))
609 		return -EACCES;
610 
611 	if (efivar_attr->show) {
612 		ret = efivar_attr->show(var, buf);
613 	}
614 	return ret;
615 }
616 
efivar_attr_store(struct kobject * kobj,struct attribute * attr,const char * buf,size_t count)617 static ssize_t efivar_attr_store(struct kobject *kobj, struct attribute *attr,
618 				const char *buf, size_t count)
619 {
620 	struct efivar_entry *var = to_efivar_entry(kobj);
621 	struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
622 	ssize_t ret = -EIO;
623 
624 	if (!capable(CAP_SYS_ADMIN))
625 		return -EACCES;
626 
627 	if (efivar_attr->store)
628 		ret = efivar_attr->store(var, buf, count);
629 
630 	return ret;
631 }
632 
633 static const struct sysfs_ops efivar_attr_ops = {
634 	.show = efivar_attr_show,
635 	.store = efivar_attr_store,
636 };
637 
efivar_release(struct kobject * kobj)638 static void efivar_release(struct kobject *kobj)
639 {
640 	struct efivar_entry *var = container_of(kobj, struct efivar_entry, kobj);
641 	kfree(var);
642 }
643 
644 static EFIVAR_ATTR(guid, 0400, efivar_guid_read, NULL);
645 static EFIVAR_ATTR(attributes, 0400, efivar_attr_read, NULL);
646 static EFIVAR_ATTR(size, 0400, efivar_size_read, NULL);
647 static EFIVAR_ATTR(data, 0400, efivar_data_read, NULL);
648 static EFIVAR_ATTR(raw_var, 0600, efivar_show_raw, efivar_store_raw);
649 
650 static struct attribute *def_attrs[] = {
651 	&efivar_attr_guid.attr,
652 	&efivar_attr_size.attr,
653 	&efivar_attr_attributes.attr,
654 	&efivar_attr_data.attr,
655 	&efivar_attr_raw_var.attr,
656 	NULL,
657 };
658 
659 static struct kobj_type efivar_ktype = {
660 	.release = efivar_release,
661 	.sysfs_ops = &efivar_attr_ops,
662 	.default_attrs = def_attrs,
663 };
664 
665 static inline void
efivar_unregister(struct efivar_entry * var)666 efivar_unregister(struct efivar_entry *var)
667 {
668 	kobject_put(&var->kobj);
669 }
670 
efi_status_to_err(efi_status_t status)671 static int efi_status_to_err(efi_status_t status)
672 {
673 	int err;
674 
675 	switch (status) {
676 	case EFI_INVALID_PARAMETER:
677 		err = -EINVAL;
678 		break;
679 	case EFI_OUT_OF_RESOURCES:
680 		err = -ENOSPC;
681 		break;
682 	case EFI_DEVICE_ERROR:
683 		err = -EIO;
684 		break;
685 	case EFI_WRITE_PROTECTED:
686 		err = -EROFS;
687 		break;
688 	case EFI_SECURITY_VIOLATION:
689 		err = -EACCES;
690 		break;
691 	case EFI_NOT_FOUND:
692 		err = -ENOENT;
693 		break;
694 	default:
695 		err = -EINVAL;
696 	}
697 
698 	return err;
699 }
700 
701 #ifdef CONFIG_EFI_VARS_PSTORE
702 
efi_pstore_open(struct pstore_info * psi)703 static int efi_pstore_open(struct pstore_info *psi)
704 {
705 	struct efivars *efivars = psi->data;
706 
707 	spin_lock_irq(&efivars->lock);
708 	efivars->walk_entry = list_first_entry(&efivars->list,
709 					       struct efivar_entry, list);
710 	return 0;
711 }
712 
efi_pstore_close(struct pstore_info * psi)713 static int efi_pstore_close(struct pstore_info *psi)
714 {
715 	struct efivars *efivars = psi->data;
716 
717 	spin_unlock_irq(&efivars->lock);
718 	return 0;
719 }
720 
efi_pstore_read(u64 * id,enum pstore_type_id * type,struct timespec * timespec,char ** buf,struct pstore_info * psi)721 static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
722 			       struct timespec *timespec,
723 			       char **buf, struct pstore_info *psi)
724 {
725 	efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
726 	struct efivars *efivars = psi->data;
727 	char name[DUMP_NAME_LEN];
728 	int i;
729 	unsigned int part, size;
730 	unsigned long time;
731 
732 	while (&efivars->walk_entry->list != &efivars->list) {
733 		if (!efi_guidcmp(efivars->walk_entry->var.VendorGuid,
734 				 vendor)) {
735 			for (i = 0; i < DUMP_NAME_LEN; i++) {
736 				name[i] = efivars->walk_entry->var.VariableName[i];
737 			}
738 			if (sscanf(name, "dump-type%u-%u-%lu", type, &part, &time) == 3) {
739 				*id = part;
740 				timespec->tv_sec = time;
741 				timespec->tv_nsec = 0;
742 				get_var_data_locked(efivars, &efivars->walk_entry->var);
743 				size = efivars->walk_entry->var.DataSize;
744 				*buf = kmalloc(size, GFP_KERNEL);
745 				if (*buf == NULL)
746 					return -ENOMEM;
747 				memcpy(*buf, efivars->walk_entry->var.Data,
748 				       size);
749 				efivars->walk_entry = list_entry(efivars->walk_entry->list.next,
750 					           struct efivar_entry, list);
751 				return size;
752 			}
753 		}
754 		efivars->walk_entry = list_entry(efivars->walk_entry->list.next,
755 						 struct efivar_entry, list);
756 	}
757 	return 0;
758 }
759 
efi_pstore_write(enum pstore_type_id type,enum kmsg_dump_reason reason,u64 * id,unsigned int part,size_t size,struct pstore_info * psi)760 static int efi_pstore_write(enum pstore_type_id type,
761 		enum kmsg_dump_reason reason, u64 *id,
762 		unsigned int part, size_t size, struct pstore_info *psi)
763 {
764 	char name[DUMP_NAME_LEN];
765 	char stub_name[DUMP_NAME_LEN];
766 	efi_char16_t efi_name[DUMP_NAME_LEN];
767 	efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
768 	struct efivars *efivars = psi->data;
769 	struct efivar_entry *entry, *found = NULL;
770 	int i, ret = 0;
771 	efi_status_t status = EFI_NOT_FOUND;
772 	unsigned long flags;
773 
774 	sprintf(stub_name, "dump-type%u-%u-", type, part);
775 	sprintf(name, "%s%lu", stub_name, get_seconds());
776 
777 	spin_lock_irqsave(&efivars->lock, flags);
778 
779 	if (size) {
780 		/*
781 		 * Check if there is a space enough to log.
782 		 * size: a size of logging data
783 		 * DUMP_NAME_LEN * 2: a maximum size of variable name
784 		 */
785 
786 		status = check_var_size_locked(efivars, PSTORE_EFI_ATTRIBUTES,
787 					       size + DUMP_NAME_LEN * 2);
788 
789 		if (status) {
790 			spin_unlock_irqrestore(&efivars->lock, flags);
791 			*id = part;
792 			return -ENOSPC;
793 		}
794 	}
795 
796 	for (i = 0; i < DUMP_NAME_LEN; i++)
797 		efi_name[i] = stub_name[i];
798 
799 	/*
800 	 * Clean up any entries with the same name
801 	 */
802 
803 	list_for_each_entry(entry, &efivars->list, list) {
804 		get_var_data_locked(efivars, &entry->var);
805 
806 		if (efi_guidcmp(entry->var.VendorGuid, vendor))
807 			continue;
808 		if (utf16_strncmp(entry->var.VariableName, efi_name,
809 				  utf16_strlen(efi_name)))
810 			continue;
811 		/* Needs to be a prefix */
812 		if (entry->var.VariableName[utf16_strlen(efi_name)] == 0)
813 			continue;
814 
815 		/* found */
816 		found = entry;
817 		efivars->ops->set_variable(entry->var.VariableName,
818 					   &entry->var.VendorGuid,
819 					   PSTORE_EFI_ATTRIBUTES,
820 					   0, NULL);
821 	}
822 
823 	if (found)
824 		list_del(&found->list);
825 
826 	for (i = 0; i < DUMP_NAME_LEN; i++)
827 		efi_name[i] = name[i];
828 
829 	efivars->ops->set_variable(efi_name, &vendor, PSTORE_EFI_ATTRIBUTES,
830 				   size, psi->buf);
831 
832 	spin_unlock_irqrestore(&efivars->lock, flags);
833 
834 	if (found)
835 		efivar_unregister(found);
836 
837 	if (reason == KMSG_DUMP_OOPS)
838 		schedule_work(&efivar_work);
839 
840 	*id = part;
841 	return ret;
842 };
843 
efi_pstore_erase(enum pstore_type_id type,u64 id,struct pstore_info * psi)844 static int efi_pstore_erase(enum pstore_type_id type, u64 id,
845 			    struct pstore_info *psi)
846 {
847 	efi_pstore_write(type, 0, &id, (unsigned int)id, 0, psi);
848 
849 	return 0;
850 }
851 
852 static struct pstore_info efi_pstore_info = {
853 	.owner		= THIS_MODULE,
854 	.name		= "efi",
855 	.open		= efi_pstore_open,
856 	.close		= efi_pstore_close,
857 	.read		= efi_pstore_read,
858 	.write		= efi_pstore_write,
859 	.erase		= efi_pstore_erase,
860 };
861 
efivar_pstore_register(struct efivars * efivars)862 static void efivar_pstore_register(struct efivars *efivars)
863 {
864 	efivars->efi_pstore_info = efi_pstore_info;
865 	efivars->efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
866 	if (efivars->efi_pstore_info.buf) {
867 		efivars->efi_pstore_info.bufsize = 1024;
868 		efivars->efi_pstore_info.data = efivars;
869 		spin_lock_init(&efivars->efi_pstore_info.buf_lock);
870 		pstore_register(&efivars->efi_pstore_info);
871 	}
872 }
873 #else
efivar_pstore_register(struct efivars * efivars)874 static void efivar_pstore_register(struct efivars *efivars)
875 {
876 	return;
877 }
878 #endif
879 
efivar_create(struct file * filp,struct kobject * kobj,struct bin_attribute * bin_attr,char * buf,loff_t pos,size_t count)880 static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
881 			     struct bin_attribute *bin_attr,
882 			     char *buf, loff_t pos, size_t count)
883 {
884 	struct efi_variable *new_var = (struct efi_variable *)buf;
885 	struct efivars *efivars = bin_attr->private;
886 	struct efivar_entry *search_efivar, *n;
887 	unsigned long strsize1, strsize2;
888 	efi_status_t status = EFI_NOT_FOUND;
889 	int found = 0;
890 
891 	if (!capable(CAP_SYS_ADMIN))
892 		return -EACCES;
893 
894 	if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
895 	    validate_var(new_var, new_var->Data, new_var->DataSize) == false) {
896 		printk(KERN_ERR "efivars: Malformed variable content\n");
897 		return -EINVAL;
898 	}
899 
900 	spin_lock_irq(&efivars->lock);
901 
902 	/*
903 	 * Does this variable already exist?
904 	 */
905 	list_for_each_entry_safe(search_efivar, n, &efivars->list, list) {
906 		strsize1 = utf16_strsize(search_efivar->var.VariableName, 1024);
907 		strsize2 = utf16_strsize(new_var->VariableName, 1024);
908 		if (strsize1 == strsize2 &&
909 			!memcmp(&(search_efivar->var.VariableName),
910 				new_var->VariableName, strsize1) &&
911 			!efi_guidcmp(search_efivar->var.VendorGuid,
912 				new_var->VendorGuid)) {
913 			found = 1;
914 			break;
915 		}
916 	}
917 	if (found) {
918 		spin_unlock_irq(&efivars->lock);
919 		return -EINVAL;
920 	}
921 
922 	status = check_var_size_locked(efivars, new_var->Attributes,
923 	       new_var->DataSize + utf16_strsize(new_var->VariableName, 1024));
924 
925 	if (status && status != EFI_UNSUPPORTED) {
926 		spin_unlock_irq(&efivars->lock);
927 		return efi_status_to_err(status);
928 	}
929 
930 	/* now *really* create the variable via EFI */
931 	status = efivars->ops->set_variable(new_var->VariableName,
932 					    &new_var->VendorGuid,
933 					    new_var->Attributes,
934 					    new_var->DataSize,
935 					    new_var->Data);
936 
937 	if (status != EFI_SUCCESS) {
938 		printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
939 			status);
940 		spin_unlock_irq(&efivars->lock);
941 		return -EIO;
942 	}
943 	spin_unlock_irq(&efivars->lock);
944 
945 	/* Create the entry in sysfs.  Locking is not required here */
946 	status = efivar_create_sysfs_entry(efivars,
947 					   utf16_strsize(new_var->VariableName,
948 							 1024),
949 					   new_var->VariableName,
950 					   &new_var->VendorGuid);
951 	if (status) {
952 		printk(KERN_WARNING "efivars: variable created, but sysfs entry wasn't.\n");
953 	}
954 	return count;
955 }
956 
efivar_delete(struct file * filp,struct kobject * kobj,struct bin_attribute * bin_attr,char * buf,loff_t pos,size_t count)957 static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
958 			     struct bin_attribute *bin_attr,
959 			     char *buf, loff_t pos, size_t count)
960 {
961 	struct efi_variable *del_var = (struct efi_variable *)buf;
962 	struct efivars *efivars = bin_attr->private;
963 	struct efivar_entry *search_efivar, *n;
964 	unsigned long strsize1, strsize2;
965 	efi_status_t status = EFI_NOT_FOUND;
966 	int found = 0;
967 
968 	if (!capable(CAP_SYS_ADMIN))
969 		return -EACCES;
970 
971 	spin_lock_irq(&efivars->lock);
972 
973 	/*
974 	 * Does this variable already exist?
975 	 */
976 	list_for_each_entry_safe(search_efivar, n, &efivars->list, list) {
977 		strsize1 = utf16_strsize(search_efivar->var.VariableName, 1024);
978 		strsize2 = utf16_strsize(del_var->VariableName, 1024);
979 		if (strsize1 == strsize2 &&
980 			!memcmp(&(search_efivar->var.VariableName),
981 				del_var->VariableName, strsize1) &&
982 			!efi_guidcmp(search_efivar->var.VendorGuid,
983 				del_var->VendorGuid)) {
984 			found = 1;
985 			break;
986 		}
987 	}
988 	if (!found) {
989 		spin_unlock_irq(&efivars->lock);
990 		return -EINVAL;
991 	}
992 	/* force the Attributes/DataSize to 0 to ensure deletion */
993 	del_var->Attributes = 0;
994 	del_var->DataSize = 0;
995 
996 	status = efivars->ops->set_variable(del_var->VariableName,
997 					    &del_var->VendorGuid,
998 					    del_var->Attributes,
999 					    del_var->DataSize,
1000 					    del_var->Data);
1001 
1002 	if (status != EFI_SUCCESS) {
1003 		printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
1004 			status);
1005 		spin_unlock_irq(&efivars->lock);
1006 		return -EIO;
1007 	}
1008 	list_del(&search_efivar->list);
1009 	/* We need to release this lock before unregistering. */
1010 	spin_unlock_irq(&efivars->lock);
1011 	efivar_unregister(search_efivar);
1012 
1013 	/* It's dead Jim.... */
1014 	return count;
1015 }
1016 
variable_is_present(efi_char16_t * variable_name,efi_guid_t * vendor)1017 static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor)
1018 {
1019 	struct efivar_entry *entry, *n;
1020 	struct efivars *efivars = &__efivars;
1021 	unsigned long strsize1, strsize2;
1022 	bool found = false;
1023 
1024 	strsize1 = utf16_strsize(variable_name, 1024);
1025 	list_for_each_entry_safe(entry, n, &efivars->list, list) {
1026 		strsize2 = utf16_strsize(entry->var.VariableName, 1024);
1027 		if (strsize1 == strsize2 &&
1028 			!memcmp(variable_name, &(entry->var.VariableName),
1029 				strsize2) &&
1030 			!efi_guidcmp(entry->var.VendorGuid,
1031 				*vendor)) {
1032 			found = true;
1033 			break;
1034 		}
1035 	}
1036 	return found;
1037 }
1038 
efivar_update_sysfs_entries(struct work_struct * work)1039 static void efivar_update_sysfs_entries(struct work_struct *work)
1040 {
1041 	struct efivars *efivars = &__efivars;
1042 	efi_guid_t vendor;
1043 	efi_char16_t *variable_name;
1044 	unsigned long variable_name_size = 1024;
1045 	efi_status_t status = EFI_NOT_FOUND;
1046 	bool found;
1047 
1048 	/* Add new sysfs entries */
1049 	while (1) {
1050 		variable_name = kzalloc(variable_name_size, GFP_KERNEL);
1051 		if (!variable_name) {
1052 			pr_err("efivars: Memory allocation failed.\n");
1053 			return;
1054 		}
1055 
1056 		spin_lock_irq(&efivars->lock);
1057 		found = false;
1058 		while (1) {
1059 			variable_name_size = 1024;
1060 			status = efivars->ops->get_next_variable(
1061 							&variable_name_size,
1062 							variable_name,
1063 							&vendor);
1064 			if (status != EFI_SUCCESS) {
1065 				break;
1066 			} else {
1067 				if (!variable_is_present(variable_name,
1068 				    &vendor)) {
1069 					found = true;
1070 					break;
1071 				}
1072 			}
1073 		}
1074 		spin_unlock_irq(&efivars->lock);
1075 
1076 		if (!found) {
1077 			kfree(variable_name);
1078 			break;
1079 		} else
1080 			efivar_create_sysfs_entry(efivars,
1081 						  variable_name_size,
1082 						  variable_name, &vendor);
1083 	}
1084 }
1085 
1086 /*
1087  * Returns the size of variable_name, in bytes, including the
1088  * terminating NULL character, or variable_name_size if no NULL
1089  * character is found among the first variable_name_size bytes.
1090  */
var_name_strnsize(efi_char16_t * variable_name,unsigned long variable_name_size)1091 static unsigned long var_name_strnsize(efi_char16_t *variable_name,
1092 				       unsigned long variable_name_size)
1093 {
1094 	unsigned long len;
1095 	efi_char16_t c;
1096 
1097 	/*
1098 	 * The variable name is, by definition, a NULL-terminated
1099 	 * string, so make absolutely sure that variable_name_size is
1100 	 * the value we expect it to be. If not, return the real size.
1101 	 */
1102 	for (len = 2; len <= variable_name_size; len += sizeof(c)) {
1103 		c = variable_name[(len / sizeof(c)) - 1];
1104 		if (!c)
1105 			break;
1106 	}
1107 
1108 	return min(len, variable_name_size);
1109 }
1110 
1111 /*
1112  * Let's not leave out systab information that snuck into
1113  * the efivars driver
1114  */
systab_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)1115 static ssize_t systab_show(struct kobject *kobj,
1116 			   struct kobj_attribute *attr, char *buf)
1117 {
1118 	char *str = buf;
1119 
1120 	if (!kobj || !buf)
1121 		return -EINVAL;
1122 
1123 	if (efi.mps != EFI_INVALID_TABLE_ADDR)
1124 		str += sprintf(str, "MPS=0x%lx\n", efi.mps);
1125 	if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
1126 		str += sprintf(str, "ACPI20=0x%lx\n", efi.acpi20);
1127 	if (efi.acpi != EFI_INVALID_TABLE_ADDR)
1128 		str += sprintf(str, "ACPI=0x%lx\n", efi.acpi);
1129 	if (efi.smbios != EFI_INVALID_TABLE_ADDR)
1130 		str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios);
1131 	if (efi.hcdp != EFI_INVALID_TABLE_ADDR)
1132 		str += sprintf(str, "HCDP=0x%lx\n", efi.hcdp);
1133 	if (efi.boot_info != EFI_INVALID_TABLE_ADDR)
1134 		str += sprintf(str, "BOOTINFO=0x%lx\n", efi.boot_info);
1135 	if (efi.uga != EFI_INVALID_TABLE_ADDR)
1136 		str += sprintf(str, "UGA=0x%lx\n", efi.uga);
1137 
1138 	return str - buf;
1139 }
1140 
1141 static struct kobj_attribute efi_attr_systab =
1142 			__ATTR(systab, 0400, systab_show, NULL);
1143 
1144 static struct attribute *efi_subsys_attrs[] = {
1145 	&efi_attr_systab.attr,
1146 	NULL,	/* maybe more in the future? */
1147 };
1148 
1149 static struct attribute_group efi_subsys_attr_group = {
1150 	.attrs = efi_subsys_attrs,
1151 };
1152 
1153 static struct kobject *efi_kobj;
1154 
1155 /*
1156  * efivar_create_sysfs_entry()
1157  * Requires:
1158  *    variable_name_size = number of bytes required to hold
1159  *                         variable_name (not counting the NULL
1160  *                         character at the end.
1161  *    efivars->lock is not held on entry or exit.
1162  * Returns 1 on failure, 0 on success
1163  */
1164 static int
efivar_create_sysfs_entry(struct efivars * efivars,unsigned long variable_name_size,efi_char16_t * variable_name,efi_guid_t * vendor_guid)1165 efivar_create_sysfs_entry(struct efivars *efivars,
1166 			  unsigned long variable_name_size,
1167 			  efi_char16_t *variable_name,
1168 			  efi_guid_t *vendor_guid)
1169 {
1170 	int i, short_name_size = variable_name_size / sizeof(efi_char16_t) + 38;
1171 	char *short_name;
1172 	struct efivar_entry *new_efivar;
1173 
1174 	short_name = kzalloc(short_name_size + 1, GFP_KERNEL);
1175 	new_efivar = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL);
1176 
1177 	if (!short_name || !new_efivar)  {
1178 		kfree(short_name);
1179 		kfree(new_efivar);
1180 		return 1;
1181 	}
1182 
1183 	new_efivar->efivars = efivars;
1184 	memcpy(new_efivar->var.VariableName, variable_name,
1185 		variable_name_size);
1186 	memcpy(&(new_efivar->var.VendorGuid), vendor_guid, sizeof(efi_guid_t));
1187 
1188 	/* Convert Unicode to normal chars (assume top bits are 0),
1189 	   ala UTF-8 */
1190 	for (i=0; i < (int)(variable_name_size / sizeof(efi_char16_t)); i++) {
1191 		short_name[i] = variable_name[i] & 0xFF;
1192 	}
1193 	/* This is ugly, but necessary to separate one vendor's
1194 	   private variables from another's.         */
1195 
1196 	*(short_name + strlen(short_name)) = '-';
1197 	efi_guid_unparse(vendor_guid, short_name + strlen(short_name));
1198 
1199 	new_efivar->kobj.kset = efivars->kset;
1200 	i = kobject_init_and_add(&new_efivar->kobj, &efivar_ktype, NULL,
1201 				 "%s", short_name);
1202 	if (i) {
1203 		kfree(short_name);
1204 		kfree(new_efivar);
1205 		return 1;
1206 	}
1207 
1208 	kobject_uevent(&new_efivar->kobj, KOBJ_ADD);
1209 	kfree(short_name);
1210 	short_name = NULL;
1211 
1212 	spin_lock_irq(&efivars->lock);
1213 	list_add(&new_efivar->list, &efivars->list);
1214 	spin_unlock_irq(&efivars->lock);
1215 
1216 	return 0;
1217 }
1218 
1219 static int
create_efivars_bin_attributes(struct efivars * efivars)1220 create_efivars_bin_attributes(struct efivars *efivars)
1221 {
1222 	struct bin_attribute *attr;
1223 	int error;
1224 
1225 	/* new_var */
1226 	attr = kzalloc(sizeof(*attr), GFP_KERNEL);
1227 	if (!attr)
1228 		return -ENOMEM;
1229 
1230 	attr->attr.name = "new_var";
1231 	attr->attr.mode = 0200;
1232 	attr->write = efivar_create;
1233 	attr->private = efivars;
1234 	efivars->new_var = attr;
1235 
1236 	/* del_var */
1237 	attr = kzalloc(sizeof(*attr), GFP_KERNEL);
1238 	if (!attr) {
1239 		error = -ENOMEM;
1240 		goto out_free;
1241 	}
1242 	attr->attr.name = "del_var";
1243 	attr->attr.mode = 0200;
1244 	attr->write = efivar_delete;
1245 	attr->private = efivars;
1246 	efivars->del_var = attr;
1247 
1248 	sysfs_bin_attr_init(efivars->new_var);
1249 	sysfs_bin_attr_init(efivars->del_var);
1250 
1251 	/* Register */
1252 	error = sysfs_create_bin_file(&efivars->kset->kobj,
1253 				      efivars->new_var);
1254 	if (error) {
1255 		printk(KERN_ERR "efivars: unable to create new_var sysfs file"
1256 			" due to error %d\n", error);
1257 		goto out_free;
1258 	}
1259 	error = sysfs_create_bin_file(&efivars->kset->kobj,
1260 				      efivars->del_var);
1261 	if (error) {
1262 		printk(KERN_ERR "efivars: unable to create del_var sysfs file"
1263 			" due to error %d\n", error);
1264 		sysfs_remove_bin_file(&efivars->kset->kobj,
1265 				      efivars->new_var);
1266 		goto out_free;
1267 	}
1268 
1269 	return 0;
1270 out_free:
1271 	kfree(efivars->del_var);
1272 	efivars->del_var = NULL;
1273 	kfree(efivars->new_var);
1274 	efivars->new_var = NULL;
1275 	return error;
1276 }
1277 
unregister_efivars(struct efivars * efivars)1278 void unregister_efivars(struct efivars *efivars)
1279 {
1280 	struct efivar_entry *entry, *n;
1281 
1282 	list_for_each_entry_safe(entry, n, &efivars->list, list) {
1283 		spin_lock_irq(&efivars->lock);
1284 		list_del(&entry->list);
1285 		spin_unlock_irq(&efivars->lock);
1286 		efivar_unregister(entry);
1287 	}
1288 	if (efivars->new_var)
1289 		sysfs_remove_bin_file(&efivars->kset->kobj, efivars->new_var);
1290 	if (efivars->del_var)
1291 		sysfs_remove_bin_file(&efivars->kset->kobj, efivars->del_var);
1292 	kfree(efivars->new_var);
1293 	kfree(efivars->del_var);
1294 	kset_unregister(efivars->kset);
1295 }
1296 EXPORT_SYMBOL_GPL(unregister_efivars);
1297 
1298 /*
1299  * Print a warning when duplicate EFI variables are encountered and
1300  * disable the sysfs workqueue since the firmware is buggy.
1301  */
dup_variable_bug(efi_char16_t * s16,efi_guid_t * vendor_guid,unsigned long len16)1302 static void dup_variable_bug(efi_char16_t *s16, efi_guid_t *vendor_guid,
1303 			     unsigned long len16)
1304 {
1305 	size_t i, len8 = len16 / sizeof(efi_char16_t);
1306 	char *s8;
1307 
1308 	s8 = kzalloc(len8, GFP_KERNEL);
1309 	if (!s8)
1310 		return;
1311 
1312 	for (i = 0; i < len8; i++)
1313 		s8[i] = s16[i];
1314 
1315 	printk(KERN_WARNING "efivars: duplicate variable: %s-%pUl\n",
1316 	       s8, vendor_guid);
1317 	kfree(s8);
1318 }
1319 
register_efivars(struct efivars * efivars,const struct efivar_operations * ops,struct kobject * parent_kobj)1320 int register_efivars(struct efivars *efivars,
1321 		     const struct efivar_operations *ops,
1322 		     struct kobject *parent_kobj)
1323 {
1324 	efi_status_t status = EFI_NOT_FOUND;
1325 	efi_guid_t vendor_guid;
1326 	efi_char16_t *variable_name;
1327 	unsigned long variable_name_size = 1024;
1328 	int error = 0;
1329 
1330 	variable_name = kzalloc(variable_name_size, GFP_KERNEL);
1331 	if (!variable_name) {
1332 		printk(KERN_ERR "efivars: Memory allocation failed.\n");
1333 		return -ENOMEM;
1334 	}
1335 
1336 	spin_lock_init(&efivars->lock);
1337 	INIT_LIST_HEAD(&efivars->list);
1338 	efivars->ops = ops;
1339 
1340 	efivars->kset = kset_create_and_add("vars", NULL, parent_kobj);
1341 	if (!efivars->kset) {
1342 		printk(KERN_ERR "efivars: Subsystem registration failed.\n");
1343 		error = -ENOMEM;
1344 		goto out;
1345 	}
1346 
1347 	/*
1348 	 * Per EFI spec, the maximum storage allocated for both
1349 	 * the variable name and variable data is 1024 bytes.
1350 	 */
1351 
1352 	do {
1353 		variable_name_size = 1024;
1354 
1355 		status = ops->get_next_variable(&variable_name_size,
1356 						variable_name,
1357 						&vendor_guid);
1358 		switch (status) {
1359 		case EFI_SUCCESS:
1360 			variable_name_size = var_name_strnsize(variable_name,
1361 							       variable_name_size);
1362 
1363 			/*
1364 			 * Some firmware implementations return the
1365 			 * same variable name on multiple calls to
1366 			 * get_next_variable(). Terminate the loop
1367 			 * immediately as there is no guarantee that
1368 			 * we'll ever see a different variable name,
1369 			 * and may end up looping here forever.
1370 			 */
1371 			if (variable_is_present(variable_name, &vendor_guid)) {
1372 				dup_variable_bug(variable_name, &vendor_guid,
1373 						 variable_name_size);
1374 				status = EFI_NOT_FOUND;
1375 				break;
1376 			}
1377 
1378 			efivar_create_sysfs_entry(efivars,
1379 						  variable_name_size,
1380 						  variable_name,
1381 						  &vendor_guid);
1382 			break;
1383 		case EFI_NOT_FOUND:
1384 			break;
1385 		default:
1386 			printk(KERN_WARNING "efivars: get_next_variable: status=%lx\n",
1387 				status);
1388 			status = EFI_NOT_FOUND;
1389 			break;
1390 		}
1391 	} while (status != EFI_NOT_FOUND);
1392 
1393 	error = create_efivars_bin_attributes(efivars);
1394 	if (error)
1395 		unregister_efivars(efivars);
1396 
1397 	if (!efivars_pstore_disable)
1398 		efivar_pstore_register(efivars);
1399 
1400 out:
1401 	kfree(variable_name);
1402 
1403 	return error;
1404 }
1405 EXPORT_SYMBOL_GPL(register_efivars);
1406 
1407 /*
1408  * For now we register the efi subsystem with the firmware subsystem
1409  * and the vars subsystem with the efi subsystem.  In the future, it
1410  * might make sense to split off the efi subsystem into its own
1411  * driver, but for now only efivars will register with it, so just
1412  * include it here.
1413  */
1414 
1415 static int __init
efivars_init(void)1416 efivars_init(void)
1417 {
1418 	int error = 0;
1419 
1420 	printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,
1421 	       EFIVARS_DATE);
1422 
1423 	if (!efi_enabled(EFI_RUNTIME_SERVICES))
1424 		return 0;
1425 
1426 	/* For now we'll register the efi directory at /sys/firmware/efi */
1427 	efi_kobj = kobject_create_and_add("efi", firmware_kobj);
1428 	if (!efi_kobj) {
1429 		printk(KERN_ERR "efivars: Firmware registration failed.\n");
1430 		return -ENOMEM;
1431 	}
1432 
1433 	ops.get_variable = efi.get_variable;
1434 	ops.set_variable = efi.set_variable;
1435 	ops.get_next_variable = efi.get_next_variable;
1436 	ops.query_variable_store = efi_query_variable_store;
1437 	error = register_efivars(&__efivars, &ops, efi_kobj);
1438 	if (error)
1439 		goto err_put;
1440 
1441 	/* Don't forget the systab entry */
1442 	error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
1443 	if (error) {
1444 		printk(KERN_ERR
1445 		       "efivars: Sysfs attribute export failed with error %d.\n",
1446 		       error);
1447 		goto err_unregister;
1448 	}
1449 
1450 	return 0;
1451 
1452 err_unregister:
1453 	unregister_efivars(&__efivars);
1454 err_put:
1455 	kobject_put(efi_kobj);
1456 	return error;
1457 }
1458 
1459 static void __exit
efivars_exit(void)1460 efivars_exit(void)
1461 {
1462 	if (efi_enabled(EFI_RUNTIME_SERVICES)) {
1463 		unregister_efivars(&__efivars);
1464 		kobject_put(efi_kobj);
1465 	}
1466 }
1467 
1468 module_init(efivars_init);
1469 module_exit(efivars_exit);
1470 
1471