efivars.c revision bc6f2e7c62bcd08177f879423188c54289694619
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2013 Lennart Poettering
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <ctype.h>
#include "util.h"
#include "utf8.h"
#include "efivars.h"
#ifdef ENABLE_EFI
bool is_efi_boot(void) {
}
int r;
void *v;
size_t s;
uint8_t b;
if (r < 0)
return r;
if (s != 1) {
r = -EINVAL;
goto finish;
}
b = *(uint8_t *)v;
r = b > 0;
free(v);
return r;
}
int is_efi_secure_boot(void) {
return read_flag("SecureBoot");
}
int is_efi_secure_boot_setup_mode(void) {
return read_flag("SetupMode");
}
int efi_get_variable(
const char *name,
void **value,
_cleanup_free_ char *p = NULL;
uint32_t a;
ssize_t n;
void *r;
if (asprintf(&p,
"/sys/firmware/efi/efivars/%s-%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
return -ENOMEM;
if (fd < 0)
return -errno;
return -errno;
return -EIO;
return -E2BIG;
if (n < 0)
return -errno;
if (n != sizeof(a))
return -EIO;
if (!r)
return -ENOMEM;
if (n < 0) {
free(r);
return (int) -n;
}
free(r);
return -EIO;
}
/* Always NUL terminate (2 bytes, to protect UTF-16) */
*value = r;
if (attribute)
*attribute = a;
return 0;
}
_cleanup_free_ void *s = NULL;
int r;
char *x;
if (r < 0)
return r;
x = utf16_to_utf8(s, ss);
if (!x)
return -ENOMEM;
*p = x;
return 0;
}
size_t l = 0;
while (s[l] > 0)
l++;
return (l+1) * sizeof(uint16_t);
}
struct uuid {
} _packed_;
}
int efi_get_boot_option(
char **title,
char **path) {
struct boot_option {
} _packed_;
struct drive_path {
char signature[16];
} _packed_;
struct device_path {
union {
struct drive_path drive;
};
} _packed_;
char boot_id[9];
size_t l;
struct boot_option *header;
char *s = NULL;
char *p = NULL;
int err;
if (err < 0)
return err;
if (l < sizeof(struct boot_option))
return -ENOENT;
return -EINVAL;
if (!s) {
goto err;
}
dnext = 0;
struct device_path *dpath;
break;
/* Type 0x7F – End of Hardware Device Path, Sub-Type 0xFF – End Entire Device Path */
break;
/* Type 0x04 – Media Device Path */
continue;
/* Sub-Type 1 – Hard Drive */
/* 0x02 – GUID Partition Table */
continue;
/* 0x02 – GUID signature */
continue;
continue;
}
/* Sub-Type 4 – File Path */
continue;
}
}
}
if (title)
*title = s;
if (part_uuid)
if (path)
*path = p;
return 0;
err:
free(s);
free(p);
return err;
}
void *buf;
size_t l;
int r;
if (r < 0)
return r;
if (l <= 0) {
return -ENOENT;
}
if ((l % sizeof(uint16_t) > 0) ||
return -EINVAL;
}
return (int) (l / sizeof(uint16_t));
}
static int boot_id_hex(const char s[4]) {
int i;
int id = 0;
for (i = 0; i < 4; i++)
if (s[i] >= '0' && s[i] <= '9')
else if (s[i] >= 'A' && s[i] <= 'F')
else
return -1;
return id;
}
return (int)*a - (int)*b;
}
int count = 0, r;
if (!dir)
return -errno;
int id;
uint16_t *t;
continue;
continue;
continue;
if (id < 0)
continue;
if (!t) {
r = -ENOMEM;
goto fail;
}
list = t;
}
return count;
fail:
return r;
}
_cleanup_free_ char *j = NULL;
int r;
uint64_t x;
assert(u);
if (r < 0)
return r;
r = safe_atou64(j, &x);
if (r < 0)
return r;
*u = x;
return 0;
}
uint64_t x, y;
int r;
if (r < 0)
return r;
if (r < 0)
return r;
if (y == 0 || y < x)
return -EIO;
if (y > USEC_PER_HOUR)
return -EIO;
*firmware = x;
*loader = y;
return 0;
}
int efi_get_boot_timestamps(const dual_timestamp *n, dual_timestamp *firmware, dual_timestamp *loader) {
usec_t x, y, a;
int r;
if (!n) {
n = &_n;
}
r = get_boot_usec(&x, &y);
if (r < 0)
return r;
/* Let's convert this to timestamps where the firmware
* since usec_t is unsigned and the kernel's monotonic clock
* begins at kernel initialization we'll actually initialize
* the monotonic timestamps here as negative of the actual
* value. */
return 0;
}
int efi_get_loader_device_part_uuid(sd_id128_t *u) {
_cleanup_free_ char *p = NULL;
int r, parsed[16];
unsigned i;
assert(u);
if (r < 0)
return r;
if (sscanf(p, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
return -EIO;
for (i = 0; i < ELEMENTSOF(parsed); i++)
return 0;
}
#endif