|
|
5fb29d |
From 91ea62136543582a9d9effd32bcccce12b748114 Mon Sep 17 00:00:00 2001
|
|
|
5fb29d |
From: Peter Jones <pjones@redhat.com>
|
|
|
5fb29d |
Date: Wed, 15 Oct 2014 10:35:56 -0400
|
|
|
5fb29d |
Subject: [PATCH] Don't error on unset BootOrder when we're trying to add to or
|
|
|
5fb29d |
rm from it.
|
|
|
5fb29d |
|
|
|
5fb29d |
Also print some better error messases here and there.
|
|
|
5fb29d |
|
|
|
5fb29d |
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
|
5fb29d |
---
|
|
|
5fb29d |
README | 1 -
|
|
|
5fb29d |
src/efibootmgr/efibootmgr.c | 126 +++++++++++++++++++++++++++-----------------
|
|
|
5fb29d |
src/lib/efi.c | 95 +++++++++++++++++++--------------
|
|
|
5fb29d |
src/man/man8/efibootmgr.8 | 3 --
|
|
|
5fb29d |
4 files changed, 131 insertions(+), 94 deletions(-)
|
|
|
5fb29d |
|
|
|
5fb29d |
diff --git a/README b/README
|
|
|
5fb29d |
index 3bc0a26..edbce4b 100644
|
|
|
5fb29d |
--- a/README
|
|
|
5fb29d |
+++ b/README
|
|
|
5fb29d |
@@ -29,7 +29,6 @@ usage: efibootmgr [options]
|
|
|
5fb29d |
-O | --delete-bootorder delete BootOrder
|
|
|
5fb29d |
-p | --part part (defaults to 1) containing loader
|
|
|
5fb29d |
-q | --quiet be quiet
|
|
|
5fb29d |
- --test filename don't write to NVRAM, write to filename
|
|
|
5fb29d |
-t | --timeout seconds Boot manager timeout
|
|
|
5fb29d |
-T | --delete-timeout delete Timeout value
|
|
|
5fb29d |
-u | --unicode | --UCS-2 pass extra args as UCS-2 (default is ASCII)
|
|
|
5fb29d |
diff --git a/src/efibootmgr/efibootmgr.c b/src/efibootmgr/efibootmgr.c
|
|
|
5fb29d |
index 4d80f87..eb13942 100644
|
|
|
5fb29d |
--- a/src/efibootmgr/efibootmgr.c
|
|
|
5fb29d |
+++ b/src/efibootmgr/efibootmgr.c
|
|
|
5fb29d |
@@ -33,6 +33,7 @@
|
|
|
5fb29d |
#define _GNU_SOURCE
|
|
|
5fb29d |
|
|
|
5fb29d |
#include <ctype.h>
|
|
|
5fb29d |
+#include <err.h>
|
|
|
5fb29d |
#include <stdio.h>
|
|
|
5fb29d |
#include <stdlib.h>
|
|
|
5fb29d |
#include <string.h>
|
|
|
5fb29d |
@@ -123,7 +124,7 @@ read_vars(char **namelist,
|
|
|
5fb29d |
}
|
|
|
5fb29d |
return;
|
|
|
5fb29d |
err:
|
|
|
5fb29d |
- fprintf(stderr, "efibootmgr: %m\n");
|
|
|
5fb29d |
+ warn("efibootmgr");
|
|
|
5fb29d |
exit(1);
|
|
|
5fb29d |
}
|
|
|
5fb29d |
|
|
|
5fb29d |
@@ -242,16 +243,20 @@ make_boot_var(list_t *boot_list)
|
|
|
5fb29d |
free_number = opts.bootnum;
|
|
|
5fb29d |
}
|
|
|
5fb29d |
|
|
|
5fb29d |
- if (free_number == -1)
|
|
|
5fb29d |
+ if (free_number == -1) {
|
|
|
5fb29d |
+ warn("efibootmgr: no available boot variables");
|
|
|
5fb29d |
return NULL;
|
|
|
5fb29d |
+ }
|
|
|
5fb29d |
|
|
|
5fb29d |
/* Create a new efi_variable_t object
|
|
|
5fb29d |
and populate it.
|
|
|
5fb29d |
*/
|
|
|
5fb29d |
|
|
|
5fb29d |
boot = calloc(1, sizeof(*boot));
|
|
|
5fb29d |
- if (!boot)
|
|
|
5fb29d |
+ if (!boot) {
|
|
|
5fb29d |
+ warn("efibootmgr");
|
|
|
5fb29d |
return NULL;
|
|
|
5fb29d |
+ }
|
|
|
5fb29d |
if (make_linux_load_option(&boot->data, &boot->data_size) < 0)
|
|
|
5fb29d |
goto err_boot_entry;
|
|
|
5fb29d |
if (append_extra_args(&boot->data, &boot->data_size) < 0)
|
|
|
5fb29d |
@@ -260,8 +265,10 @@ make_boot_var(list_t *boot_list)
|
|
|
5fb29d |
boot->num = free_number;
|
|
|
5fb29d |
boot->guid = EFI_GLOBAL_VARIABLE;
|
|
|
5fb29d |
rc = asprintf(&boot->name, "Boot%04X", free_number);
|
|
|
5fb29d |
- if (rc < 0)
|
|
|
5fb29d |
+ if (rc < 0) {
|
|
|
5fb29d |
+ warn("efibootmgr");
|
|
|
5fb29d |
goto err_boot_entry;
|
|
|
5fb29d |
+ }
|
|
|
5fb29d |
boot->attributes = EFI_VARIABLE_NON_VOLATILE |
|
|
|
5fb29d |
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
|
|
5fb29d |
EFI_VARIABLE_RUNTIME_ACCESS;
|
|
|
5fb29d |
@@ -272,8 +279,12 @@ make_boot_var(list_t *boot_list)
|
|
|
5fb29d |
list_add_tail(&boot->list, boot_list);
|
|
|
5fb29d |
return boot;
|
|
|
5fb29d |
err_boot_entry:
|
|
|
5fb29d |
- if (boot->name)
|
|
|
5fb29d |
+ if (boot->name) {
|
|
|
5fb29d |
+ warn("Could not set variable %s", boot->name);
|
|
|
5fb29d |
free(boot->name);
|
|
|
5fb29d |
+ } else {
|
|
|
5fb29d |
+ warn("Could not set variable");
|
|
|
5fb29d |
+ }
|
|
|
5fb29d |
if (boot->data)
|
|
|
5fb29d |
free(boot->data);
|
|
|
5fb29d |
free(boot);
|
|
|
5fb29d |
@@ -313,6 +324,15 @@ read_boot_order(efi_variable_t **boot_order)
|
|
|
5fb29d |
}
|
|
|
5fb29d |
|
|
|
5fb29d |
static int
|
|
|
5fb29d |
+set_boot_u16(const char *name, uint16_t num)
|
|
|
5fb29d |
+{
|
|
|
5fb29d |
+ return efi_set_variable(EFI_GLOBAL_GUID, name, (uint8_t *)&num,
|
|
|
5fb29d |
+ sizeof (num), EFI_VARIABLE_NON_VOLATILE |
|
|
|
5fb29d |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
|
|
5fb29d |
+ EFI_VARIABLE_RUNTIME_ACCESS);
|
|
|
5fb29d |
+}
|
|
|
5fb29d |
+
|
|
|
5fb29d |
+static int
|
|
|
5fb29d |
add_to_boot_order(uint16_t num)
|
|
|
5fb29d |
{
|
|
|
5fb29d |
efi_variable_t *boot_order = NULL;
|
|
|
5fb29d |
@@ -321,8 +341,11 @@ add_to_boot_order(uint16_t num)
|
|
|
5fb29d |
int rc;
|
|
|
5fb29d |
|
|
|
5fb29d |
rc = read_boot_order(&boot_order);
|
|
|
5fb29d |
- if (rc < 0)
|
|
|
5fb29d |
+ if (rc < 0) {
|
|
|
5fb29d |
+ if (errno == ENOENT)
|
|
|
5fb29d |
+ rc = set_boot_u16("BootOrder", num);
|
|
|
5fb29d |
return rc;
|
|
|
5fb29d |
+ }
|
|
|
5fb29d |
|
|
|
5fb29d |
/* We've now got an array (in boot_order->data) of the
|
|
|
5fb29d |
* boot order. First add our entry, then copy the old array.
|
|
|
5fb29d |
@@ -358,8 +381,11 @@ remove_dupes_from_boot_order(void)
|
|
|
5fb29d |
int rc;
|
|
|
5fb29d |
|
|
|
5fb29d |
rc = read_boot_order(&boot_order);
|
|
|
5fb29d |
- if (rc < 0)
|
|
|
5fb29d |
+ if (rc < 0) {
|
|
|
5fb29d |
+ if (errno == ENOENT)
|
|
|
5fb29d |
+ rc = 0;
|
|
|
5fb29d |
return rc;
|
|
|
5fb29d |
+ }
|
|
|
5fb29d |
|
|
|
5fb29d |
old_data = (uint16_t *)(boot_order->data);
|
|
|
5fb29d |
/* Start with the same size */
|
|
|
5fb29d |
@@ -409,8 +435,11 @@ remove_from_boot_order(uint16_t num)
|
|
|
5fb29d |
int rc;
|
|
|
5fb29d |
|
|
|
5fb29d |
rc = read_boot_order(&boot_order);
|
|
|
5fb29d |
- if (rc < 0)
|
|
|
5fb29d |
+ if (rc < 0) {
|
|
|
5fb29d |
+ if (errno == ENOENT)
|
|
|
5fb29d |
+ rc = 0;
|
|
|
5fb29d |
return rc;
|
|
|
5fb29d |
+ }
|
|
|
5fb29d |
|
|
|
5fb29d |
/* We've now got an array (in boot_order->data) of the
|
|
|
5fb29d |
boot order. Simply copy the array, skipping the
|
|
|
5fb29d |
@@ -470,15 +499,6 @@ read_boot_u16(const char *name)
|
|
|
5fb29d |
}
|
|
|
5fb29d |
|
|
|
5fb29d |
static int
|
|
|
5fb29d |
-set_boot_u16(const char *name, uint16_t num)
|
|
|
5fb29d |
-{
|
|
|
5fb29d |
- return efi_set_variable(EFI_GLOBAL_GUID, name, (uint8_t *)&num,
|
|
|
5fb29d |
- sizeof (num), EFI_VARIABLE_NON_VOLATILE |
|
|
|
5fb29d |
- EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
|
|
5fb29d |
- EFI_VARIABLE_RUNTIME_ACCESS);
|
|
|
5fb29d |
-}
|
|
|
5fb29d |
-
|
|
|
5fb29d |
-static int
|
|
|
5fb29d |
delete_boot_var(uint16_t num)
|
|
|
5fb29d |
{
|
|
|
5fb29d |
int rc;
|
|
|
5fb29d |
@@ -490,13 +510,18 @@ delete_boot_var(uint16_t num)
|
|
|
5fb29d |
rc = efi_del_variable(EFI_GLOBAL_GUID, name);
|
|
|
5fb29d |
|
|
|
5fb29d |
/* For backwards compatibility, try to delete abcdef entries as well */
|
|
|
5fb29d |
- if (rc < 0 && errno == ENOENT) {
|
|
|
5fb29d |
- snprintf(name, sizeof(name), "Boot%04x", num);
|
|
|
5fb29d |
- rc = efi_del_variable(EFI_GLOBAL_GUID, name);
|
|
|
5fb29d |
+ if (rc < 0) {
|
|
|
5fb29d |
+ if (errno == ENOENT) {
|
|
|
5fb29d |
+ snprintf(name, sizeof(name), "Boot%04x", num);
|
|
|
5fb29d |
+ rc = efi_del_variable(EFI_GLOBAL_GUID, name);
|
|
|
5fb29d |
+ } else if (errno == EPERM) {
|
|
|
5fb29d |
+ warn("Could not delete Boot%04X", num);
|
|
|
5fb29d |
+ return rc;
|
|
|
5fb29d |
+ }
|
|
|
5fb29d |
}
|
|
|
5fb29d |
|
|
|
5fb29d |
if (rc < 0) {
|
|
|
5fb29d |
- fprintf(stderr,"\nboot entry: %X not found\n\n",num);
|
|
|
5fb29d |
+ warnx("Boot entry %04X not found", num);
|
|
|
5fb29d |
return rc;
|
|
|
5fb29d |
}
|
|
|
5fb29d |
list_for_each_safe(pos, n, &boot_entry_list) {
|
|
|
5fb29d |
@@ -512,7 +537,6 @@ delete_boot_var(uint16_t num)
|
|
|
5fb29d |
return 0;
|
|
|
5fb29d |
}
|
|
|
5fb29d |
|
|
|
5fb29d |
-
|
|
|
5fb29d |
static void
|
|
|
5fb29d |
set_var_nums(list_t *list)
|
|
|
5fb29d |
{
|
|
|
5fb29d |
@@ -1177,34 +1201,28 @@ main(int argc, char **argv)
|
|
|
5fb29d |
if (opts.iface && (
|
|
|
5fb29d |
opts.acpi_hid < 0 || opts.acpi_uid < 0 ||
|
|
|
5fb29d |
opts.acpi_hid > UINT32_MAX ||
|
|
|
5fb29d |
- opts.acpi_uid > UINT32_MAX)) {
|
|
|
5fb29d |
- fprintf(stderr, "\nYou must specify the ACPI HID and UID when using -i.\n\n");
|
|
|
5fb29d |
- return 1;
|
|
|
5fb29d |
- }
|
|
|
5fb29d |
+ opts.acpi_uid > UINT32_MAX))
|
|
|
5fb29d |
+ errx(1, "You must specify the ACPI HID and UID when using -i.");
|
|
|
5fb29d |
|
|
|
5fb29d |
- if (!efi_variables_supported()) {
|
|
|
5fb29d |
- fprintf(stderr, "\nEFI variables are not supported on this system.\n\n");
|
|
|
5fb29d |
- return 1;
|
|
|
5fb29d |
- }
|
|
|
5fb29d |
+ if (!efi_variables_supported())
|
|
|
5fb29d |
+ errx(2, "EFI variables are not supported on this system.");
|
|
|
5fb29d |
|
|
|
5fb29d |
read_boot_var_names(&boot_names);
|
|
|
5fb29d |
read_vars(boot_names, &boot_entry_list);
|
|
|
5fb29d |
set_var_nums(&boot_entry_list);
|
|
|
5fb29d |
|
|
|
5fb29d |
if (opts.delete_boot) {
|
|
|
5fb29d |
- if (opts.bootnum == -1) {
|
|
|
5fb29d |
- fprintf(stderr, "\nYou must specify a boot entry to delete (see the -b option).\n\n");
|
|
|
5fb29d |
- return 1;
|
|
|
5fb29d |
- }
|
|
|
5fb29d |
+ if (opts.bootnum == -1)
|
|
|
5fb29d |
+ errx(3, "You must specify a boot entry to delete "
|
|
|
5fb29d |
+ "(see the -b option).");
|
|
|
5fb29d |
else
|
|
|
5fb29d |
ret = delete_boot_var(opts.bootnum);
|
|
|
5fb29d |
}
|
|
|
5fb29d |
|
|
|
5fb29d |
if (opts.active >= 0) {
|
|
|
5fb29d |
- if (opts.bootnum == -1) {
|
|
|
5fb29d |
- fprintf(stderr, "\nYou must specify a boot entry to activate (see the -b option).\n\n");
|
|
|
5fb29d |
- return 1;
|
|
|
5fb29d |
- }
|
|
|
5fb29d |
+ if (opts.bootnum == -1)
|
|
|
5fb29d |
+ errx(4, "You must specify a boot entry to activate "
|
|
|
5fb29d |
+ "(see the -b option");
|
|
|
5fb29d |
else
|
|
|
5fb29d |
ret=set_active_state();
|
|
|
5fb29d |
}
|
|
|
5fb29d |
@@ -1212,47 +1230,57 @@ main(int argc, char **argv)
|
|
|
5fb29d |
if (opts.create) {
|
|
|
5fb29d |
warn_duplicate_name(&boot_entry_list);
|
|
|
5fb29d |
new_boot = make_boot_var(&boot_entry_list);
|
|
|
5fb29d |
- if (!new_boot) {
|
|
|
5fb29d |
- fprintf(stderr, "\nCould not prepare boot variable: %m\n\n");
|
|
|
5fb29d |
- return 1;
|
|
|
5fb29d |
- }
|
|
|
5fb29d |
+ if (!new_boot)
|
|
|
5fb29d |
+ err(5, "Could not prepare boot variable");
|
|
|
5fb29d |
|
|
|
5fb29d |
/* Put this boot var in the right BootOrder */
|
|
|
5fb29d |
if (new_boot)
|
|
|
5fb29d |
ret=add_to_boot_order(new_boot->num);
|
|
|
5fb29d |
+ if (ret)
|
|
|
5fb29d |
+ err(6, "Could not add entry to BootOrder");
|
|
|
5fb29d |
}
|
|
|
5fb29d |
|
|
|
5fb29d |
if (opts.delete_bootorder) {
|
|
|
5fb29d |
ret = efi_del_variable(EFI_GLOBAL_GUID, "BootOrder");
|
|
|
5fb29d |
+ err(7, "Could not remove entry from BootOrder");
|
|
|
5fb29d |
}
|
|
|
5fb29d |
|
|
|
5fb29d |
if (opts.bootorder) {
|
|
|
5fb29d |
ret = set_boot_order(opts.keep_old_entries);
|
|
|
5fb29d |
+ if (ret)
|
|
|
5fb29d |
+ err(8, "Could not set BootOrder");
|
|
|
5fb29d |
}
|
|
|
5fb29d |
|
|
|
5fb29d |
if (opts.deduplicate) {
|
|
|
5fb29d |
ret = remove_dupes_from_boot_order();
|
|
|
5fb29d |
+ if (ret)
|
|
|
5fb29d |
+ err(9, "Could not set BootOrder");
|
|
|
5fb29d |
}
|
|
|
5fb29d |
|
|
|
5fb29d |
if (opts.delete_bootnext) {
|
|
|
5fb29d |
ret = efi_del_variable(EFI_GLOBAL_GUID, "BootNext");
|
|
|
5fb29d |
+ if (ret)
|
|
|
5fb29d |
+ err(10, "Could not set BootNext");
|
|
|
5fb29d |
}
|
|
|
5fb29d |
|
|
|
5fb29d |
if (opts.delete_timeout) {
|
|
|
5fb29d |
ret = efi_del_variable(EFI_GLOBAL_GUID, "Timeout");
|
|
|
5fb29d |
+ if (ret)
|
|
|
5fb29d |
+ err(11, "Could not delete Timeout");
|
|
|
5fb29d |
}
|
|
|
5fb29d |
|
|
|
5fb29d |
if (opts.bootnext >= 0) {
|
|
|
5fb29d |
- if (!is_current_boot_entry(opts.bootnext & 0xFFFF)){
|
|
|
5fb29d |
- fprintf (stderr,"\n\nboot entry %X does not exist\n\n",
|
|
|
5fb29d |
- opts.bootnext);
|
|
|
5fb29d |
- return 1;
|
|
|
5fb29d |
- }
|
|
|
5fb29d |
- ret=set_boot_u16("BootNext", opts.bootnext & 0xFFFF);
|
|
|
5fb29d |
+ if (!is_current_boot_entry(opts.bootnext & 0xFFFF))
|
|
|
5fb29d |
+ errx(12, "Boot entry %X does not exist", opts.bootnext);
|
|
|
5fb29d |
+ ret = set_boot_u16("BootNext", opts.bootnext & 0xFFFF);
|
|
|
5fb29d |
+ if (ret)
|
|
|
5fb29d |
+ err(13, "Could not set BootNext");
|
|
|
5fb29d |
}
|
|
|
5fb29d |
|
|
|
5fb29d |
if (opts.set_timeout) {
|
|
|
5fb29d |
- ret=set_boot_u16("Timeout", opts.timeout);
|
|
|
5fb29d |
+ ret = set_boot_u16("Timeout", opts.timeout);
|
|
|
5fb29d |
+ if (ret)
|
|
|
5fb29d |
+ err(14, "Could not set Timeout");
|
|
|
5fb29d |
}
|
|
|
5fb29d |
|
|
|
5fb29d |
if (!opts.quiet && ret == 0) {
|
|
|
5fb29d |
diff --git a/src/lib/efi.c b/src/lib/efi.c
|
|
|
5fb29d |
index 7cdc884..d19c00d 100644
|
|
|
5fb29d |
--- a/src/lib/efi.c
|
|
|
5fb29d |
+++ b/src/lib/efi.c
|
|
|
5fb29d |
@@ -19,6 +19,7 @@
|
|
|
5fb29d |
*/
|
|
|
5fb29d |
|
|
|
5fb29d |
#include <ctype.h>
|
|
|
5fb29d |
+#include <err.h>
|
|
|
5fb29d |
#include <stdio.h>
|
|
|
5fb29d |
#include <stdlib.h>
|
|
|
5fb29d |
#include <string.h>
|
|
|
5fb29d |
@@ -502,7 +503,6 @@ static ssize_t
|
|
|
5fb29d |
make_disk_load_option(char *disk, uint8_t *buf, size_t size)
|
|
|
5fb29d |
{
|
|
|
5fb29d |
int disk_fd=0;
|
|
|
5fb29d |
- char buffer[80];
|
|
|
5fb29d |
char signature[16];
|
|
|
5fb29d |
int rc, edd_version=0;
|
|
|
5fb29d |
uint8_t mbr_type=0, signature_type=0;
|
|
|
5fb29d |
@@ -514,11 +514,8 @@ make_disk_load_option(char *disk, uint8_t *buf, size_t size)
|
|
|
5fb29d |
memset(signature, 0, sizeof(signature));
|
|
|
5fb29d |
|
|
|
5fb29d |
disk_fd = open(opts.disk, O_RDWR);
|
|
|
5fb29d |
- if (disk_fd == -1) {
|
|
|
5fb29d |
- sprintf(buffer, "Could not open disk %s", opts.disk);
|
|
|
5fb29d |
- perror(buffer);
|
|
|
5fb29d |
- return -1;
|
|
|
5fb29d |
- }
|
|
|
5fb29d |
+ if (disk_fd == -1)
|
|
|
5fb29d |
+ err(5, "Could not open disk %s", opts.disk);
|
|
|
5fb29d |
|
|
|
5fb29d |
if (opts.edd_version) {
|
|
|
5fb29d |
edd_version = get_edd_version();
|
|
|
5fb29d |
@@ -539,12 +536,10 @@ make_disk_load_option(char *disk, uint8_t *buf, size_t size)
|
|
|
5fb29d |
&part_start, &part_size, signature,
|
|
|
5fb29d |
&mbr_type, &signature_type);
|
|
|
5fb29d |
close(disk_fd);
|
|
|
5fb29d |
- if (rc) {
|
|
|
5fb29d |
- fprintf(stderr, "Error: no partition information on disk %s.\n"
|
|
|
5fb29d |
- " Cowardly refusing to create a boot option.\n",
|
|
|
5fb29d |
+ if (rc)
|
|
|
5fb29d |
+ errx(5, "No partition information on disk %s.\n"
|
|
|
5fb29d |
+ "Cowardly refusing to create a boot option.\n",
|
|
|
5fb29d |
opts.disk);
|
|
|
5fb29d |
- return -1;
|
|
|
5fb29d |
- }
|
|
|
5fb29d |
|
|
|
5fb29d |
needed = make_harddrive_device_path(opts.part, part_start, part_size,
|
|
|
5fb29d |
(uint8_t *)signature, mbr_type,
|
|
|
5fb29d |
@@ -724,10 +719,13 @@ make_linux_load_option(uint8_t **data, size_t *data_size)
|
|
|
5fb29d |
uint8_t *buf;
|
|
|
5fb29d |
ssize_t needed;
|
|
|
5fb29d |
off_t buf_offset = 0, desc_offset;
|
|
|
5fb29d |
+ int rc;
|
|
|
5fb29d |
|
|
|
5fb29d |
load_option = calloc(1, sizeof (*load_option));
|
|
|
5fb29d |
- if (load_option == NULL)
|
|
|
5fb29d |
+ if (load_option == NULL) {
|
|
|
5fb29d |
+ fprintf(stderr, "efibootmgr: %m\n");
|
|
|
5fb29d |
return -1;
|
|
|
5fb29d |
+ }
|
|
|
5fb29d |
buf = (uint8_t *)load_option;
|
|
|
5fb29d |
buf_offset = 0;
|
|
|
5fb29d |
|
|
|
5fb29d |
@@ -755,21 +753,33 @@ make_linux_load_option(uint8_t **data, size_t *data_size)
|
|
|
5fb29d |
if (opts.iface) {
|
|
|
5fb29d |
needed = make_net_load_option(opts.iface, NULL, 0);
|
|
|
5fb29d |
if (needed < 0) {
|
|
|
5fb29d |
+ fprintf(stderr, "efibootmgr: could not create load option: %m\n");
|
|
|
5fb29d |
free(buf);
|
|
|
5fb29d |
return needed;
|
|
|
5fb29d |
}
|
|
|
5fb29d |
buf = extend(load_option, load_option_size, needed);
|
|
|
5fb29d |
- make_net_load_option(opts.iface, buf + buf_offset, needed);
|
|
|
5fb29d |
+ rc = make_net_load_option(opts.iface, buf + buf_offset, needed);
|
|
|
5fb29d |
buf_offset += needed;
|
|
|
5fb29d |
+ if (rc < 0) {
|
|
|
5fb29d |
+ fprintf(stderr, "efibootmgr: could not create load option: %m\n");
|
|
|
5fb29d |
+ free(buf);
|
|
|
5fb29d |
+ return rc;
|
|
|
5fb29d |
+ }
|
|
|
5fb29d |
} else {
|
|
|
5fb29d |
needed = make_disk_load_option(opts.iface, NULL, 0);
|
|
|
5fb29d |
if (needed < 0) {
|
|
|
5fb29d |
+ fprintf(stderr, "efibootmgr: could not create load option: %m\n");
|
|
|
5fb29d |
free(buf);
|
|
|
5fb29d |
return needed;
|
|
|
5fb29d |
}
|
|
|
5fb29d |
buf = extend(load_option, load_option_size, needed);
|
|
|
5fb29d |
- make_disk_load_option(opts.iface, buf + buf_offset, needed);
|
|
|
5fb29d |
+ rc = make_disk_load_option(opts.iface, buf + buf_offset, needed);
|
|
|
5fb29d |
buf_offset += needed;
|
|
|
5fb29d |
+ if (rc < 0) {
|
|
|
5fb29d |
+ fprintf(stderr, "efibootmgr: could not create load option: %m\n");
|
|
|
5fb29d |
+ free(buf);
|
|
|
5fb29d |
+ return rc;
|
|
|
5fb29d |
+ }
|
|
|
5fb29d |
}
|
|
|
5fb29d |
|
|
|
5fb29d |
load_option->file_path_list_length = buf_offset - desc_offset;
|
|
|
5fb29d |
@@ -792,25 +802,25 @@ append_extra_args_ascii(uint8_t **data, size_t *data_size)
|
|
|
5fb29d |
int i;
|
|
|
5fb29d |
unsigned long usedchars=0;
|
|
|
5fb29d |
|
|
|
5fb29d |
- if (!data || *data)
|
|
|
5fb29d |
+ if (!data || *data) {
|
|
|
5fb29d |
+ errno = EINVAL;
|
|
|
5fb29d |
return -1;
|
|
|
5fb29d |
+ }
|
|
|
5fb29d |
|
|
|
5fb29d |
for (i=opts.optind; i < opts.argc; i++) {
|
|
|
5fb29d |
- int l = strlen(opts.argv[i]) + 1;
|
|
|
5fb29d |
+ int l = strlen(opts.argv[i]);
|
|
|
5fb29d |
int space = (i < opts.argc - 1) ? 1: 0;
|
|
|
5fb29d |
- uint8_t *tmp = realloc(new_data, (usedchars + l + space));
|
|
|
5fb29d |
+ uint8_t *tmp = realloc(new_data, (usedchars + l + space + 1));
|
|
|
5fb29d |
if (tmp == NULL)
|
|
|
5fb29d |
return -1;
|
|
|
5fb29d |
new_data = tmp;
|
|
|
5fb29d |
p = (char *)new_data + usedchars;
|
|
|
5fb29d |
strcpy(p, opts.argv[i]);
|
|
|
5fb29d |
usedchars += l;
|
|
|
5fb29d |
- p += l;
|
|
|
5fb29d |
/* Put a space between args */
|
|
|
5fb29d |
if (space)
|
|
|
5fb29d |
- p[usedchars++] = ' ';
|
|
|
5fb29d |
- else
|
|
|
5fb29d |
- p[usedchars] = '\0';
|
|
|
5fb29d |
+ new_data[usedchars++] = ' ';
|
|
|
5fb29d |
+ new_data[usedchars] = '\0';
|
|
|
5fb29d |
}
|
|
|
5fb29d |
|
|
|
5fb29d |
if (!new_data)
|
|
|
5fb29d |
@@ -829,8 +839,10 @@ append_extra_args_unicode(uint8_t **data, size_t *data_size)
|
|
|
5fb29d |
int i;
|
|
|
5fb29d |
unsigned long usedchars=0;
|
|
|
5fb29d |
|
|
|
5fb29d |
- if (!data || *data)
|
|
|
5fb29d |
+ if (!data || *data) {
|
|
|
5fb29d |
+ errno = EINVAL;
|
|
|
5fb29d |
return -1;
|
|
|
5fb29d |
+ }
|
|
|
5fb29d |
|
|
|
5fb29d |
for (i = opts.optind; i < opts.argc; i++) {
|
|
|
5fb29d |
int l = strlen(opts.argv[i]) + 1;
|
|
|
5fb29d |
@@ -871,37 +883,31 @@ append_extra_args_file(uint8_t **data, size_t *data_size)
|
|
|
5fb29d |
size_t maxchars = 0;
|
|
|
5fb29d |
char *buffer;
|
|
|
5fb29d |
|
|
|
5fb29d |
- if (!data) {
|
|
|
5fb29d |
- fprintf(stderr, "internal error\n");
|
|
|
5fb29d |
- exit(1);
|
|
|
5fb29d |
+ if (!data || *data) {
|
|
|
5fb29d |
+ errno = EINVAL;
|
|
|
5fb29d |
+ return -1;
|
|
|
5fb29d |
}
|
|
|
5fb29d |
|
|
|
5fb29d |
if (file && strncmp(file, "-", 1))
|
|
|
5fb29d |
fd = open(file, O_RDONLY);
|
|
|
5fb29d |
|
|
|
5fb29d |
- if (fd == -1) {
|
|
|
5fb29d |
- perror("Failed to open extra arguments file");
|
|
|
5fb29d |
- exit(1);
|
|
|
5fb29d |
- }
|
|
|
5fb29d |
+ if (fd < 0)
|
|
|
5fb29d |
+ return -1;
|
|
|
5fb29d |
|
|
|
5fb29d |
buffer = malloc(maxchars);
|
|
|
5fb29d |
do {
|
|
|
5fb29d |
if (maxchars - appended == 0) {
|
|
|
5fb29d |
maxchars += 1024;
|
|
|
5fb29d |
char *tmp = realloc(buffer, maxchars);
|
|
|
5fb29d |
- if (tmp == NULL) {
|
|
|
5fb29d |
- perror("Error reading extra arguments file");
|
|
|
5fb29d |
- exit(1);
|
|
|
5fb29d |
- }
|
|
|
5fb29d |
+ if (tmp == NULL)
|
|
|
5fb29d |
+ return -1;
|
|
|
5fb29d |
buffer = tmp;
|
|
|
5fb29d |
}
|
|
|
5fb29d |
num_read = read(fd, buffer + appended, maxchars - appended);
|
|
|
5fb29d |
- if (num_read < 0) {
|
|
|
5fb29d |
- perror("Error reading extra arguments file");
|
|
|
5fb29d |
- exit(1);
|
|
|
5fb29d |
- } else if (num_read > 0) {
|
|
|
5fb29d |
+ if (num_read < 0)
|
|
|
5fb29d |
+ return -1;
|
|
|
5fb29d |
+ else if (num_read > 0)
|
|
|
5fb29d |
appended += num_read;
|
|
|
5fb29d |
- }
|
|
|
5fb29d |
} while (num_read > 0);
|
|
|
5fb29d |
|
|
|
5fb29d |
if (fd != STDIN_FILENO)
|
|
|
5fb29d |
@@ -935,14 +941,18 @@ append_extra_args(uint8_t **data, size_t *data_size)
|
|
|
5fb29d |
|
|
|
5fb29d |
if (opts.extra_opts_file) {
|
|
|
5fb29d |
ret = append_extra_args_file(&new_data, &new_data_size);
|
|
|
5fb29d |
- if (ret < 0)
|
|
|
5fb29d |
+ if (ret < 0) {
|
|
|
5fb29d |
+ fprintf(stderr, "efibootmgr: append_extra_args: %m\n");
|
|
|
5fb29d |
return -1;
|
|
|
5fb29d |
+ }
|
|
|
5fb29d |
}
|
|
|
5fb29d |
if (new_data_size) {
|
|
|
5fb29d |
ret = add_new_data(data, data_size, new_data, new_data_size);
|
|
|
5fb29d |
free(new_data);
|
|
|
5fb29d |
- if (ret < 0)
|
|
|
5fb29d |
+ if (ret < 0) {
|
|
|
5fb29d |
+ fprintf(stderr, "efibootmgr: append_extra_args: %m\n");
|
|
|
5fb29d |
return -1;
|
|
|
5fb29d |
+ }
|
|
|
5fb29d |
new_data = NULL;
|
|
|
5fb29d |
new_data_size = 0;
|
|
|
5fb29d |
}
|
|
|
5fb29d |
@@ -952,6 +962,7 @@ append_extra_args(uint8_t **data, size_t *data_size)
|
|
|
5fb29d |
else
|
|
|
5fb29d |
ret = append_extra_args_ascii(&new_data, &new_data_size);
|
|
|
5fb29d |
if (ret < 0) {
|
|
|
5fb29d |
+ fprintf(stderr, "efibootmgr: append_extra_args: %m\n");
|
|
|
5fb29d |
if (new_data) /* this can't happen, but covscan believes */
|
|
|
5fb29d |
free(new_data);
|
|
|
5fb29d |
return -1;
|
|
|
5fb29d |
@@ -960,8 +971,10 @@ append_extra_args(uint8_t **data, size_t *data_size)
|
|
|
5fb29d |
ret = add_new_data(data, data_size, new_data, new_data_size);
|
|
|
5fb29d |
free(new_data);
|
|
|
5fb29d |
new_data = NULL;
|
|
|
5fb29d |
- if (ret < 0)
|
|
|
5fb29d |
+ if (ret < 0) {
|
|
|
5fb29d |
+ fprintf(stderr, "efibootmgr: append_extra_args: %m\n");
|
|
|
5fb29d |
return -1;
|
|
|
5fb29d |
+ }
|
|
|
5fb29d |
new_data_size = 0;
|
|
|
5fb29d |
}
|
|
|
5fb29d |
|
|
|
5fb29d |
diff --git a/src/man/man8/efibootmgr.8 b/src/man/man8/efibootmgr.8
|
|
|
5fb29d |
index 96071d7..423bc16 100644
|
|
|
5fb29d |
--- a/src/man/man8/efibootmgr.8
|
|
|
5fb29d |
+++ b/src/man/man8/efibootmgr.8
|
|
|
5fb29d |
@@ -93,9 +93,6 @@ Partition number containing the bootloader (defaults to 1)
|
|
|
5fb29d |
\fB-q | --quiet\fR
|
|
|
5fb29d |
Quiet mode - supresses output.
|
|
|
5fb29d |
.TP
|
|
|
5fb29d |
-\fB--test \fIfilename\fB\fR
|
|
|
5fb29d |
-Don't write to NVRAM, write to \fIfilename\fR\&.
|
|
|
5fb29d |
-.TP
|
|
|
5fb29d |
\fB-t | --timeout \fIseconds\fB\fR
|
|
|
5fb29d |
Boot Manager timeout, in \fIseconds\fR\&.
|
|
|
5fb29d |
.TP
|
|
|
5fb29d |
--
|
|
|
5fb29d |
1.9.3
|
|
|
5fb29d |
|