aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware/efivars.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firmware/efivars.c')
-rw-r--r--drivers/firmware/efivars.c258
1 files changed, 131 insertions, 127 deletions
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index fe62aa392239..f4baa11d3644 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -80,6 +80,7 @@
80#include <linux/slab.h> 80#include <linux/slab.h>
81#include <linux/pstore.h> 81#include <linux/pstore.h>
82#include <linux/ctype.h> 82#include <linux/ctype.h>
83#include <linux/ucs2_string.h>
83 84
84#include <linux/fs.h> 85#include <linux/fs.h>
85#include <linux/ramfs.h> 86#include <linux/ramfs.h>
@@ -103,6 +104,11 @@ MODULE_VERSION(EFIVARS_VERSION);
103 */ 104 */
104#define GUID_LEN 36 105#define GUID_LEN 36
105 106
107static bool efivars_pstore_disable =
108 IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE);
109
110module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644);
111
106/* 112/*
107 * The maximum size of VariableName + Data = 1024 113 * The maximum size of VariableName + Data = 1024
108 * Therefore, it's reasonable to save that much 114 * Therefore, it's reasonable to save that much
@@ -165,51 +171,7 @@ efivar_create_sysfs_entry(struct efivars *efivars,
165 171
166static void efivar_update_sysfs_entries(struct work_struct *); 172static void efivar_update_sysfs_entries(struct work_struct *);
167static DECLARE_WORK(efivar_work, efivar_update_sysfs_entries); 173static DECLARE_WORK(efivar_work, efivar_update_sysfs_entries);
168 174static bool efivar_wq_enabled = true;
169/* Return the number of unicode characters in data */
170static unsigned long
171utf16_strnlen(efi_char16_t *s, size_t maxlength)
172{
173 unsigned long length = 0;
174
175 while (*s++ != 0 && length < maxlength)
176 length++;
177 return length;
178}
179
180static inline unsigned long
181utf16_strlen(efi_char16_t *s)
182{
183 return utf16_strnlen(s, ~0UL);
184}
185
186/*
187 * Return the number of bytes is the length of this string
188 * Note: this is NOT the same as the number of unicode characters
189 */
190static inline unsigned long
191utf16_strsize(efi_char16_t *data, unsigned long maxlength)
192{
193 return utf16_strnlen(data, maxlength/sizeof(efi_char16_t)) * sizeof(efi_char16_t);
194}
195
196static inline int
197utf16_strncmp(const efi_char16_t *a, const efi_char16_t *b, size_t len)
198{
199 while (1) {
200 if (len == 0)
201 return 0;
202 if (*a < *b)
203 return -1;
204 if (*a > *b)
205 return 1;
206 if (*a == 0) /* implies *b == 0 */
207 return 0;
208 a++;
209 b++;
210 len--;
211 }
212}
213 175
214static bool 176static bool
215validate_device_path(struct efi_variable *var, int match, u8 *buffer, 177validate_device_path(struct efi_variable *var, int match, u8 *buffer,
@@ -262,7 +224,7 @@ validate_load_option(struct efi_variable *var, int match, u8 *buffer,
262 u16 filepathlength; 224 u16 filepathlength;
263 int i, desclength = 0, namelen; 225 int i, desclength = 0, namelen;
264 226
265 namelen = utf16_strnlen(var->VariableName, sizeof(var->VariableName)); 227 namelen = ucs2_strnlen(var->VariableName, sizeof(var->VariableName));
266 228
267 /* Either "Boot" or "Driver" followed by four digits of hex */ 229 /* Either "Boot" or "Driver" followed by four digits of hex */
268 for (i = match; i < match+4; i++) { 230 for (i = match; i < match+4; i++) {
@@ -285,7 +247,7 @@ validate_load_option(struct efi_variable *var, int match, u8 *buffer,
285 * There's no stored length for the description, so it has to be 247 * There's no stored length for the description, so it has to be
286 * found by hand 248 * found by hand
287 */ 249 */
288 desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2; 250 desclength = ucs2_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2;
289 251
290 /* Each boot entry must have a descriptor */ 252 /* Each boot entry must have a descriptor */
291 if (!desclength) 253 if (!desclength)
@@ -430,24 +392,12 @@ static efi_status_t
430check_var_size_locked(struct efivars *efivars, u32 attributes, 392check_var_size_locked(struct efivars *efivars, u32 attributes,
431 unsigned long size) 393 unsigned long size)
432{ 394{
433 u64 storage_size, remaining_size, max_size;
434 efi_status_t status;
435 const struct efivar_operations *fops = efivars->ops; 395 const struct efivar_operations *fops = efivars->ops;
436 396
437 if (!efivars->ops->query_variable_info) 397 if (!efivars->ops->query_variable_store)
438 return EFI_UNSUPPORTED; 398 return EFI_UNSUPPORTED;
439 399
440 status = fops->query_variable_info(attributes, &storage_size, 400 return fops->query_variable_store(attributes, size);
441 &remaining_size, &max_size);
442
443 if (status != EFI_SUCCESS)
444 return status;
445
446 if (!storage_size || size > remaining_size || size > max_size ||
447 (remaining_size - size) < (storage_size / 2))
448 return EFI_OUT_OF_RESOURCES;
449
450 return status;
451} 401}
452 402
453 403
@@ -587,7 +537,7 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
587 spin_lock_irq(&efivars->lock); 537 spin_lock_irq(&efivars->lock);
588 538
589 status = check_var_size_locked(efivars, new_var->Attributes, 539 status = check_var_size_locked(efivars, new_var->Attributes,
590 new_var->DataSize + utf16_strsize(new_var->VariableName, 1024)); 540 new_var->DataSize + ucs2_strsize(new_var->VariableName, 1024));
591 541
592 if (status == EFI_SUCCESS || status == EFI_UNSUPPORTED) 542 if (status == EFI_SUCCESS || status == EFI_UNSUPPORTED)
593 status = efivars->ops->set_variable(new_var->VariableName, 543 status = efivars->ops->set_variable(new_var->VariableName,
@@ -765,7 +715,7 @@ static ssize_t efivarfs_file_write(struct file *file,
765 * QueryVariableInfo() isn't supported by the firmware. 715 * QueryVariableInfo() isn't supported by the firmware.
766 */ 716 */
767 717
768 varsize = datasize + utf16_strsize(var->var.VariableName, 1024); 718 varsize = datasize + ucs2_strsize(var->var.VariableName, 1024);
769 status = check_var_size(efivars, attributes, varsize); 719 status = check_var_size(efivars, attributes, varsize);
770 720
771 if (status != EFI_SUCCESS) { 721 if (status != EFI_SUCCESS) {
@@ -1217,7 +1167,7 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
1217 1167
1218 inode = NULL; 1168 inode = NULL;
1219 1169
1220 len = utf16_strlen(entry->var.VariableName); 1170 len = ucs2_strlen(entry->var.VariableName);
1221 1171
1222 /* name, plus '-', plus GUID, plus NUL*/ 1172 /* name, plus '-', plus GUID, plus NUL*/
1223 name = kmalloc(len + 1 + GUID_LEN + 1, GFP_ATOMIC); 1173 name = kmalloc(len + 1 + GUID_LEN + 1, GFP_ATOMIC);
@@ -1309,9 +1259,7 @@ static const struct inode_operations efivarfs_dir_inode_operations = {
1309 .create = efivarfs_create, 1259 .create = efivarfs_create,
1310}; 1260};
1311 1261
1312static struct pstore_info efi_pstore_info; 1262#ifdef CONFIG_EFI_VARS_PSTORE
1313
1314#ifdef CONFIG_PSTORE
1315 1263
1316static int efi_pstore_open(struct pstore_info *psi) 1264static int efi_pstore_open(struct pstore_info *psi)
1317{ 1265{
@@ -1441,7 +1389,7 @@ static int efi_pstore_write(enum pstore_type_id type,
1441 1389
1442 spin_unlock_irqrestore(&efivars->lock, flags); 1390 spin_unlock_irqrestore(&efivars->lock, flags);
1443 1391
1444 if (reason == KMSG_DUMP_OOPS) 1392 if (reason == KMSG_DUMP_OOPS && efivar_wq_enabled)
1445 schedule_work(&efivar_work); 1393 schedule_work(&efivar_work);
1446 1394
1447 *id = part; 1395 *id = part;
@@ -1477,8 +1425,8 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
1477 1425
1478 if (efi_guidcmp(entry->var.VendorGuid, vendor)) 1426 if (efi_guidcmp(entry->var.VendorGuid, vendor))
1479 continue; 1427 continue;
1480 if (utf16_strncmp(entry->var.VariableName, efi_name, 1428 if (ucs2_strncmp(entry->var.VariableName, efi_name,
1481 utf16_strlen(efi_name))) { 1429 ucs2_strlen(efi_name))) {
1482 /* 1430 /*
1483 * Check if an old format, 1431 * Check if an old format,
1484 * which doesn't support holding 1432 * which doesn't support holding
@@ -1490,8 +1438,8 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
1490 for (i = 0; i < DUMP_NAME_LEN; i++) 1438 for (i = 0; i < DUMP_NAME_LEN; i++)
1491 efi_name_old[i] = name_old[i]; 1439 efi_name_old[i] = name_old[i];
1492 1440
1493 if (utf16_strncmp(entry->var.VariableName, efi_name_old, 1441 if (ucs2_strncmp(entry->var.VariableName, efi_name_old,
1494 utf16_strlen(efi_name_old))) 1442 ucs2_strlen(efi_name_old)))
1495 continue; 1443 continue;
1496 } 1444 }
1497 1445
@@ -1514,38 +1462,6 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
1514 1462
1515 return 0; 1463 return 0;
1516} 1464}
1517#else
1518static int efi_pstore_open(struct pstore_info *psi)
1519{
1520 return 0;
1521}
1522
1523static int efi_pstore_close(struct pstore_info *psi)
1524{
1525 return 0;
1526}
1527
1528static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, int *count,
1529 struct timespec *timespec,
1530 char **buf, struct pstore_info *psi)
1531{
1532 return -1;
1533}
1534
1535static int efi_pstore_write(enum pstore_type_id type,
1536 enum kmsg_dump_reason reason, u64 *id,
1537 unsigned int part, int count, size_t size,
1538 struct pstore_info *psi)
1539{
1540 return 0;
1541}
1542
1543static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
1544 struct timespec time, struct pstore_info *psi)
1545{
1546 return 0;
1547}
1548#endif
1549 1465
1550static struct pstore_info efi_pstore_info = { 1466static struct pstore_info efi_pstore_info = {
1551 .owner = THIS_MODULE, 1467 .owner = THIS_MODULE,
@@ -1557,6 +1473,24 @@ static struct pstore_info efi_pstore_info = {
1557 .erase = efi_pstore_erase, 1473 .erase = efi_pstore_erase,
1558}; 1474};
1559 1475
1476static void efivar_pstore_register(struct efivars *efivars)
1477{
1478 efivars->efi_pstore_info = efi_pstore_info;
1479 efivars->efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
1480 if (efivars->efi_pstore_info.buf) {
1481 efivars->efi_pstore_info.bufsize = 1024;
1482 efivars->efi_pstore_info.data = efivars;
1483 spin_lock_init(&efivars->efi_pstore_info.buf_lock);
1484 pstore_register(&efivars->efi_pstore_info);
1485 }
1486}
1487#else
1488static void efivar_pstore_register(struct efivars *efivars)
1489{
1490 return;
1491}
1492#endif
1493
1560static ssize_t efivar_create(struct file *filp, struct kobject *kobj, 1494static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
1561 struct bin_attribute *bin_attr, 1495 struct bin_attribute *bin_attr,
1562 char *buf, loff_t pos, size_t count) 1496 char *buf, loff_t pos, size_t count)
@@ -1583,8 +1517,8 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
1583 * Does this variable already exist? 1517 * Does this variable already exist?
1584 */ 1518 */
1585 list_for_each_entry_safe(search_efivar, n, &efivars->list, list) { 1519 list_for_each_entry_safe(search_efivar, n, &efivars->list, list) {
1586 strsize1 = utf16_strsize(search_efivar->var.VariableName, 1024); 1520 strsize1 = ucs2_strsize(search_efivar->var.VariableName, 1024);
1587 strsize2 = utf16_strsize(new_var->VariableName, 1024); 1521 strsize2 = ucs2_strsize(new_var->VariableName, 1024);
1588 if (strsize1 == strsize2 && 1522 if (strsize1 == strsize2 &&
1589 !memcmp(&(search_efivar->var.VariableName), 1523 !memcmp(&(search_efivar->var.VariableName),
1590 new_var->VariableName, strsize1) && 1524 new_var->VariableName, strsize1) &&
@@ -1600,7 +1534,7 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
1600 } 1534 }
1601 1535
1602 status = check_var_size_locked(efivars, new_var->Attributes, 1536 status = check_var_size_locked(efivars, new_var->Attributes,
1603 new_var->DataSize + utf16_strsize(new_var->VariableName, 1024)); 1537 new_var->DataSize + ucs2_strsize(new_var->VariableName, 1024));
1604 1538
1605 if (status && status != EFI_UNSUPPORTED) { 1539 if (status && status != EFI_UNSUPPORTED) {
1606 spin_unlock_irq(&efivars->lock); 1540 spin_unlock_irq(&efivars->lock);
@@ -1624,7 +1558,7 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
1624 1558
1625 /* Create the entry in sysfs. Locking is not required here */ 1559 /* Create the entry in sysfs. Locking is not required here */
1626 status = efivar_create_sysfs_entry(efivars, 1560 status = efivar_create_sysfs_entry(efivars,
1627 utf16_strsize(new_var->VariableName, 1561 ucs2_strsize(new_var->VariableName,
1628 1024), 1562 1024),
1629 new_var->VariableName, 1563 new_var->VariableName,
1630 &new_var->VendorGuid); 1564 &new_var->VendorGuid);
@@ -1654,8 +1588,8 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
1654 * Does this variable already exist? 1588 * Does this variable already exist?
1655 */ 1589 */
1656 list_for_each_entry_safe(search_efivar, n, &efivars->list, list) { 1590 list_for_each_entry_safe(search_efivar, n, &efivars->list, list) {
1657 strsize1 = utf16_strsize(search_efivar->var.VariableName, 1024); 1591 strsize1 = ucs2_strsize(search_efivar->var.VariableName, 1024);
1658 strsize2 = utf16_strsize(del_var->VariableName, 1024); 1592 strsize2 = ucs2_strsize(del_var->VariableName, 1024);
1659 if (strsize1 == strsize2 && 1593 if (strsize1 == strsize2 &&
1660 !memcmp(&(search_efivar->var.VariableName), 1594 !memcmp(&(search_efivar->var.VariableName),
1661 del_var->VariableName, strsize1) && 1595 del_var->VariableName, strsize1) &&
@@ -1694,16 +1628,17 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
1694 return count; 1628 return count;
1695} 1629}
1696 1630
1697static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor) 1631static bool variable_is_present(struct efivars *efivars,
1632 efi_char16_t *variable_name,
1633 efi_guid_t *vendor)
1698{ 1634{
1699 struct efivar_entry *entry, *n; 1635 struct efivar_entry *entry, *n;
1700 struct efivars *efivars = &__efivars;
1701 unsigned long strsize1, strsize2; 1636 unsigned long strsize1, strsize2;
1702 bool found = false; 1637 bool found = false;
1703 1638
1704 strsize1 = utf16_strsize(variable_name, 1024); 1639 strsize1 = ucs2_strsize(variable_name, 1024);
1705 list_for_each_entry_safe(entry, n, &efivars->list, list) { 1640 list_for_each_entry_safe(entry, n, &efivars->list, list) {
1706 strsize2 = utf16_strsize(entry->var.VariableName, 1024); 1641 strsize2 = ucs2_strsize(entry->var.VariableName, 1024);
1707 if (strsize1 == strsize2 && 1642 if (strsize1 == strsize2 &&
1708 !memcmp(variable_name, &(entry->var.VariableName), 1643 !memcmp(variable_name, &(entry->var.VariableName),
1709 strsize2) && 1644 strsize2) &&
@@ -1716,6 +1651,31 @@ static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor)
1716 return found; 1651 return found;
1717} 1652}
1718 1653
1654/*
1655 * Returns the size of variable_name, in bytes, including the
1656 * terminating NULL character, or variable_name_size if no NULL
1657 * character is found among the first variable_name_size bytes.
1658 */
1659static unsigned long var_name_strnsize(efi_char16_t *variable_name,
1660 unsigned long variable_name_size)
1661{
1662 unsigned long len;
1663 efi_char16_t c;
1664
1665 /*
1666 * The variable name is, by definition, a NULL-terminated
1667 * string, so make absolutely sure that variable_name_size is
1668 * the value we expect it to be. If not, return the real size.
1669 */
1670 for (len = 2; len <= variable_name_size; len += sizeof(c)) {
1671 c = variable_name[(len / sizeof(c)) - 1];
1672 if (!c)
1673 break;
1674 }
1675
1676 return min(len, variable_name_size);
1677}
1678
1719static void efivar_update_sysfs_entries(struct work_struct *work) 1679static void efivar_update_sysfs_entries(struct work_struct *work)
1720{ 1680{
1721 struct efivars *efivars = &__efivars; 1681 struct efivars *efivars = &__efivars;
@@ -1744,8 +1704,8 @@ static void efivar_update_sysfs_entries(struct work_struct *work)
1744 if (status != EFI_SUCCESS) { 1704 if (status != EFI_SUCCESS) {
1745 break; 1705 break;
1746 } else { 1706 } else {
1747 if (!variable_is_present(variable_name, 1707 if (!variable_is_present(efivars,
1748 &vendor)) { 1708 variable_name, &vendor)) {
1749 found = true; 1709 found = true;
1750 break; 1710 break;
1751 } 1711 }
@@ -1756,10 +1716,13 @@ static void efivar_update_sysfs_entries(struct work_struct *work)
1756 if (!found) { 1716 if (!found) {
1757 kfree(variable_name); 1717 kfree(variable_name);
1758 break; 1718 break;
1759 } else 1719 } else {
1720 variable_name_size = var_name_strnsize(variable_name,
1721 variable_name_size);
1760 efivar_create_sysfs_entry(efivars, 1722 efivar_create_sysfs_entry(efivars,
1761 variable_name_size, 1723 variable_name_size,
1762 variable_name, &vendor); 1724 variable_name, &vendor);
1725 }
1763 } 1726 }
1764} 1727}
1765 1728
@@ -1958,6 +1921,35 @@ void unregister_efivars(struct efivars *efivars)
1958} 1921}
1959EXPORT_SYMBOL_GPL(unregister_efivars); 1922EXPORT_SYMBOL_GPL(unregister_efivars);
1960 1923
1924/*
1925 * Print a warning when duplicate EFI variables are encountered and
1926 * disable the sysfs workqueue since the firmware is buggy.
1927 */
1928static void dup_variable_bug(efi_char16_t *s16, efi_guid_t *vendor_guid,
1929 unsigned long len16)
1930{
1931 size_t i, len8 = len16 / sizeof(efi_char16_t);
1932 char *s8;
1933
1934 /*
1935 * Disable the workqueue since the algorithm it uses for
1936 * detecting new variables won't work with this buggy
1937 * implementation of GetNextVariableName().
1938 */
1939 efivar_wq_enabled = false;
1940
1941 s8 = kzalloc(len8, GFP_KERNEL);
1942 if (!s8)
1943 return;
1944
1945 for (i = 0; i < len8; i++)
1946 s8[i] = s16[i];
1947
1948 printk(KERN_WARNING "efivars: duplicate variable: %s-%pUl\n",
1949 s8, vendor_guid);
1950 kfree(s8);
1951}
1952
1961int register_efivars(struct efivars *efivars, 1953int register_efivars(struct efivars *efivars,
1962 const struct efivar_operations *ops, 1954 const struct efivar_operations *ops,
1963 struct kobject *parent_kobj) 1955 struct kobject *parent_kobj)
@@ -2006,6 +1998,25 @@ int register_efivars(struct efivars *efivars,
2006 &vendor_guid); 1998 &vendor_guid);
2007 switch (status) { 1999 switch (status) {
2008 case EFI_SUCCESS: 2000 case EFI_SUCCESS:
2001 variable_name_size = var_name_strnsize(variable_name,
2002 variable_name_size);
2003
2004 /*
2005 * Some firmware implementations return the
2006 * same variable name on multiple calls to
2007 * get_next_variable(). Terminate the loop
2008 * immediately as there is no guarantee that
2009 * we'll ever see a different variable name,
2010 * and may end up looping here forever.
2011 */
2012 if (variable_is_present(efivars, variable_name,
2013 &vendor_guid)) {
2014 dup_variable_bug(variable_name, &vendor_guid,
2015 variable_name_size);
2016 status = EFI_NOT_FOUND;
2017 break;
2018 }
2019
2009 efivar_create_sysfs_entry(efivars, 2020 efivar_create_sysfs_entry(efivars,
2010 variable_name_size, 2021 variable_name_size,
2011 variable_name, 2022 variable_name,
@@ -2025,15 +2036,8 @@ int register_efivars(struct efivars *efivars,
2025 if (error) 2036 if (error)
2026 unregister_efivars(efivars); 2037 unregister_efivars(efivars);
2027 2038
2028 efivars->efi_pstore_info = efi_pstore_info; 2039 if (!efivars_pstore_disable)
2029 2040 efivar_pstore_register(efivars);
2030 efivars->efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
2031 if (efivars->efi_pstore_info.buf) {
2032 efivars->efi_pstore_info.bufsize = 1024;
2033 efivars->efi_pstore_info.data = efivars;
2034 spin_lock_init(&efivars->efi_pstore_info.buf_lock);
2035 pstore_register(&efivars->efi_pstore_info);
2036 }
2037 2041
2038 register_filesystem(&efivarfs_type); 2042 register_filesystem(&efivarfs_type);
2039 2043
@@ -2073,7 +2077,7 @@ efivars_init(void)
2073 ops.get_variable = efi.get_variable; 2077 ops.get_variable = efi.get_variable;
2074 ops.set_variable = efi.set_variable; 2078 ops.set_variable = efi.set_variable;
2075 ops.get_next_variable = efi.get_next_variable; 2079 ops.get_next_variable = efi.get_next_variable;
2076 ops.query_variable_info = efi.query_variable_info; 2080 ops.query_variable_store = efi_query_variable_store;
2077 2081
2078 error = register_efivars(&__efivars, &ops, efi_kobj); 2082 error = register_efivars(&__efivars, &ops, efi_kobj);
2079 if (error) 2083 if (error)