EFI_VARIABLE_T(3)
β¨ EFI_VARIABLE_T β¨
okay so bestie, this is a page from the Library Functions Manual (section 3, we're in C library land π
) and it's all about efi_variable_t β the little in-memory glow-up for UEFI variables. let's get into it π¦
π NAME π
efi_variable_import, efi_variable_export, efi_variable_alloc, efi_variable_free, efi_variable_set_name, efi_variable_get_name, efi_variable_set_guid, efi_variable_get_guid, efi_variable_set_data, efi_variable_get_data, efi_variable_set_attributes, efi_variable_get_attributes, efi_variable_realize β these are the utility functions that import and export UEFI variables to files. that's the whole vibe. π«Ά
π SYNOPSIS π
#include <efivar.h>
typedef struct efi_variable efi_variable_t;
ssize_t efi_variable_import(uint8_t *data, size_t size, efi_variable_t **var);
ssize_t efi_variable_export(efi_variable_t *var, uint8_t **data, size_t *size);
efi_variable_t *efi_variable_alloc(void);
void efi_variable_free(efi_variable_t *var, int free_data);
int efi_variable_set_name(efi_variable_t *var, char *name);
char *efi_variable_get_name(efi_variable_t *var);
int efi_variable_set_guid(efi_variable_t *var, efi_guid_t *guid);
int efi_variable_get_guid(efi_variable_t *var, efi_guid_t **guid);
int efi_variable_set_data(efi_variable_t *var, uint8_t *data, size_t size);
int efi_variable_get_data(efi_variable_t *var, uint8_t **data, size_t *size);
#define EFI_VARIABLE_NON_VOLATILE 0x0000000000000001
#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002
#define EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004
#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x0000000000000008
#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x0000000000000010
#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x0000000000000020
#define EFI_VARIABLE_APPEND_WRITE 0x0000000000000040
#define EFI_VARIABLE_HAS_AUTH_HEADER 0x0000000100000000
#define EFI_VARIABLE_HAS_SIGNATURE 0x0000000200000000
int efi_variable_set_attributes(efi_variable_t *var, uint64_t attrs);
int efi_variable_get_attributes(efi_variable_t *var, uint64_t *attrs);
int efi_variable_realize(efi_variable_t *var);
π DESCRIPTION π
so efi_variable_t is an opaque data type, right? its whole job is holding variables in-memory so the rest of this API can play with them. mysterious. iconic. we don't need to know its inner workings, we just need to know it's there for us. π
π importing & exporting
efi_variable_import() is your girl for pulling in raw data that was read from a file. she returns the amount of data consumed by this variable, and β plot twist β you can call her over and over again, using her return code as an offset, to chew through a whole list of variables. ate. π₯
heads up bestie: the internalguid,name, anddatavalues are allocated separately, so they gotta be freed either individually or via thefree_dataparameter ofefi_variable_free(). the_get()accessors for those values hand you back data that's suitable for freeing individually β except in those cases where a_set()accessor was passed an object that was already unsuitable for that. π
efi_variable_export() does the reverse glow-up: she marshalls efi_variable_t objects into linear data you can write to a file. and here's the cute part β if you don't provide the data or size parameters, she'll just tell you how much storage a caller must allocate. otherwise, efi_variable_export() will use the storage referred to as its buffer; and if size is smaller than the amount of needed storage, the buffer will not be modified, and the difference between the needed space and size will be returned. no cap. β¨
π§ allocating & freeing
efi_variable_alloc() allocates you an unpopulated efi_variable_t object β a blank canvas, suitable to be used throughout this whole API. efi_variable_free() is her counterpart: she frees an efi_variable_t object, and if free_data is nonzero, she also frees its constituent data. clean up after yourself, periodt. π
π¦ the accessor lore
each pair of _set() and _get() accessors has essentially the same semantics. and listen β neither operation performs any memory management, including freeing previously set values or values that got set by efi_variable_import(). so in some cases you may need to use a _get() accessor to retrieve an object that you then free yourself. and if no value has been set? _get() accessors will set errno to ENOENT and return a negative value or NULL. noted. π
π the individual accessors
efi_variable_set_name()andefi_variable_get_name()β set and retrieve the name of the variable that theefi_variable_tobject is referring to.efi_variable_set_guid()andefi_variable_get_guid()β set and retrieve the Vendor GUID value of the variable that theefi_variable_tobject is referring to.efi_variable_set_data()andefi_variable_get_data()β set and retrieve anefi_variable_tobject's variable data.efi_variable_set_attributes()andefi_variable_get_attributesβ set and retrieve anefi_variable_tobject's attributes.
πΈ about those attributes
all bits except EFI_VARIABLE_HAS_AUTH_HEADER and EFI_VARIABLE_HAS_SIGNATURE are defined in the UEFI specification and should be used accordingly. fr fr.
EFI_VARIABLE_HAS_AUTH_HEADER should be used by applications to track whether the variable data contents include an authentication header.
EFI_VARIABLE_HAS_SIGNATURE should be used by applications to track if the variable's data contents include a signature β and it should not be set unless EFI_VARIABLE_HAS_AUTH_HEADER is also set. read that twice bestie. π
these attributes are how you track whether an exported variable is in a state of partial construction β for example, if an authenticated variable has been created but is intended to be signed at a later date. werk-in-progress energy. π
π realize
efi_variable_realize() is a convenience function β she sets or appends a UEFI variable on the running system from an efi_variable_t object. her return codes are the same as efi_append_variable(3) if EFI_VARIABLE_APPEND_WRITE is set, and efi_set_variable() if that bit is not set.
additionally, in the case that any of the authentication bits are set, efi_variable_realize() will return an error and set errno to EPERM unless both the EFI_VARIABLE_HAS_AUTH_HEADER and EFI_VARIABLE_HAS_SIGNATURE attribute bits have been set. so likeβ¦ no half-signed shenanigans. π
β RETURN VALUE β
efi_variable_import()returns0on success, and-1on failure. in cases where it can't parse the data,errnowill be set toEINVAL. in cases where memory has been exhausted,errnowill be set toENOMEM. πefi_variable_export()returns the size of the buffer data on success, or a negative value in the case of an error. if thedataorsizeparameters are not provided, this function will return how much storage a caller must allocate. otherwise, this function will use the storage provided indata; ifsizeis less than the needed space, the buffer will not be modified, and the return value will be the difficiency in size. π«Άefi_variable_alloc()returns a newly allocatedefi_variable_tobject β but she does not perform any allocation for that object'sname,guid, ordata. in the case that memory is exhausted,NULLwill be returned, anderrnowill be set toENOMEM. πefi_variable_get_name()returns a pointer to the NUL-terminated string containing theefi_variable_tobject's name information. β¨efi_variable_set_name(),efi_variable_set_guid(),efi_variable_get_guid(),efi_variable_set_data(),efi_variable_get_data(),efi_variable_set_attributes(),efi_variable_get_attributes(), andefi_variable_realize()return0on success and-1on error. that's it, that's the rule. π
π AUTHORS π
Peter Jones <pjones@redhat.com> β the icon, the moment, the legend. π
and that's the whole page bestie!! this one's from Thu Nov 11 2014, out of the EFI_VARIABLE_T(3) manual β go forth and import/export your variables responsibly, mwah ππ¦πΈ
π¦ where this page comes from
- alpine 3.22: efivar-doc 39-r0 Β· LGPL-2.1-only
- alpine 3.23: efivar-doc 39-r1 Β· LGPL-2.1-only
- alpine 3.24: efivar-doc 39-r1 Β· LGPL-2.1-only
- arch rolling: efivar 39-2 Β· LGPL-2.1-or-later
- centos-stream 10: efivar-devel 39-3.el10 Β· LGPL-2.1-only
- centos-stream 9: efivar-devel 38-3.el9 Β· LGPLv2
- centos-stream 9: efivar-devel 38-3.el9 Β· LGPLv2
- debian bookworm: libefivar-dev 37-6 Β· LGPL-2.0-or-later
- debian trixie: libefivar-dev 38-3.1+b1 Β· LGPL-2.0-or-later
- fedora 43: efivar-devel 39-10.fc43 Β· LGPL-2.1-only
- fedora 43: efivar-devel 39-10.fc43 Β· LGPL-2.1-only
- fedora 44: efivar-devel 39-12.fc44 Β· LGPL-2.1-only
- fedora 44: efivar-devel 39-12.fc44 Β· LGPL-2.1-only
- nixpkgs unstable: efivar 39
- opensuse-leap 16.0: efivar-devel 38-160000.2.2 Β· LGPL-2.1-only
- opensuse-leap 16.0: efivar-devel 38-160000.2.2 Β· LGPL-2.1-only
- opensuse-leap 16.0: efivar-devel 38-160000.2.2 Β· LGPL-2.1-only
- opensuse-leap 16.0: efivar-devel 38-160000.2.2 Β· LGPL-2.1-only
- ubuntu jammy: libefivar-dev 37-6ubuntu2 Β· LGPL-2.0-or-later
- ubuntu noble: libefivar-dev 38-3.1build1 Β· LGPL-2.0-or-later
- ubuntu questing: libefivar-dev 38-3.1build1
- ubuntu resolute: libefivar-dev 39-2 Β· LGPL-2.0-or-later
- ubuntu stonking: libefivar-dev 39-2 Β· LGPL-2.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms