int efi_set_variable_string(sd_id128_t vendor, const char *name, const char *v) { _cleanup_free_ char16_t *u16 = NULL; u16 = utf8_to_utf16(v, strlen(v)); if (!u16) return -ENOMEM; return efi_set_variable(vendor, name, u16, (char16_strlen(u16) + 1) * sizeof(char16_t)); }
static int put_info(update_info *info) { efi_guid_t varguid = FWUPDATE_GUID; ssize_t dps, is; char *guidstr = NULL; char *varname; int error; int rc; rc = efi_guid_to_str(&info->guid, &guidstr); if (rc < 0) { err: return rc; } guidstr = onstack(guidstr, strlen(guidstr)+1); rc = asprintf(&varname, "fwupdate-%s-%"PRIx64, guidstr, info->hw_inst); if (rc < 0) goto err; varname = onstack(varname, strlen(varname)+1); dps = efidp_size((efidp)info->dp_ptr); /* make sure dps is at least big enough to have our structure */ if (dps < 0 || (size_t)dps < sizeof(*info)) { errno = EINVAL; return -1; } /* Make sure sizeof(*info) + dps won't integer overflow */ if ((size_t)dps > SSIZE_MAX - sizeof(*info)) { errno = EOVERFLOW; return -1; } is = sizeof(*info) + dps - sizeof(info->dp_ptr); update_info *info2; info2 = malloc(is); if (!info2) return -1; memcpy(info2, info, sizeof(*info)); memcpy(info2->dp, info->dp_ptr, dps); uint32_t attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; rc = efi_set_variable(varguid, varname, (uint8_t *)info2, is, attributes, 0600); error = errno; free(info2); errno = error; return rc; }
static void write_variable(char *name, char *val) { char *vname; efi_guid_t guid; size_t datalen; uint8_t *data; breakdown_name(name, &guid, &vname); data = get_value(val, &datalen); if (efi_set_variable(guid, vname, data, datalen, attrib) < 0) err(1, "efi_set_variable"); }
int efi_set_reboot_to_firmware(bool value) { int r; uint64_t b, b_new; r = get_os_indications(&b); if (r < 0) return r; if (value) b_new = b | EFI_OS_INDICATIONS_BOOT_TO_FW_UI; else b_new = b & ~EFI_OS_INDICATIONS_BOOT_TO_FW_UI; /* Avoid writing to efi vars store if we can due to firmware bugs. */ if (b != b_new) return efi_set_variable(EFI_VENDOR_GLOBAL, "OsIndications", &b_new, sizeof(uint64_t)); return 0; }
efi_variable_realize(efi_variable_t *var) { if (!var->name || !var->data || !var->data_size || var->attrs == ATTRS_UNSET) { errno = -EINVAL; return -1; } if (var->attrs & EFI_VARIABLE_HAS_AUTH_HEADER && !(var->attrs & EFI_VARIABLE_HAS_SIGNATURE)) { errno = -EPERM; return -1; } uint32_t attrs = var->attrs & ATTRS_MASK; if (attrs & EFI_VARIABLE_APPEND_WRITE) { return efi_append_variable(*var->guid, var->name, var->data, var->data_size, attrs); } return efi_set_variable(*var->guid, var->name, var->data, var->data_size, attrs, 0600); }
static void edit_variable(const char *guid_name, void *data, size_t data_size, int attrib, int edit_type) { efi_guid_t guid; char *name = NULL; int rc; uint8_t *old_data = NULL; size_t old_data_size = 0; uint32_t old_attributes = 0; parse_name(guid_name, &name, &guid); rc = efi_get_variable(guid, name, &old_data, &old_data_size, &old_attributes); if (rc < 0) { fprintf(stderr, "efivar: %m\n"); exit(1); } if (attrib != 0) old_attributes = attrib; switch (edit_type){ case EDIT_APPEND: rc = efi_append_variable(guid, name, data, data_size, old_attributes); break; case EDIT_WRITE: rc = efi_set_variable(guid, name, data, data_size, old_attributes, 0644); break; } if (rc < 0) { fprintf(stderr, "efivar: %m\n"); exit(1); } }