Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: efivar: Copy VarToFile to RTStorageVolatile file at ESP #267

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 5 additions & 95 deletions src/efivar.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,34 +53,6 @@ static const char *attribute_names[] = {
""
};

static inline void
validate_name(const char *name)
{
if (name == NULL) {
err:
warnx("Invalid variable name \"%s\"",
(name == NULL) ? "(null)" : name);
show_errors();
exit(1);
}
if (name[0] == '{') {
const char *next = strchr(name+1, '}');
if (!next)
goto err;
if (next[1] != '-')
goto err;
if (next[2] == '\000')
goto err;
} else {
if (strlen(name) < 38)
goto err;
if (name[8] != '-' || name[13] != '-' ||
name[18] != '-' || name[23] != '-' ||
name[36] != '-')
goto err;
}
}

static void
list_all_variables(void)
{
Expand All @@ -97,68 +69,6 @@ list_all_variables(void)
}
}

static void
parse_name(const char *guid_name, char **name, efi_guid_t *guid)
{
unsigned int guid_len = sizeof("84be9c3e-8a32-42c0-891c-4cd3b072becc");
char guid_buf[guid_len + 2];
int rc;
off_t name_pos = 0;

const char *left, *right;

validate_name(guid_name);

left = strchr(guid_name, '{');
right = strchr(guid_name, '}');
if (left && right) {
if (right[1] != '-' || right[2] == '\0') {
bad_name:
errno = -EINVAL;
fprintf(stderr, "efivar: invalid name \"%s\"\n",
guid_name);
show_errors();
exit(1);
}
name_pos = right + 1 - guid_name;

strncpy(guid_buf, guid_name, name_pos);
guid_buf[name_pos++] = '\0';

rc = efi_id_guid_to_guid(guid_buf, guid);
if (rc < 0)
goto bad_name;
} else {
/* it has to be at least the length of the guid, a dash, and
* one more character */
if (strlen(guid_name) < guid_len + 2)
goto bad_name;
name_pos = guid_len - 1;

if (guid_name[name_pos] != '-' || guid_name[name_pos+1] == '\0')
goto bad_name;
name_pos++;

memset(guid_buf, 0, sizeof(guid_buf));
strncpy(guid_buf, guid_name, guid_len - 1);

rc = text_to_guid(guid_buf, guid);
if (rc < 0)
goto bad_name;
}

char *name_buf = NULL;
int name_len;
name_len = strlen(guid_name + name_pos) + 1;
name_buf = calloc(1, name_len);
if (!name_buf) {
fprintf(stderr, "efivar: %m\n");
exit(1);
}
strcpy(name_buf, guid_name + name_pos);
*name = name_buf;
}

static void
show_variable_data(efi_guid_t guid, const char *name, uint32_t attributes,
uint8_t *data, size_t data_size,
Expand Down Expand Up @@ -233,7 +143,7 @@ show_variable(char *guid_name, int display_type)
size_t data_size = 0;
uint32_t attributes;

parse_name(guid_name, &name, &guid);
efi_parse_name(guid_name, &name, &guid);
if (!name || efi_guid_is_empty(&guid)) {
fprintf(stderr, "efivar: could not parse variable name.\n");
show_errors();
Expand Down Expand Up @@ -301,7 +211,7 @@ save_variable(char *guid_name, char *outfile, bool dmpstore)
uint32_t attributes = 7;
efi_variable_t *var;

parse_name(guid_name, &name, &guid);
efi_parse_name(guid_name, &name, &guid);
if (!name || efi_guid_is_empty(&guid)) {
fprintf(stderr, "efivar: could not parse variable name.\n");
show_errors();
Expand Down Expand Up @@ -348,7 +258,7 @@ edit_variable(const char *guid_name, void *data, size_t data_size,
size_t old_data_size = 0;
uint32_t old_attributes = 0;

parse_name(guid_name, &name, &guid);
efi_parse_name(guid_name, &name, &guid);
if (!name || efi_guid_is_empty(&guid)) {
fprintf(stderr, "efivar: could not parse variable name.\n");
show_errors();
Expand Down Expand Up @@ -441,7 +351,7 @@ usage(int ret)
" -a, --append append to variable specified by --name\n"
" -f, --datafile=<file> load or save variable contents from <file>\n"
" -e, --export=<file> export variable to <file>\n"
" -i, --import=<file> import variable from <file\n"
" -i, --import=<file> import variable from <file>\n"
" -L, --list-guids show internal guid list\n"
" -w, --write write to variable specified by --name\n\n"
"Help options:\n"
Expand Down Expand Up @@ -589,7 +499,7 @@ int main(int argc, char *argv[])
efi_guid_t guid = efi_guid_zero;
efi_variable_t *var;

parse_name(guid_name, &name, &guid);
efi_parse_name(guid_name, &name, &guid);
prepare_data(datafile, &data, &data_size);

var = efi_variable_alloc();
Expand Down
4 changes: 4 additions & 0 deletions src/efivarfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,8 @@ efivarfs_del_variable(efi_guid_t guid, const char *name)
if (rc < 0)
efi_error("unlink failed");

efi_save_esp_filename();

__typeof__(errno) errno_value = errno;
free(path);
errno = errno_value;
Expand Down Expand Up @@ -442,6 +444,8 @@ efivarfs_set_variable(efi_guid_t guid, const char *name, const uint8_t *data,
goto err;
}

efi_save_esp_filename();

/* we're done */
ret = 0;

Expand Down
3 changes: 3 additions & 0 deletions src/include/efivar/efivar.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ extern int efi_variable_get_attributes(efi_variable_t *var, uint64_t *attrs)
extern int efi_variable_realize(efi_variable_t *var)
__attribute__((__nonnull__ (1)));

extern void efi_parse_name(const char *guid_name, char **name, efi_guid_t *guid);
extern void efi_save_esp_filename(void);

#ifndef EFIVAR_BUILD_ENVIRONMENT
extern int efi_error_get(unsigned int n,
char ** const filename,
Expand Down
Loading