From 6f302ce676a2b822564cc7361c527da74d0067a4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 23 Nov 2017 22:02:10 +0100 Subject: [PATCH 1/3] logind: don't propagate firmware misbehaviours to bus clients If for some reason we can't query the firmware state, don't propagate that to clients, but instead log about it, and claim that reboot-to-firmware is not available (which is the right answer, since it is not working). Let's log about this though, as this is certainly relevant to know, even though not for the client. --- src/login/logind-dbus.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index df8cb369fb..df14c9e711 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -2397,7 +2397,7 @@ static int property_get_reboot_to_firmware_setup( r = efi_get_reboot_to_firmware(); if (r < 0 && r != -EOPNOTSUPP) - return r; + log_warning_errno(r, "Failed to determine reboot-to-firmware state: %m"); return sd_bus_message_append(reply, "b", r > 0); } @@ -2451,10 +2451,12 @@ static int method_can_reboot_to_firmware_setup( assert(m); r = efi_reboot_to_firmware_supported(); - if (r == -EOPNOTSUPP) + if (r < 0) { + if (r != -EOPNOTSUPP) + log_warning_errno(errno, "Failed to determine whether reboot to firmware is supported: %m"); + return sd_bus_reply_method_return(message, "s", "na"); - else if (r < 0) - return r; + } r = bus_test_polkit(message, CAP_SYS_ADMIN, From e22c567fea0c6eb7599bce5f7aeb1273e8861072 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 23 Nov 2017 22:05:34 +0100 Subject: [PATCH 2/3] efivars: minor coding style improvements --- src/shared/efivars.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/shared/efivars.c b/src/shared/efivars.c index 845ab0fa58..cf2966fd5c 100644 --- a/src/shared/efivars.c +++ b/src/shared/efivars.c @@ -85,10 +85,10 @@ bool is_efi_boot(void) { } static int read_flag(const char *varname) { - int r; _cleanup_free_ void *v = NULL; - size_t s; uint8_t b; + size_t s; + int r; r = efi_get_variable(EFI_VENDOR_GLOBAL, varname, NULL, &v, &s); if (r < 0) @@ -98,8 +98,7 @@ static int read_flag(const char *varname) { return -EINVAL; b = *(uint8_t *)v; - r = b > 0; - return r; + return b > 0; } bool is_efi_secure_boot(void) { @@ -111,10 +110,10 @@ bool is_efi_secure_boot_setup_mode(void) { } int efi_reboot_to_firmware_supported(void) { - int r; - size_t s; - uint64_t b; _cleanup_free_ void *v = NULL; + uint64_t b; + size_t s; + int r; if (!is_efi_boot() || detect_container() > 0) return -EOPNOTSUPP; @@ -122,18 +121,20 @@ int efi_reboot_to_firmware_supported(void) { r = efi_get_variable(EFI_VENDOR_GLOBAL, "OsIndicationsSupported", NULL, &v, &s); if (r < 0) return r; - else if (s != sizeof(uint64_t)) + if (s != sizeof(uint64_t)) return -EINVAL; - b = *(uint64_t *)v; - b &= EFI_OS_INDICATIONS_BOOT_TO_FW_UI; - return b > 0 ? 0 : -EOPNOTSUPP; + b = *(uint64_t*) v; + if (!(b & EFI_OS_INDICATIONS_BOOT_TO_FW_UI)) + return -EOPNOTSUPP; /* bit unset? it's not supported then */ + + return 0; } static int get_os_indications(uint64_t *os_indication) { - int r; - size_t s; _cleanup_free_ void *v = NULL; + size_t s; + int r; r = efi_reboot_to_firmware_supported(); if (r < 0) From 846ab104cade96599f8a27cc8a0c54dc919f908f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 23 Nov 2017 22:05:46 +0100 Subject: [PATCH 3/3] efivars: if OsIndicationsSupported does not exist, assume that reboot-to-firmware is not available It's not advertised and hence not available. Fixes: #7424 --- src/shared/efivars.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/shared/efivars.c b/src/shared/efivars.c index cf2966fd5c..9ca51cf750 100644 --- a/src/shared/efivars.c +++ b/src/shared/efivars.c @@ -119,6 +119,8 @@ int efi_reboot_to_firmware_supported(void) { return -EOPNOTSUPP; r = efi_get_variable(EFI_VENDOR_GLOBAL, "OsIndicationsSupported", NULL, &v, &s); + if (r == -ENOENT) /* variable doesn't exist? it's not supported then */ + return -EOPNOTSUPP; if (r < 0) return r; if (s != sizeof(uint64_t))