Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

efi: vars: Move efivar caching layer into efivarfs

Move the fiddly bits of the efivar layer into its only remaining user,
efivarfs, and confine its use to that particular module. All other uses
of the EFI variable store have no need for this additional layer of
complexity, given that they either only read variables, or read and
write variables into a separate GUIDed namespace, and cannot be used to
manipulate EFI variables that are covered by the EFI spec and/or affect
the boot flow.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>

+780 -772
+1
drivers/firmware/efi/efi.c
··· 899 899 900 900 return err; 901 901 } 902 + EXPORT_SYMBOL_GPL(efi_status_to_err); 902 903 903 904 static DEFINE_SPINLOCK(efi_mem_reserve_persistent_lock); 904 905 static struct linux_efi_memreserve *efi_memreserve_root __ro_after_init;
-733
drivers/firmware/efi/vars.c
··· 6 6 * Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com> 7 7 */ 8 8 9 - #include <linux/capability.h> 10 9 #include <linux/types.h> 11 10 #include <linux/errno.h> 12 11 #include <linux/init.h> 13 - #include <linux/mm.h> 14 12 #include <linux/module.h> 15 13 #include <linux/string.h> 16 14 #include <linux/smp.h> 17 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 16 #include <linux/ucs2_string.h> 23 17 24 18 /* Private pointer to registered efivars */ 25 19 static 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 - */ 33 21 static DEFINE_SEMAPHORE(efivars_lock); 34 - 35 - static bool 36 - validate_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 - 68 - static bool 69 - validate_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 - 79 - static bool 80 - validate_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 - 130 - static bool 131 - validate_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 - 141 - static bool 142 - validate_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 - 158 - struct 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 - */ 176 - static 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 - */ 207 - static bool 208 - variable_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 - 236 - bool 237 - efivar_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 - } 270 - EXPORT_SYMBOL_GPL(efivar_validate); 271 - 272 - bool 273 - efivar_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 - } 299 - EXPORT_SYMBOL_GPL(efivar_variable_is_removable); 300 22 301 23 efi_status_t check_var_size(u32 attributes, unsigned long size) 302 24 { ··· 45 323 return fops->query_variable_store(attributes, size, true); 46 324 } 47 325 EXPORT_SYMBOL_NS_GPL(check_var_size_nonblocking, EFIVAR); 48 - 49 - static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor, 50 - struct list_head *head) 51 - { 52 - struct efivar_entry *entry, *n; 53 - unsigned long strsize1, strsize2; 54 - bool found = false; 55 - 56 - strsize1 = ucs2_strsize(variable_name, 1024); 57 - list_for_each_entry_safe(entry, n, head, list) { 58 - strsize2 = ucs2_strsize(entry->var.VariableName, 1024); 59 - if (strsize1 == strsize2 && 60 - !memcmp(variable_name, &(entry->var.VariableName), 61 - strsize2) && 62 - !efi_guidcmp(entry->var.VendorGuid, 63 - *vendor)) { 64 - found = true; 65 - break; 66 - } 67 - } 68 - return found; 69 - } 70 - 71 - /* 72 - * Returns the size of variable_name, in bytes, including the 73 - * terminating NULL character, or variable_name_size if no NULL 74 - * character is found among the first variable_name_size bytes. 75 - */ 76 - static unsigned long var_name_strnsize(efi_char16_t *variable_name, 77 - unsigned long variable_name_size) 78 - { 79 - unsigned long len; 80 - efi_char16_t c; 81 - 82 - /* 83 - * The variable name is, by definition, a NULL-terminated 84 - * string, so make absolutely sure that variable_name_size is 85 - * the value we expect it to be. If not, return the real size. 86 - */ 87 - for (len = 2; len <= variable_name_size; len += sizeof(c)) { 88 - c = variable_name[(len / sizeof(c)) - 1]; 89 - if (!c) 90 - break; 91 - } 92 - 93 - return min(len, variable_name_size); 94 - } 95 - 96 - /* 97 - * Print a warning when duplicate EFI variables are encountered and 98 - * disable the sysfs workqueue since the firmware is buggy. 99 - */ 100 - static void dup_variable_bug(efi_char16_t *str16, efi_guid_t *vendor_guid, 101 - unsigned long len16) 102 - { 103 - size_t i, len8 = len16 / sizeof(efi_char16_t); 104 - char *str8; 105 - 106 - str8 = kzalloc(len8, GFP_KERNEL); 107 - if (!str8) 108 - return; 109 - 110 - for (i = 0; i < len8; i++) 111 - str8[i] = str16[i]; 112 - 113 - printk(KERN_WARNING "efivars: duplicate variable: %s-%pUl\n", 114 - str8, vendor_guid); 115 - kfree(str8); 116 - } 117 - 118 - /** 119 - * efivar_init - build the initial list of EFI variables 120 - * @func: callback function to invoke for every variable 121 - * @data: function-specific data to pass to @func 122 - * @duplicates: error if we encounter duplicates on @head? 123 - * @head: initialised head of variable list 124 - * 125 - * Get every EFI variable from the firmware and invoke @func. @func 126 - * should call efivar_entry_add() to build the list of variables. 127 - * 128 - * Returns 0 on success, or a kernel error code on failure. 129 - */ 130 - int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *), 131 - void *data, bool duplicates, struct list_head *head) 132 - { 133 - unsigned long variable_name_size = 1024; 134 - efi_char16_t *variable_name; 135 - efi_status_t status; 136 - efi_guid_t vendor_guid; 137 - int err = 0; 138 - 139 - variable_name = kzalloc(variable_name_size, GFP_KERNEL); 140 - if (!variable_name) { 141 - printk(KERN_ERR "efivars: Memory allocation failed.\n"); 142 - return -ENOMEM; 143 - } 144 - 145 - err = efivar_lock(); 146 - if (err) 147 - goto free; 148 - 149 - /* 150 - * Per EFI spec, the maximum storage allocated for both 151 - * the variable name and variable data is 1024 bytes. 152 - */ 153 - 154 - do { 155 - variable_name_size = 1024; 156 - 157 - status = efivar_get_next_variable(&variable_name_size, 158 - variable_name, 159 - &vendor_guid); 160 - switch (status) { 161 - case EFI_SUCCESS: 162 - variable_name_size = var_name_strnsize(variable_name, 163 - variable_name_size); 164 - 165 - /* 166 - * Some firmware implementations return the 167 - * same variable name on multiple calls to 168 - * get_next_variable(). Terminate the loop 169 - * immediately as there is no guarantee that 170 - * we'll ever see a different variable name, 171 - * and may end up looping here forever. 172 - */ 173 - if (duplicates && 174 - variable_is_present(variable_name, &vendor_guid, 175 - head)) { 176 - dup_variable_bug(variable_name, &vendor_guid, 177 - variable_name_size); 178 - status = EFI_NOT_FOUND; 179 - } else { 180 - err = func(variable_name, vendor_guid, 181 - variable_name_size, data); 182 - if (err) 183 - status = EFI_NOT_FOUND; 184 - } 185 - break; 186 - case EFI_UNSUPPORTED: 187 - err = -EOPNOTSUPP; 188 - status = EFI_NOT_FOUND; 189 - break; 190 - case EFI_NOT_FOUND: 191 - break; 192 - default: 193 - printk(KERN_WARNING "efivars: get_next_variable: status=%lx\n", 194 - status); 195 - status = EFI_NOT_FOUND; 196 - break; 197 - } 198 - 199 - } while (status != EFI_NOT_FOUND); 200 - 201 - efivar_unlock(); 202 - free: 203 - kfree(variable_name); 204 - 205 - return err; 206 - } 207 - EXPORT_SYMBOL_GPL(efivar_init); 208 - 209 - /** 210 - * efivar_entry_add - add entry to variable list 211 - * @entry: entry to add to list 212 - * @head: list head 213 - * 214 - * Returns 0 on success, or a kernel error code on failure. 215 - */ 216 - int efivar_entry_add(struct efivar_entry *entry, struct list_head *head) 217 - { 218 - int err; 219 - 220 - err = efivar_lock(); 221 - if (err) 222 - return err; 223 - list_add(&entry->list, head); 224 - efivar_unlock(); 225 - 226 - return 0; 227 - } 228 - EXPORT_SYMBOL_GPL(efivar_entry_add); 229 - 230 - /** 231 - * __efivar_entry_add - add entry to variable list 232 - * @entry: entry to add to list 233 - * @head: list head 234 - */ 235 - void __efivar_entry_add(struct efivar_entry *entry, struct list_head *head) 236 - { 237 - list_add(&entry->list, head); 238 - } 239 - EXPORT_SYMBOL_GPL(__efivar_entry_add); 240 - 241 - /** 242 - * efivar_entry_remove - remove entry from variable list 243 - * @entry: entry to remove from list 244 - */ 245 - void efivar_entry_remove(struct efivar_entry *entry) 246 - { 247 - list_del(&entry->list); 248 - } 249 - EXPORT_SYMBOL_GPL(efivar_entry_remove); 250 - 251 - /* 252 - * efivar_entry_list_del_unlock - remove entry from variable list 253 - * @entry: entry to remove 254 - * 255 - * Remove @entry from the variable list and release the list lock. 256 - * 257 - * NOTE: slightly weird locking semantics here - we expect to be 258 - * called with the efivars lock already held, and we release it before 259 - * returning. This is because this function is usually called after 260 - * set_variable() while the lock is still held. 261 - */ 262 - static void efivar_entry_list_del_unlock(struct efivar_entry *entry) 263 - { 264 - list_del(&entry->list); 265 - efivar_unlock(); 266 - } 267 - 268 - /** 269 - * efivar_entry_delete - delete variable and remove entry from list 270 - * @entry: entry containing variable to delete 271 - * 272 - * Delete the variable from the firmware and remove @entry from the 273 - * variable list. It is the caller's responsibility to free @entry 274 - * once we return. 275 - * 276 - * Returns 0 on success, -EINTR if we can't grab the semaphore, 277 - * converted EFI status code if set_variable() fails. 278 - */ 279 - int efivar_entry_delete(struct efivar_entry *entry) 280 - { 281 - efi_status_t status; 282 - int err; 283 - 284 - err = efivar_lock(); 285 - if (err) 286 - return err; 287 - 288 - status = efivar_set_variable_locked(entry->var.VariableName, 289 - &entry->var.VendorGuid, 290 - 0, 0, NULL, false); 291 - if (!(status == EFI_SUCCESS || status == EFI_NOT_FOUND)) { 292 - efivar_unlock(); 293 - return efi_status_to_err(status); 294 - } 295 - 296 - efivar_entry_list_del_unlock(entry); 297 - return 0; 298 - } 299 - EXPORT_SYMBOL_GPL(efivar_entry_delete); 300 - 301 - /** 302 - * efivar_entry_size - obtain the size of a variable 303 - * @entry: entry for this variable 304 - * @size: location to store the variable's size 305 - */ 306 - int efivar_entry_size(struct efivar_entry *entry, unsigned long *size) 307 - { 308 - efi_status_t status; 309 - int err; 310 - 311 - *size = 0; 312 - 313 - err = efivar_lock(); 314 - if (err) 315 - return err; 316 - 317 - status = efivar_get_variable(entry->var.VariableName, 318 - &entry->var.VendorGuid, NULL, size, NULL); 319 - efivar_unlock(); 320 - 321 - if (status != EFI_BUFFER_TOO_SMALL) 322 - return efi_status_to_err(status); 323 - 324 - return 0; 325 - } 326 - EXPORT_SYMBOL_GPL(efivar_entry_size); 327 - 328 - /** 329 - * __efivar_entry_get - call get_variable() 330 - * @entry: read data for this variable 331 - * @attributes: variable attributes 332 - * @size: size of @data buffer 333 - * @data: buffer to store variable data 334 - * 335 - * The caller MUST hold the efivar lock when calling this function. 336 - */ 337 - int __efivar_entry_get(struct efivar_entry *entry, u32 *attributes, 338 - unsigned long *size, void *data) 339 - { 340 - efi_status_t status; 341 - 342 - status = efivar_get_variable(entry->var.VariableName, 343 - &entry->var.VendorGuid, 344 - attributes, size, data); 345 - 346 - return efi_status_to_err(status); 347 - } 348 - EXPORT_SYMBOL_GPL(__efivar_entry_get); 349 - 350 - /** 351 - * efivar_entry_get - call get_variable() 352 - * @entry: read data for this variable 353 - * @attributes: variable attributes 354 - * @size: size of @data buffer 355 - * @data: buffer to store variable data 356 - */ 357 - int efivar_entry_get(struct efivar_entry *entry, u32 *attributes, 358 - unsigned long *size, void *data) 359 - { 360 - int err; 361 - 362 - err = efivar_lock(); 363 - if (err) 364 - return err; 365 - err = __efivar_entry_get(entry, attributes, size, data); 366 - efivar_unlock(); 367 - 368 - return err; 369 - } 370 - EXPORT_SYMBOL_GPL(efivar_entry_get); 371 - 372 - /** 373 - * efivar_entry_set_get_size - call set_variable() and get new size (atomic) 374 - * @entry: entry containing variable to set and get 375 - * @attributes: attributes of variable to be written 376 - * @size: size of data buffer 377 - * @data: buffer containing data to write 378 - * @set: did the set_variable() call succeed? 379 - * 380 - * This is a pretty special (complex) function. See efivarfs_file_write(). 381 - * 382 - * Atomically call set_variable() for @entry and if the call is 383 - * successful, return the new size of the variable from get_variable() 384 - * in @size. The success of set_variable() is indicated by @set. 385 - * 386 - * Returns 0 on success, -EINVAL if the variable data is invalid, 387 - * -ENOSPC if the firmware does not have enough available space, or a 388 - * converted EFI status code if either of set_variable() or 389 - * get_variable() fail. 390 - * 391 - * If the EFI variable does not exist when calling set_variable() 392 - * (EFI_NOT_FOUND), @entry is removed from the variable list. 393 - */ 394 - int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes, 395 - unsigned long *size, void *data, bool *set) 396 - { 397 - efi_char16_t *name = entry->var.VariableName; 398 - efi_guid_t *vendor = &entry->var.VendorGuid; 399 - efi_status_t status; 400 - int err; 401 - 402 - *set = false; 403 - 404 - if (efivar_validate(*vendor, name, data, *size) == false) 405 - return -EINVAL; 406 - 407 - /* 408 - * The lock here protects the get_variable call, the conditional 409 - * set_variable call, and removal of the variable from the efivars 410 - * list (in the case of an authenticated delete). 411 - */ 412 - err = efivar_lock(); 413 - if (err) 414 - return err; 415 - 416 - /* 417 - * Ensure that the available space hasn't shrunk below the safe level 418 - */ 419 - status = check_var_size(attributes, *size + ucs2_strsize(name, 1024)); 420 - if (status != EFI_SUCCESS) { 421 - if (status != EFI_UNSUPPORTED) { 422 - err = efi_status_to_err(status); 423 - goto out; 424 - } 425 - 426 - if (*size > 65536) { 427 - err = -ENOSPC; 428 - goto out; 429 - } 430 - } 431 - 432 - status = efivar_set_variable_locked(name, vendor, attributes, *size, 433 - data, false); 434 - if (status != EFI_SUCCESS) { 435 - err = efi_status_to_err(status); 436 - goto out; 437 - } 438 - 439 - *set = true; 440 - 441 - /* 442 - * Writing to the variable may have caused a change in size (which 443 - * could either be an append or an overwrite), or the variable to be 444 - * deleted. Perform a GetVariable() so we can tell what actually 445 - * happened. 446 - */ 447 - *size = 0; 448 - status = efivar_get_variable(entry->var.VariableName, 449 - &entry->var.VendorGuid, 450 - NULL, size, NULL); 451 - 452 - if (status == EFI_NOT_FOUND) 453 - efivar_entry_list_del_unlock(entry); 454 - else 455 - efivar_unlock(); 456 - 457 - if (status && status != EFI_BUFFER_TOO_SMALL) 458 - return efi_status_to_err(status); 459 - 460 - return 0; 461 - 462 - out: 463 - efivar_unlock(); 464 - return err; 465 - 466 - } 467 - EXPORT_SYMBOL_GPL(efivar_entry_set_get_size); 468 - 469 - /** 470 - * efivar_entry_iter - iterate over variable list 471 - * @func: callback function 472 - * @head: head of variable list 473 - * @data: function-specific data to pass to callback 474 - * 475 - * Iterate over the list of EFI variables and call @func with every 476 - * entry on the list. It is safe for @func to remove entries in the 477 - * list via efivar_entry_delete() while iterating. 478 - * 479 - * Some notes for the callback function: 480 - * - a non-zero return value indicates an error and terminates the loop 481 - * - @func is called from atomic context 482 - */ 483 - int efivar_entry_iter(int (*func)(struct efivar_entry *, void *), 484 - struct list_head *head, void *data) 485 - { 486 - struct efivar_entry *entry, *n; 487 - int err = 0; 488 - 489 - err = efivar_lock(); 490 - if (err) 491 - return err; 492 - 493 - list_for_each_entry_safe(entry, n, head, list) { 494 - err = func(entry, data); 495 - if (err) 496 - break; 497 - } 498 - efivar_unlock(); 499 - 500 - return err; 501 - } 502 - EXPORT_SYMBOL_GPL(efivar_entry_iter); 503 326 504 327 /** 505 328 * efivars_kobject - get the kobject for the registered efivars
+1 -1
fs/efivarfs/Makefile
··· 5 5 6 6 obj-$(CONFIG_EFIVAR_FS) += efivarfs.o 7 7 8 - efivarfs-objs := inode.o file.o super.o 8 + efivarfs-objs := inode.o file.o super.o vars.o
+40
fs/efivarfs/internal.h
··· 7 7 #define EFIVAR_FS_INTERNAL_H 8 8 9 9 #include <linux/list.h> 10 + #include <linux/efi.h> 11 + 12 + struct 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 + 21 + struct efivar_entry { 22 + struct efi_variable var; 23 + struct list_head list; 24 + struct kobject kobj; 25 + }; 26 + 27 + int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *), 28 + void *data, bool duplicates, struct list_head *head); 29 + 30 + int efivar_entry_add(struct efivar_entry *entry, struct list_head *head); 31 + void __efivar_entry_add(struct efivar_entry *entry, struct list_head *head); 32 + void efivar_entry_remove(struct efivar_entry *entry); 33 + int efivar_entry_delete(struct efivar_entry *entry); 34 + 35 + int efivar_entry_size(struct efivar_entry *entry, unsigned long *size); 36 + int __efivar_entry_get(struct efivar_entry *entry, u32 *attributes, 37 + unsigned long *size, void *data); 38 + int efivar_entry_get(struct efivar_entry *entry, u32 *attributes, 39 + unsigned long *size, void *data); 40 + int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes, 41 + unsigned long *size, void *data, bool *set); 42 + 43 + int efivar_entry_iter(int (*func)(struct efivar_entry *, void *), 44 + struct list_head *head, void *data); 45 + 46 + bool efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data, 47 + unsigned long data_size); 48 + bool efivar_variable_is_removable(efi_guid_t vendor, const char *name, 49 + size_t len); 10 50 11 51 extern const struct file_operations efivarfs_file_operations; 12 52 extern const struct inode_operations efivarfs_dir_inode_operations;
+738
fs/efivarfs/vars.c
··· 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 + 25 + MODULE_IMPORT_NS(EFIVAR); 26 + 27 + static bool 28 + validate_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 + 60 + static bool 61 + validate_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 + 71 + static bool 72 + validate_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 + 122 + static bool 123 + validate_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 + 133 + static bool 134 + validate_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 + 150 + struct 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 + */ 168 + static 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 + */ 199 + static bool 200 + variable_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 + 228 + bool 229 + efivar_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 + 263 + bool 264 + efivar_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 + 291 + static 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 + */ 318 + static 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 + */ 342 + static 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 + */ 372 + int 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(); 444 + free: 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 + */ 457 + int 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 + */ 475 + void __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 + */ 486 + void 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 + */ 502 + static 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 + */ 519 + int 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 + */ 545 + int 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 + */ 577 + int __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 + */ 596 + int 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 + */ 632 + int 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 + 700 + out: 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 + */ 720 + int 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 + }
-38
include/linux/efi.h
··· 1030 1030 1031 1031 #define EFI_VAR_NAME_LEN 1024 1032 1032 1033 - struct 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 - 1042 - struct efivar_entry { 1043 - struct efi_variable var; 1044 - struct list_head list; 1045 - struct kobject kobj; 1046 - }; 1047 - 1048 1033 int efivars_register(struct efivars *efivars, 1049 1034 const struct efivar_operations *ops, 1050 1035 struct kobject *kobject); ··· 1037 1052 struct kobject *efivars_kobject(void); 1038 1053 1039 1054 int efivar_supports_writes(void); 1040 - int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *), 1041 - void *data, bool duplicates, struct list_head *head); 1042 - 1043 - int efivar_entry_add(struct efivar_entry *entry, struct list_head *head); 1044 - void __efivar_entry_add(struct efivar_entry *entry, struct list_head *head); 1045 - void efivar_entry_remove(struct efivar_entry *entry); 1046 - int efivar_entry_delete(struct efivar_entry *entry); 1047 - 1048 - int efivar_entry_size(struct efivar_entry *entry, unsigned long *size); 1049 - int __efivar_entry_get(struct efivar_entry *entry, u32 *attributes, 1050 - unsigned long *size, void *data); 1051 - int efivar_entry_get(struct efivar_entry *entry, u32 *attributes, 1052 - unsigned long *size, void *data); 1053 - int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes, 1054 - unsigned long *size, void *data, bool *set); 1055 - 1056 - int efivar_entry_iter(int (*func)(struct efivar_entry *, void *), 1057 - struct list_head *head, void *data); 1058 - 1059 - bool efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data, 1060 - unsigned long data_size); 1061 - bool efivar_variable_is_removable(efi_guid_t vendor, const char *name, 1062 - size_t len); 1063 1055 1064 1056 int efivar_lock(void); 1065 1057 int efivar_trylock(void);