Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Originally from efivars.c
0004  *
0005  * Copyright (C) 2001,2003,2004 Dell <Matt_Domsch@dell.com>
0006  * Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com>
0007  */
0008 
0009 #include <linux/capability.h>
0010 #include <linux/types.h>
0011 #include <linux/errno.h>
0012 #include <linux/init.h>
0013 #include <linux/mm.h>
0014 #include <linux/module.h>
0015 #include <linux/string.h>
0016 #include <linux/smp.h>
0017 #include <linux/efi.h>
0018 #include <linux/device.h>
0019 #include <linux/slab.h>
0020 #include <linux/ctype.h>
0021 #include <linux/ucs2_string.h>
0022 
0023 #include "internal.h"
0024 
0025 MODULE_IMPORT_NS(EFIVAR);
0026 
0027 static bool
0028 validate_device_path(efi_char16_t *var_name, int match, u8 *buffer,
0029              unsigned long len)
0030 {
0031     struct efi_generic_dev_path *node;
0032     int offset = 0;
0033 
0034     node = (struct efi_generic_dev_path *)buffer;
0035 
0036     if (len < sizeof(*node))
0037         return false;
0038 
0039     while (offset <= len - sizeof(*node) &&
0040            node->length >= sizeof(*node) &&
0041         node->length <= len - offset) {
0042         offset += node->length;
0043 
0044         if ((node->type == EFI_DEV_END_PATH ||
0045              node->type == EFI_DEV_END_PATH2) &&
0046             node->sub_type == EFI_DEV_END_ENTIRE)
0047             return true;
0048 
0049         node = (struct efi_generic_dev_path *)(buffer + offset);
0050     }
0051 
0052     /*
0053      * If we're here then either node->length pointed past the end
0054      * of the buffer or we reached the end of the buffer without
0055      * finding a device path end node.
0056      */
0057     return false;
0058 }
0059 
0060 static bool
0061 validate_boot_order(efi_char16_t *var_name, int match, u8 *buffer,
0062             unsigned long len)
0063 {
0064     /* An array of 16-bit integers */
0065     if ((len % 2) != 0)
0066         return false;
0067 
0068     return true;
0069 }
0070 
0071 static bool
0072 validate_load_option(efi_char16_t *var_name, int match, u8 *buffer,
0073              unsigned long len)
0074 {
0075     u16 filepathlength;
0076     int i, desclength = 0, namelen;
0077 
0078     namelen = ucs2_strnlen(var_name, EFI_VAR_NAME_LEN);
0079 
0080     /* Either "Boot" or "Driver" followed by four digits of hex */
0081     for (i = match; i < match+4; i++) {
0082         if (var_name[i] > 127 ||
0083             hex_to_bin(var_name[i] & 0xff) < 0)
0084             return true;
0085     }
0086 
0087     /* Reject it if there's 4 digits of hex and then further content */
0088     if (namelen > match + 4)
0089         return false;
0090 
0091     /* A valid entry must be at least 8 bytes */
0092     if (len < 8)
0093         return false;
0094 
0095     filepathlength = buffer[4] | buffer[5] << 8;
0096 
0097     /*
0098      * There's no stored length for the description, so it has to be
0099      * found by hand
0100      */
0101     desclength = ucs2_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2;
0102 
0103     /* Each boot entry must have a descriptor */
0104     if (!desclength)
0105         return false;
0106 
0107     /*
0108      * If the sum of the length of the description, the claimed filepath
0109      * length and the original header are greater than the length of the
0110      * variable, it's malformed
0111      */
0112     if ((desclength + filepathlength + 6) > len)
0113         return false;
0114 
0115     /*
0116      * And, finally, check the filepath
0117      */
0118     return validate_device_path(var_name, match, buffer + desclength + 6,
0119                     filepathlength);
0120 }
0121 
0122 static bool
0123 validate_uint16(efi_char16_t *var_name, int match, u8 *buffer,
0124         unsigned long len)
0125 {
0126     /* A single 16-bit integer */
0127     if (len != 2)
0128         return false;
0129 
0130     return true;
0131 }
0132 
0133 static bool
0134 validate_ascii_string(efi_char16_t *var_name, int match, u8 *buffer,
0135               unsigned long len)
0136 {
0137     int i;
0138 
0139     for (i = 0; i < len; i++) {
0140         if (buffer[i] > 127)
0141             return false;
0142 
0143         if (buffer[i] == 0)
0144             return true;
0145     }
0146 
0147     return false;
0148 }
0149 
0150 struct variable_validate {
0151     efi_guid_t vendor;
0152     char *name;
0153     bool (*validate)(efi_char16_t *var_name, int match, u8 *data,
0154              unsigned long len);
0155 };
0156 
0157 /*
0158  * This is the list of variables we need to validate, as well as the
0159  * whitelist for what we think is safe not to default to immutable.
0160  *
0161  * If it has a validate() method that's not NULL, it'll go into the
0162  * validation routine.  If not, it is assumed valid, but still used for
0163  * whitelisting.
0164  *
0165  * Note that it's sorted by {vendor,name}, but globbed names must come after
0166  * any other name with the same prefix.
0167  */
0168 static const struct variable_validate variable_validate[] = {
0169     { EFI_GLOBAL_VARIABLE_GUID, "BootNext", validate_uint16 },
0170     { EFI_GLOBAL_VARIABLE_GUID, "BootOrder", validate_boot_order },
0171     { EFI_GLOBAL_VARIABLE_GUID, "Boot*", validate_load_option },
0172     { EFI_GLOBAL_VARIABLE_GUID, "DriverOrder", validate_boot_order },
0173     { EFI_GLOBAL_VARIABLE_GUID, "Driver*", validate_load_option },
0174     { EFI_GLOBAL_VARIABLE_GUID, "ConIn", validate_device_path },
0175     { EFI_GLOBAL_VARIABLE_GUID, "ConInDev", validate_device_path },
0176     { EFI_GLOBAL_VARIABLE_GUID, "ConOut", validate_device_path },
0177     { EFI_GLOBAL_VARIABLE_GUID, "ConOutDev", validate_device_path },
0178     { EFI_GLOBAL_VARIABLE_GUID, "ErrOut", validate_device_path },
0179     { EFI_GLOBAL_VARIABLE_GUID, "ErrOutDev", validate_device_path },
0180     { EFI_GLOBAL_VARIABLE_GUID, "Lang", validate_ascii_string },
0181     { EFI_GLOBAL_VARIABLE_GUID, "OsIndications", NULL },
0182     { EFI_GLOBAL_VARIABLE_GUID, "PlatformLang", validate_ascii_string },
0183     { EFI_GLOBAL_VARIABLE_GUID, "Timeout", validate_uint16 },
0184     { LINUX_EFI_CRASH_GUID, "*", NULL },
0185     { NULL_GUID, "", NULL },
0186 };
0187 
0188 /*
0189  * Check if @var_name matches the pattern given in @match_name.
0190  *
0191  * @var_name: an array of @len non-NUL characters.
0192  * @match_name: a NUL-terminated pattern string, optionally ending in "*". A
0193  *              final "*" character matches any trailing characters @var_name,
0194  *              including the case when there are none left in @var_name.
0195  * @match: on output, the number of non-wildcard characters in @match_name
0196  *         that @var_name matches, regardless of the return value.
0197  * @return: whether @var_name fully matches @match_name.
0198  */
0199 static bool
0200 variable_matches(const char *var_name, size_t len, const char *match_name,
0201          int *match)
0202 {
0203     for (*match = 0; ; (*match)++) {
0204         char c = match_name[*match];
0205 
0206         switch (c) {
0207         case '*':
0208             /* Wildcard in @match_name means we've matched. */
0209             return true;
0210 
0211         case '\0':
0212             /* @match_name has ended. Has @var_name too? */
0213             return (*match == len);
0214 
0215         default:
0216             /*
0217              * We've reached a non-wildcard char in @match_name.
0218              * Continue only if there's an identical character in
0219              * @var_name.
0220              */
0221             if (*match < len && c == var_name[*match])
0222                 continue;
0223             return false;
0224         }
0225     }
0226 }
0227 
0228 bool
0229 efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data,
0230         unsigned long data_size)
0231 {
0232     int i;
0233     unsigned long utf8_size;
0234     u8 *utf8_name;
0235 
0236     utf8_size = ucs2_utf8size(var_name);
0237     utf8_name = kmalloc(utf8_size + 1, GFP_KERNEL);
0238     if (!utf8_name)
0239         return false;
0240 
0241     ucs2_as_utf8(utf8_name, var_name, utf8_size);
0242     utf8_name[utf8_size] = '\0';
0243 
0244     for (i = 0; variable_validate[i].name[0] != '\0'; i++) {
0245         const char *name = variable_validate[i].name;
0246         int match = 0;
0247 
0248         if (efi_guidcmp(vendor, variable_validate[i].vendor))
0249             continue;
0250 
0251         if (variable_matches(utf8_name, utf8_size+1, name, &match)) {
0252             if (variable_validate[i].validate == NULL)
0253                 break;
0254             kfree(utf8_name);
0255             return variable_validate[i].validate(var_name, match,
0256                                  data, data_size);
0257         }
0258     }
0259     kfree(utf8_name);
0260     return true;
0261 }
0262 
0263 bool
0264 efivar_variable_is_removable(efi_guid_t vendor, const char *var_name,
0265                  size_t len)
0266 {
0267     int i;
0268     bool found = false;
0269     int match = 0;
0270 
0271     /*
0272      * Check if our variable is in the validated variables list
0273      */
0274     for (i = 0; variable_validate[i].name[0] != '\0'; i++) {
0275         if (efi_guidcmp(variable_validate[i].vendor, vendor))
0276             continue;
0277 
0278         if (variable_matches(var_name, len,
0279                      variable_validate[i].name, &match)) {
0280             found = true;
0281             break;
0282         }
0283     }
0284 
0285     /*
0286      * If it's in our list, it is removable.
0287      */
0288     return found;
0289 }
0290 
0291 static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor,
0292                 struct list_head *head)
0293 {
0294     struct efivar_entry *entry, *n;
0295     unsigned long strsize1, strsize2;
0296     bool found = false;
0297 
0298     strsize1 = ucs2_strsize(variable_name, 1024);
0299     list_for_each_entry_safe(entry, n, head, list) {
0300         strsize2 = ucs2_strsize(entry->var.VariableName, 1024);
0301         if (strsize1 == strsize2 &&
0302             !memcmp(variable_name, &(entry->var.VariableName),
0303                 strsize2) &&
0304             !efi_guidcmp(entry->var.VendorGuid,
0305                 *vendor)) {
0306             found = true;
0307             break;
0308         }
0309     }
0310     return found;
0311 }
0312 
0313 /*
0314  * Returns the size of variable_name, in bytes, including the
0315  * terminating NULL character, or variable_name_size if no NULL
0316  * character is found among the first variable_name_size bytes.
0317  */
0318 static unsigned long var_name_strnsize(efi_char16_t *variable_name,
0319                        unsigned long variable_name_size)
0320 {
0321     unsigned long len;
0322     efi_char16_t c;
0323 
0324     /*
0325      * The variable name is, by definition, a NULL-terminated
0326      * string, so make absolutely sure that variable_name_size is
0327      * the value we expect it to be. If not, return the real size.
0328      */
0329     for (len = 2; len <= variable_name_size; len += sizeof(c)) {
0330         c = variable_name[(len / sizeof(c)) - 1];
0331         if (!c)
0332             break;
0333     }
0334 
0335     return min(len, variable_name_size);
0336 }
0337 
0338 /*
0339  * Print a warning when duplicate EFI variables are encountered and
0340  * disable the sysfs workqueue since the firmware is buggy.
0341  */
0342 static void dup_variable_bug(efi_char16_t *str16, efi_guid_t *vendor_guid,
0343                  unsigned long len16)
0344 {
0345     size_t i, len8 = len16 / sizeof(efi_char16_t);
0346     char *str8;
0347 
0348     str8 = kzalloc(len8, GFP_KERNEL);
0349     if (!str8)
0350         return;
0351 
0352     for (i = 0; i < len8; i++)
0353         str8[i] = str16[i];
0354 
0355     printk(KERN_WARNING "efivars: duplicate variable: %s-%pUl\n",
0356            str8, vendor_guid);
0357     kfree(str8);
0358 }
0359 
0360 /**
0361  * efivar_init - build the initial list of EFI variables
0362  * @func: callback function to invoke for every variable
0363  * @data: function-specific data to pass to @func
0364  * @duplicates: error if we encounter duplicates on @head?
0365  * @head: initialised head of variable list
0366  *
0367  * Get every EFI variable from the firmware and invoke @func. @func
0368  * should call efivar_entry_add() to build the list of variables.
0369  *
0370  * Returns 0 on success, or a kernel error code on failure.
0371  */
0372 int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
0373         void *data, bool duplicates, struct list_head *head)
0374 {
0375     unsigned long variable_name_size = 1024;
0376     efi_char16_t *variable_name;
0377     efi_status_t status;
0378     efi_guid_t vendor_guid;
0379     int err = 0;
0380 
0381     variable_name = kzalloc(variable_name_size, GFP_KERNEL);
0382     if (!variable_name) {
0383         printk(KERN_ERR "efivars: Memory allocation failed.\n");
0384         return -ENOMEM;
0385     }
0386 
0387     err = efivar_lock();
0388     if (err)
0389         goto free;
0390 
0391     /*
0392      * Per EFI spec, the maximum storage allocated for both
0393      * the variable name and variable data is 1024 bytes.
0394      */
0395 
0396     do {
0397         variable_name_size = 1024;
0398 
0399         status = efivar_get_next_variable(&variable_name_size,
0400                           variable_name,
0401                           &vendor_guid);
0402         switch (status) {
0403         case EFI_SUCCESS:
0404             variable_name_size = var_name_strnsize(variable_name,
0405                                    variable_name_size);
0406 
0407             /*
0408              * Some firmware implementations return the
0409              * same variable name on multiple calls to
0410              * get_next_variable(). Terminate the loop
0411              * immediately as there is no guarantee that
0412              * we'll ever see a different variable name,
0413              * and may end up looping here forever.
0414              */
0415             if (duplicates &&
0416                 variable_is_present(variable_name, &vendor_guid,
0417                         head)) {
0418                 dup_variable_bug(variable_name, &vendor_guid,
0419                          variable_name_size);
0420                 status = EFI_NOT_FOUND;
0421             } else {
0422                 err = func(variable_name, vendor_guid,
0423                        variable_name_size, data);
0424                 if (err)
0425                     status = EFI_NOT_FOUND;
0426             }
0427             break;
0428         case EFI_UNSUPPORTED:
0429             err = -EOPNOTSUPP;
0430             status = EFI_NOT_FOUND;
0431             break;
0432         case EFI_NOT_FOUND:
0433             break;
0434         default:
0435             printk(KERN_WARNING "efivars: get_next_variable: status=%lx\n",
0436                 status);
0437             status = EFI_NOT_FOUND;
0438             break;
0439         }
0440 
0441     } while (status != EFI_NOT_FOUND);
0442 
0443     efivar_unlock();
0444 free:
0445     kfree(variable_name);
0446 
0447     return err;
0448 }
0449 
0450 /**
0451  * efivar_entry_add - add entry to variable list
0452  * @entry: entry to add to list
0453  * @head: list head
0454  *
0455  * Returns 0 on success, or a kernel error code on failure.
0456  */
0457 int efivar_entry_add(struct efivar_entry *entry, struct list_head *head)
0458 {
0459     int err;
0460 
0461     err = efivar_lock();
0462     if (err)
0463         return err;
0464     list_add(&entry->list, head);
0465     efivar_unlock();
0466 
0467     return 0;
0468 }
0469 
0470 /**
0471  * __efivar_entry_add - add entry to variable list
0472  * @entry: entry to add to list
0473  * @head: list head
0474  */
0475 void __efivar_entry_add(struct efivar_entry *entry, struct list_head *head)
0476 {
0477     list_add(&entry->list, head);
0478 }
0479 
0480 /**
0481  * efivar_entry_remove - remove entry from variable list
0482  * @entry: entry to remove from list
0483  *
0484  * Returns 0 on success, or a kernel error code on failure.
0485  */
0486 void efivar_entry_remove(struct efivar_entry *entry)
0487 {
0488     list_del(&entry->list);
0489 }
0490 
0491 /*
0492  * efivar_entry_list_del_unlock - remove entry from variable list
0493  * @entry: entry to remove
0494  *
0495  * Remove @entry from the variable list and release the list lock.
0496  *
0497  * NOTE: slightly weird locking semantics here - we expect to be
0498  * called with the efivars lock already held, and we release it before
0499  * returning. This is because this function is usually called after
0500  * set_variable() while the lock is still held.
0501  */
0502 static void efivar_entry_list_del_unlock(struct efivar_entry *entry)
0503 {
0504     list_del(&entry->list);
0505     efivar_unlock();
0506 }
0507 
0508 /**
0509  * efivar_entry_delete - delete variable and remove entry from list
0510  * @entry: entry containing variable to delete
0511  *
0512  * Delete the variable from the firmware and remove @entry from the
0513  * variable list. It is the caller's responsibility to free @entry
0514  * once we return.
0515  *
0516  * Returns 0 on success, -EINTR if we can't grab the semaphore,
0517  * converted EFI status code if set_variable() fails.
0518  */
0519 int efivar_entry_delete(struct efivar_entry *entry)
0520 {
0521     efi_status_t status;
0522     int err;
0523 
0524     err = efivar_lock();
0525     if (err)
0526         return err;
0527 
0528     status = efivar_set_variable_locked(entry->var.VariableName,
0529                         &entry->var.VendorGuid,
0530                         0, 0, NULL, false);
0531     if (!(status == EFI_SUCCESS || status == EFI_NOT_FOUND)) {
0532         efivar_unlock();
0533         return efi_status_to_err(status);
0534     }
0535 
0536     efivar_entry_list_del_unlock(entry);
0537     return 0;
0538 }
0539 
0540 /**
0541  * efivar_entry_size - obtain the size of a variable
0542  * @entry: entry for this variable
0543  * @size: location to store the variable's size
0544  */
0545 int efivar_entry_size(struct efivar_entry *entry, unsigned long *size)
0546 {
0547     efi_status_t status;
0548     int err;
0549 
0550     *size = 0;
0551 
0552     err = efivar_lock();
0553     if (err)
0554         return err;
0555 
0556     status = efivar_get_variable(entry->var.VariableName,
0557                      &entry->var.VendorGuid, NULL, size, NULL);
0558     efivar_unlock();
0559 
0560     if (status != EFI_BUFFER_TOO_SMALL)
0561         return efi_status_to_err(status);
0562 
0563     return 0;
0564 }
0565 
0566 /**
0567  * __efivar_entry_get - call get_variable()
0568  * @entry: read data for this variable
0569  * @attributes: variable attributes
0570  * @size: size of @data buffer
0571  * @data: buffer to store variable data
0572  *
0573  * The caller MUST call efivar_entry_iter_begin() and
0574  * efivar_entry_iter_end() before and after the invocation of this
0575  * function, respectively.
0576  */
0577 int __efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
0578                unsigned long *size, void *data)
0579 {
0580     efi_status_t status;
0581 
0582     status = efivar_get_variable(entry->var.VariableName,
0583                      &entry->var.VendorGuid,
0584                      attributes, size, data);
0585 
0586     return efi_status_to_err(status);
0587 }
0588 
0589 /**
0590  * efivar_entry_get - call get_variable()
0591  * @entry: read data for this variable
0592  * @attributes: variable attributes
0593  * @size: size of @data buffer
0594  * @data: buffer to store variable data
0595  */
0596 int efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
0597              unsigned long *size, void *data)
0598 {
0599     int err;
0600 
0601     err = efivar_lock();
0602     if (err)
0603         return err;
0604     err = __efivar_entry_get(entry, attributes, size, data);
0605     efivar_unlock();
0606 
0607     return 0;
0608 }
0609 
0610 /**
0611  * efivar_entry_set_get_size - call set_variable() and get new size (atomic)
0612  * @entry: entry containing variable to set and get
0613  * @attributes: attributes of variable to be written
0614  * @size: size of data buffer
0615  * @data: buffer containing data to write
0616  * @set: did the set_variable() call succeed?
0617  *
0618  * This is a pretty special (complex) function. See efivarfs_file_write().
0619  *
0620  * Atomically call set_variable() for @entry and if the call is
0621  * successful, return the new size of the variable from get_variable()
0622  * in @size. The success of set_variable() is indicated by @set.
0623  *
0624  * Returns 0 on success, -EINVAL if the variable data is invalid,
0625  * -ENOSPC if the firmware does not have enough available space, or a
0626  * converted EFI status code if either of set_variable() or
0627  * get_variable() fail.
0628  *
0629  * If the EFI variable does not exist when calling set_variable()
0630  * (EFI_NOT_FOUND), @entry is removed from the variable list.
0631  */
0632 int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes,
0633                   unsigned long *size, void *data, bool *set)
0634 {
0635     efi_char16_t *name = entry->var.VariableName;
0636     efi_guid_t *vendor = &entry->var.VendorGuid;
0637     efi_status_t status;
0638     int err;
0639 
0640     *set = false;
0641 
0642     if (efivar_validate(*vendor, name, data, *size) == false)
0643         return -EINVAL;
0644 
0645     /*
0646      * The lock here protects the get_variable call, the conditional
0647      * set_variable call, and removal of the variable from the efivars
0648      * list (in the case of an authenticated delete).
0649      */
0650     err = efivar_lock();
0651     if (err)
0652         return err;
0653 
0654     /*
0655      * Ensure that the available space hasn't shrunk below the safe level
0656      */
0657     status = check_var_size(attributes, *size + ucs2_strsize(name, 1024));
0658     if (status != EFI_SUCCESS) {
0659         if (status != EFI_UNSUPPORTED) {
0660             err = efi_status_to_err(status);
0661             goto out;
0662         }
0663 
0664         if (*size > 65536) {
0665             err = -ENOSPC;
0666             goto out;
0667         }
0668     }
0669 
0670     status = efivar_set_variable_locked(name, vendor, attributes, *size,
0671                         data, false);
0672     if (status != EFI_SUCCESS) {
0673         err = efi_status_to_err(status);
0674         goto out;
0675     }
0676 
0677     *set = true;
0678 
0679     /*
0680      * Writing to the variable may have caused a change in size (which
0681      * could either be an append or an overwrite), or the variable to be
0682      * deleted. Perform a GetVariable() so we can tell what actually
0683      * happened.
0684      */
0685     *size = 0;
0686     status = efivar_get_variable(entry->var.VariableName,
0687                     &entry->var.VendorGuid,
0688                     NULL, size, NULL);
0689 
0690     if (status == EFI_NOT_FOUND)
0691         efivar_entry_list_del_unlock(entry);
0692     else
0693         efivar_unlock();
0694 
0695     if (status && status != EFI_BUFFER_TOO_SMALL)
0696         return efi_status_to_err(status);
0697 
0698     return 0;
0699 
0700 out:
0701     efivar_unlock();
0702     return err;
0703 
0704 }
0705 
0706 /**
0707  * efivar_entry_iter - iterate over variable list
0708  * @func: callback function
0709  * @head: head of variable list
0710  * @data: function-specific data to pass to callback
0711  *
0712  * Iterate over the list of EFI variables and call @func with every
0713  * entry on the list. It is safe for @func to remove entries in the
0714  * list via efivar_entry_delete() while iterating.
0715  *
0716  * Some notes for the callback function:
0717  *  - a non-zero return value indicates an error and terminates the loop
0718  *  - @func is called from atomic context
0719  */
0720 int efivar_entry_iter(int (*func)(struct efivar_entry *, void *),
0721               struct list_head *head, void *data)
0722 {
0723     struct efivar_entry *entry, *n;
0724     int err = 0;
0725 
0726     err = efivar_lock();
0727     if (err)
0728         return err;
0729 
0730     list_for_each_entry_safe(entry, n, head, list) {
0731         err = func(entry, data);
0732         if (err)
0733             break;
0734     }
0735     efivar_unlock();
0736 
0737     return err;
0738 }