]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #10802 from poettering/hide-only-on
authorLennart Poettering <lennart@poettering.net>
Fri, 16 Nov 2018 16:53:01 +0000 (17:53 +0100)
committerGitHub <noreply@github.com>
Fri, 16 Nov 2018 16:53:01 +0000 (17:53 +0100)
man: let's deprecate PermissionsStartOnly=

20 files changed:
coccinelle/redundant-if.cocci [new file with mode: 0644]
man/systemd-boot.xml
src/basic/cgroup-util.c
src/basic/locale-util.c
src/basic/locale-util.h
src/boot/bootctl.c
src/boot/efi/boot.c
src/boot/efi/util.c
src/boot/efi/util.h
src/core/manager.c
src/fuzz/fuzz-main.c
src/libsystemd/sd-bus/bus-message.c
src/login/logind-core.c
src/login/logind-dbus.c
src/login/logind.h
src/login/org.freedesktop.login1.policy
src/resolve/resolved-dns-dnssec.c
src/shared/efivars.c
src/shared/efivars.h
src/test/test-locale-util.c

diff --git a/coccinelle/redundant-if.cocci b/coccinelle/redundant-if.cocci
new file mode 100644 (file)
index 0000000..515e36e
--- /dev/null
@@ -0,0 +1,54 @@
+@@
+expression r;
+@@
+- if (r < 0)
+-         return r;
+- if (r == 0)
+-         return 0;
++ if (r <= 0)
++         return r;
+@@
+expression r;
+@@
+- if (r == 0)
+-         return 0;
+- if (r < 0)
+-         return r;
++ if (r <= 0)
++         return r;
+@@
+expression r;
+@@
+- if (r < 0)
+-         return r;
+- if (r == 0)
+-         return r;
++ if (r <= 0)
++         return r;
+@@
+expression r;
+@@
+- if (r == 0)
+-         return r;
+- if (r < 0)
+-         return r;
++ if (r <= 0)
++         return r;
+@@
+expression r;
+@@
+- if (r < 0)
+-         return r;
+- if (r > 0)
+-         return r;
++ if (r != 0)
++         return r;
+@@
+expression r;
+@@
+- if (r > 0)
+-         return r;
+- if (r < 0)
+-         return r;
++ if (r != 0)
++         return r;
index 3b726e63a4fa7646488840a2cc08d682aeaaa3c0..e5374269706b393554b6e9e646c0777ddbe77a5e 100644 (file)
 
       <varlistentry>
         <term><varname>LoaderConfigTimeout</varname></term>
-        <listitem><para>The menu time-out. Read by the boot loader. (Also, modified by it when the
-        <keycap>t</keycap>/<keycap>T</keycap> keys are used, see above.)</para></listitem>
+        <term><varname>LoaderConfigTimeoutOneShot</varname></term>
+        <listitem><para>The menu time-out in seconds. Read by the boot loader. <varname>LoaderConfigTimeout</varname>
+        is maintained persistently, while <varname>LoaderConfigTimeoutOneShot</varname> is a one-time override which is
+        read once (in which case it takes precedence over <varname>LoaderConfigTimeout</varname>) and then
+        removed. <varname>LoaderConfigTimeout</varname> may be manipulated with the
+        <keycap>t</keycap>/<keycap>T</keycap> keys, see above.)</para></listitem>
       </varlistentry>
 
       <varlistentry>
         loader.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>LoaderFeatures</varname></term>
+
+        <listitem><para>A set of flags indicating the features the boot loader supports. Set by the boot loader. Use
+        <citerefentry><refentrytitle>bootctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> to view this
+        data.</para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>LoaderFirmwareInfo</varname></term>
         <term><varname>LoaderFirmwareType</varname></term>
index 5c02f0cb350a971c3648408a631999ffc19ac86c..70c91249d7a8da8805d4fa8903793873f82741a2 100644 (file)
@@ -199,10 +199,8 @@ int cg_rmdir(const char *controller, const char *path) {
                 return -errno;
 
         r = cg_hybrid_unified();
-        if (r < 0)
+        if (r <= 0)
                 return r;
-        if (r == 0)
-                return 0;
 
         if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
                 r = cg_rmdir(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path);
index 9ad51a197253c5be31e00c114a015728aac5821d..7e479d605a782027003abad386632bde19c30d37 100644 (file)
@@ -369,6 +369,8 @@ const char *special_glyph(SpecialGlyph code) {
                         [MDASH]              = "-",
                         [ELLIPSIS]           = "...",
                         [MU]                 = "u",
+                        [CHECK_MARK]         = "+",
+                        [CROSS_MARK]         = "-",
                 },
 
                 /* UTF-8 */
@@ -383,6 +385,8 @@ const char *special_glyph(SpecialGlyph code) {
                         [MDASH]              = "\342\200\223",             /* – */
                         [ELLIPSIS]           = "\342\200\246",             /* … */
                         [MU]                 = "\316\274",                 /* μ */
+                        [CHECK_MARK]         = "\342\234\223",             /* ✓ */
+                        [CROSS_MARK]         = "\342\234\227",             /* ✗ */
                 },
         };
 
index 14beece6d8bd6d8e47965e5cd15ffd3f31fdc14a..ea624e99082629db09f66b0e59597ac012d09210 100644 (file)
@@ -49,6 +49,8 @@ typedef enum {
         MDASH,
         ELLIPSIS,
         MU,
+        CHECK_MARK,
+        CROSS_MARK,
         _SPECIAL_GLYPH_MAX
 } SpecialGlyph;
 
index 7a20965b6a8e61e4b3fe31921213cbe02ced9c1c..427faf8b242ab0708c3e965b72f7fb2368430475 100644 (file)
@@ -968,14 +968,28 @@ static int verb_status(int argc, char *argv[], void *userdata) {
         (void) pager_open(arg_pager_flags);
 
         if (is_efi_boot()) {
+                static const struct {
+                        uint64_t flag;
+                        const char *name;
+                } flags[] = {
+                        { EFI_LOADER_FEATURE_BOOT_COUNTING,           "Boot counting"                 },
+                        { EFI_LOADER_FEATURE_CONFIG_TIMEOUT,          "Menu timeout control"          },
+                        { EFI_LOADER_FEATURE_CONFIG_TIMEOUT_ONE_SHOT, "One-shot menu timeout control" },
+                        { EFI_LOADER_FEATURE_ENTRY_DEFAULT,           "Default entry control"         },
+                        { EFI_LOADER_FEATURE_ENTRY_ONESHOT,           "One-shot entry control"        },
+                };
+
                 _cleanup_free_ char *fw_type = NULL, *fw_info = NULL, *loader = NULL, *loader_path = NULL, *stub = NULL;
                 sd_id128_t loader_part_uuid = SD_ID128_NULL;
+                uint64_t loader_features = 0;
+                size_t i;
 
                 read_loader_efi_var("LoaderFirmwareType", &fw_type);
                 read_loader_efi_var("LoaderFirmwareInfo", &fw_info);
                 read_loader_efi_var("LoaderInfo", &loader);
                 read_loader_efi_var("StubInfo", &stub);
                 read_loader_efi_var("LoaderImageIdentifier", &loader_path);
+                (void) efi_loader_get_features(&loader_features);
 
                 if (loader_path)
                         efi_tilt_backslashes(loader_path);
@@ -992,6 +1006,20 @@ static int verb_status(int argc, char *argv[], void *userdata) {
 
                 printf("Current Boot Loader:\n");
                 printf("      Product: %s%s%s\n", ansi_highlight(), strna(loader), ansi_normal());
+
+                for (i = 0; i < ELEMENTSOF(flags); i++) {
+
+                        if (i == 0)
+                                printf("     Features: ");
+                        else
+                                printf("               ");
+
+                        if (FLAGS_SET(loader_features, flags[i].flag))
+                                printf("%s%s%s %s\n", ansi_highlight_green(), special_glyph(CHECK_MARK), ansi_normal(), flags[i].name);
+                        else
+                                printf("%s%s%s %s\n", ansi_highlight_red(), special_glyph(CROSS_MARK), ansi_normal(), flags[i].name);
+                }
+
                 if (stub)
                         printf("         Stub: %s\n", stub);
                 if (!sd_id128_is_null(loader_part_uuid))
index 4ff7594a9a61afea34e6450d422e63cfca3b22d5..d3a26fd7a0e0d0c18197ce1dc4f8febf0a2a85e9 100644 (file)
@@ -62,6 +62,7 @@ typedef struct {
         BOOLEAN editor;
         BOOLEAN auto_entries;
         BOOLEAN auto_firmware;
+        BOOLEAN force_menu;
         UINTN console_mode;
         enum console_mode_change_type console_mode_change;
 } Config;
@@ -385,10 +386,10 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
         Print(L"\n--- press key ---\n\n");
         console_key_read(&key, TRUE);
 
-        Print(L"timeout:                %d\n", config->timeout_sec);
+        Print(L"timeout:                %u\n", config->timeout_sec);
         if (config->timeout_sec_efivar >= 0)
                 Print(L"timeout (EFI var):      %d\n", config->timeout_sec_efivar);
-        Print(L"timeout (config):       %d\n", config->timeout_sec_config);
+        Print(L"timeout (config):       %u\n", config->timeout_sec_config);
         if (config->entry_default_pattern)
                 Print(L"default pattern:        '%s'\n", config->entry_default_pattern);
         Print(L"editor:                 %s\n", yes_no(config->editor));
@@ -403,7 +404,8 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
         Print(L"\n");
 
         if (efivar_get_int(L"LoaderConfigTimeout", &i) == EFI_SUCCESS)
-                Print(L"LoaderConfigTimeout:    %d\n", i);
+                Print(L"LoaderConfigTimeout:    %u\n", i);
+
         if (config->entry_oneshot)
                 Print(L"LoaderEntryOneShot:     %s\n", config->entry_oneshot);
         if (efivar_get(L"LoaderDevicePartUUID", &partstr) == EFI_SUCCESS)
@@ -1402,9 +1404,11 @@ static VOID config_load_defaults(Config *config, EFI_FILE *root_dir) {
         UINTN sec;
         EFI_STATUS err;
 
-        config->editor = TRUE;
-        config->auto_entries = TRUE;
-        config->auto_firmware = TRUE;
+        *config = (Config) {
+                .editor = TRUE,
+                .auto_entries = TRUE,
+                .auto_firmware = TRUE,
+        };
 
         err = file_read(root_dir, L"\\loader\\loader.conf", 0, 0, &content, NULL);
         if (!EFI_ERROR(err))
@@ -1412,10 +1416,19 @@ static VOID config_load_defaults(Config *config, EFI_FILE *root_dir) {
 
         err = efivar_get_int(L"LoaderConfigTimeout", &sec);
         if (!EFI_ERROR(err)) {
-                config->timeout_sec_efivar = sec;
+                config->timeout_sec_efivar = sec > INTN_MAX ? INTN_MAX : sec;
                 config->timeout_sec = sec;
         } else
                 config->timeout_sec_efivar = -1;
+
+        err = efivar_get_int(L"LoaderConfigTimeoutOneShot", &sec);
+        if (!EFI_ERROR(err)) {
+                /* Unset variable now, after all it's "one shot". */
+                (void) efivar_set(L"LoaderConfigTimeoutOneShot", NULL, TRUE);
+
+                config->timeout_sec = sec;
+                config->force_menu = TRUE; /* force the menu when this is set */
+        }
 }
 
 static VOID config_load_entries(
@@ -2061,6 +2074,14 @@ static VOID config_write_entries_to_variable(Config *config) {
 }
 
 EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
+        static const UINT64 loader_features =
+                (1ULL << 0) | /* I honour the LoaderConfigTimeout variable */
+                (1ULL << 1) | /* I honour the LoaderConfigTimeoutOneShot variable */
+                (1ULL << 2) | /* I honour the LoaderEntryDefault variable */
+                (1ULL << 3) | /* I honour the LoaderEntryOneShot variable */
+                (1ULL << 4) | /* I support boot counting */
+                0;
+
         _cleanup_freepool_ CHAR16 *infostr = NULL, *typestr = NULL;
         CHAR8 *b;
         UINTN size;
@@ -2084,6 +2105,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
         typestr = PoolPrint(L"UEFI %d.%02d", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff);
         efivar_set(L"LoaderFirmwareType", typestr, FALSE);
 
+        (void) efivar_set_raw(&loader_guid, L"LoaderFeatures", &loader_features, sizeof(loader_features), FALSE);
+
         err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image,
                                 image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
         if (EFI_ERROR(err)) {
@@ -2116,7 +2139,6 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
         loaded_image_path = DevicePathToStr(loaded_image->FilePath);
         efivar_set(L"LoaderImageIdentifier", loaded_image_path, FALSE);
 
-        ZeroMem(&config, sizeof(Config));
         config_load_defaults(&config, root_dir);
 
         /* scan /EFI/Linux/ directory */
@@ -2141,7 +2163,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
                 UINT64 osind = (UINT64)*b;
 
                 if (osind & EFI_OS_INDICATIONS_BOOT_TO_FW_UI)
-                        config_entry_add_call(&config, L"auto-reboot-into-firmware-ui", L"Reboot Into Firmware Interface", reboot_into_firmware);
+                        config_entry_add_call(&config, L"auto-reboot-to-firmware-setup", L"Reboot Into Firmware Interface", reboot_into_firmware);
                 FreePool(b);
         }
 
@@ -2166,7 +2188,9 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
         }
 
         /* select entry or show menu when key is pressed or timeout is set */
-        if (config.timeout_sec == 0) {
+        if (config.force_menu || config.timeout_sec > 0)
+                menu = TRUE;
+        else {
                 UINT64 key;
 
                 err = console_key_read(&key, FALSE);
@@ -2180,8 +2204,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
                         else
                                 menu = TRUE;
                 }
-        } else
-                menu = TRUE;
+        }
 
         for (;;) {
                 ConfigEntry *entry;
@@ -2192,12 +2215,12 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
                         uefi_call_wrapper(BS->SetWatchdogTimer, 4, 0, 0x10000, 0, NULL);
                         if (!menu_run(&config, &entry, loaded_image_path))
                                 break;
+                }
 
-                        /* run special entry like "reboot" */
-                        if (entry->call) {
-                                entry->call();
-                                continue;
-                        }
+                /* run special entry like "reboot" */
+                if (entry->call) {
+                        entry->call();
+                        continue;
                 }
 
                 config_entry_bump_counters(entry, root_dir);
index fd4be681a538b45ea187758e5611a6f98f401078..f1f1674c59493f031db986044fbd5c699948a7a3 100644 (file)
@@ -39,7 +39,7 @@ UINT64 ticks_freq(VOID) {
         uefi_call_wrapper(BS->Stall, 1, 1000);
         ticks_end = ticks_read();
 
-        return (ticks_end - ticks_start) * 1000;
+        return (ticks_end - ticks_start) * 1000UL;
 }
 
 UINT64 time_usec(VOID) {
@@ -56,10 +56,13 @@ UINT64 time_usec(VOID) {
                         return 0;
         }
 
-        return 1000 * 1000 * ticks / freq;
+        return 1000UL * 1000UL * ticks / freq;
 }
 
-EFI_STATUS parse_boolean(CHAR8 *v, BOOLEAN *b) {
+EFI_STATUS parse_boolean(const CHAR8 *v, BOOLEAN *b) {
+        if (!v)
+                return EFI_INVALID_PARAMETER;
+
         if (strcmpa(v, (CHAR8 *)"1") == 0 ||
             strcmpa(v, (CHAR8 *)"yes") == 0 ||
             strcmpa(v, (CHAR8 *)"y") == 0 ||
@@ -79,46 +82,61 @@ EFI_STATUS parse_boolean(CHAR8 *v, BOOLEAN *b) {
         return EFI_INVALID_PARAMETER;
 }
 
-EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, CHAR16 *name, VOID *buf, UINTN size, BOOLEAN persistent) {
+EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const CHAR16 *name, const VOID *buf, UINTN size, BOOLEAN persistent) {
         UINT32 flags;
 
         flags = EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS;
         if (persistent)
                 flags |= EFI_VARIABLE_NON_VOLATILE;
 
-        return uefi_call_wrapper(RT->SetVariable, 5, name, (EFI_GUID *)vendor, flags, size, buf);
+        return uefi_call_wrapper(RT->SetVariable, 5, (CHAR16*) name, (EFI_GUID *)vendor, flags, size, (VOID*) buf);
 }
 
-EFI_STATUS efivar_set(CHAR16 *name, CHAR16 *value, BOOLEAN persistent) {
+EFI_STATUS efivar_set(const CHAR16 *name, const CHAR16 *value, BOOLEAN persistent) {
         return efivar_set_raw(&loader_guid, name, value, value ? (StrLen(value)+1) * sizeof(CHAR16) : 0, persistent);
 }
 
 EFI_STATUS efivar_set_int(CHAR16 *name, UINTN i, BOOLEAN persistent) {
         CHAR16 str[32];
 
-        SPrint(str, 32, L"%d", i);
+        SPrint(str, 32, L"%u", i);
         return efivar_set(name, str, persistent);
 }
 
-EFI_STATUS efivar_get(CHAR16 *name, CHAR16 **value) {
+EFI_STATUS efivar_get(const CHAR16 *name, CHAR16 **value) {
         _cleanup_freepool_ CHAR8 *buf = NULL;
+        EFI_STATUS err;
         CHAR16 *val;
         UINTN size;
-        EFI_STATUS err;
 
         err = efivar_get_raw(&loader_guid, name, &buf, &size);
         if (EFI_ERROR(err))
                 return err;
 
-        val = StrDuplicate((CHAR16 *)buf);
+        /* Make sure there are no incomplete characters in the buffer */
+        if ((size % 2) != 0)
+                return EFI_INVALID_PARAMETER;
+
+        /* Return buffer directly if it happens to be NUL terminated already */
+        if (size >= 2 && buf[size-2] == 0 && buf[size-1] == 0) {
+                *value = (CHAR16*) buf;
+                buf = NULL;
+                return EFI_SUCCESS;
+        }
+
+        /* Make sure a terminating NUL is available at the end */
+        val = AllocatePool(size + 2);
         if (!val)
                 return EFI_OUT_OF_RESOURCES;
 
+        CopyMem(val, buf, size);
+        val[size/2] = 0; /* NUL terminate */
+
         *value = val;
         return EFI_SUCCESS;
 }
 
-EFI_STATUS efivar_get_int(CHAR16 *name, UINTN *i) {
+EFI_STATUS efivar_get_int(const CHAR16 *name, UINTN *i) {
         _cleanup_freepool_ CHAR16 *val = NULL;
         EFI_STATUS err;
 
@@ -129,7 +147,7 @@ EFI_STATUS efivar_get_int(CHAR16 *name, UINTN *i) {
         return err;
 }
 
-EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, CHAR16 *name, CHAR8 **buffer, UINTN *size) {
+EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **buffer, UINTN *size) {
         _cleanup_freepool_ CHAR8 *buf = NULL;
         UINTN l;
         EFI_STATUS err;
@@ -139,7 +157,7 @@ EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, CHAR16 *name, CHAR8 **buffer,
         if (!buf)
                 return EFI_OUT_OF_RESOURCES;
 
-        err = uefi_call_wrapper(RT->GetVariable, 5, name, (EFI_GUID *)vendor, NULL, &l, buf);
+        err = uefi_call_wrapper(RT->GetVariable, 5, (CHAR16*) name, (EFI_GUID *)vendor, NULL, &l, buf);
         if (!EFI_ERROR(err)) {
                 *buffer = buf;
                 buf = NULL;
@@ -287,12 +305,12 @@ CHAR8 *strchra(CHAR8 *s, CHAR8 c) {
         return NULL;
 }
 
-EFI_STATUS file_read(EFI_FILE_HANDLE dir, CHAR16 *name, UINTN off, UINTN size, CHAR8 **content, UINTN *content_size) {
+EFI_STATUS file_read(EFI_FILE_HANDLE dir, const CHAR16 *name, UINTN off, UINTN size, CHAR8 **content, UINTN *content_size) {
         EFI_FILE_HANDLE handle;
         _cleanup_freepool_ CHAR8 *buf = NULL;
         EFI_STATUS err;
 
-        err = uefi_call_wrapper(dir->Open, 5, dir, &handle, name, EFI_FILE_MODE_READ, 0ULL);
+        err = uefi_call_wrapper(dir->Open, 5, dir, &handle, (CHAR16*) name, EFI_FILE_MODE_READ, 0ULL);
         if (EFI_ERROR(err))
                 return err;
 
index daa386b7696a45bcd98675daa586ff976f9d3399..f7e0e49c06a6d3d1217a839dacda3729608e5008 100644 (file)
@@ -11,26 +11,26 @@ static inline const CHAR16 *yes_no(BOOLEAN b) {
         return b ? L"yes" : L"no";
 }
 
-EFI_STATUS parse_boolean(CHAR8 *v, BOOLEAN *b);
+EFI_STATUS parse_boolean(const CHAR8 *v, BOOLEAN *b);
 
 UINT64 ticks_read(void);
 UINT64 ticks_freq(void);
 UINT64 time_usec(void);
 
-EFI_STATUS efivar_set(CHAR16 *name, CHAR16 *value, BOOLEAN persistent);
-EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, CHAR16 *name, VOID *buf, UINTN size, BOOLEAN persistent);
+EFI_STATUS efivar_set(const CHAR16 *name, const CHAR16 *value, BOOLEAN persistent);
+EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const CHAR16 *name, const VOID *buf, UINTN size, BOOLEAN persistent);
 EFI_STATUS efivar_set_int(CHAR16 *name, UINTN i, BOOLEAN persistent);
 VOID efivar_set_time_usec(CHAR16 *name, UINT64 usec);
 
-EFI_STATUS efivar_get(CHAR16 *name, CHAR16 **value);
-EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, CHAR16 *name, CHAR8 **buffer, UINTN *size);
-EFI_STATUS efivar_get_int(CHAR16 *name, UINTN *i);
+EFI_STATUS efivar_get(const CHAR16 *name, CHAR16 **value);
+EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **buffer, UINTN *size);
+EFI_STATUS efivar_get_int(const CHAR16 *name, UINTN *i);
 
 CHAR8 *strchra(CHAR8 *s, CHAR8 c);
 CHAR16 *stra_to_path(CHAR8 *stra);
 CHAR16 *stra_to_str(CHAR8 *stra);
 
-EFI_STATUS file_read(EFI_FILE_HANDLE dir, CHAR16 *name, UINTN off, UINTN size, CHAR8 **content, UINTN *content_size);
+EFI_STATUS file_read(EFI_FILE_HANDLE dir, const CHAR16 *name, UINTN off, UINTN size, CHAR8 **content, UINTN *content_size);
 
 static inline void FreePoolp(void *p) {
         void *q = *(void**) p;
@@ -52,3 +52,6 @@ static inline void FileHandleClosep(EFI_FILE_HANDLE *handle) {
 }
 
 const EFI_GUID loader_guid;
+
+#define UINTN_MAX (~(UINTN)0)
+#define INTN_MAX ((INTN)(UINTN_MAX>>1))
index 3150740e05ade46cbda70f26e252585285edc161..1f739bf22b5f50596b67de0726a048f3cdb56a9d 100644 (file)
@@ -2788,10 +2788,8 @@ static int manager_dispatch_timezone_change(
         log_debug("inotify event for /etc/localtime");
 
         changed = manager_read_timezone_stat(m);
-        if (changed < 0)
+        if (changed <= 0)
                 return changed;
-        if (!changed)
-                return 0;
 
         /* Something changed, restart the watch, to ensure we watch the new /etc/localtime if it changed */
         (void) manager_setup_timezone_change(m);
index caf7a27ef135af547345697ea67235e54cc6156f..cc9252377a25551cd02e92853bcfcc36cfdeb345 100644 (file)
  * It reads files named on the command line and passes them one by one into the
  * fuzzer that it is compiled into. */
 
+/* This one was borrowed from
+ * https://github.com/google/oss-fuzz/blob/646fca1b506b056db3a60d32c4a1a7398f171c94/infra/base-images/base-runner/bad_build_check#L19
+ */
+#define MIN_NUMBER_OF_RUNS 4
+
 int main(int argc, char **argv) {
         int i, r;
         size_t size;
@@ -30,7 +35,8 @@ int main(int argc, char **argv) {
                 }
                 printf("%s... ", name);
                 fflush(stdout);
-                (void) LLVMFuzzerTestOneInput((uint8_t*)buf, size);
+                for (int j = 0; j < MIN_NUMBER_OF_RUNS; j++)
+                        (void) LLVMFuzzerTestOneInput((uint8_t*)buf, size);
                 printf("ok\n");
         }
 
index 697553e74edd36bde43feecb6503864dc35731de..bd3e1f34460cbf59baa8eced1092f053f6e13bb7 100644 (file)
@@ -4057,7 +4057,7 @@ _public_ int sd_bus_message_enter_container(sd_bus_message *m,
                 end = m->rindex + 0;
         else
                 end = m->rindex + c->item_size;
-        
+
         m->containers[m->n_containers++] = (struct bus_container) {
                  .enclosing = type,
                  .signature = TAKE_PTR(signature),
@@ -5078,6 +5078,7 @@ int bus_message_parse_fields(sd_bus_message *m) {
                                 return -EBADMSG;
 
                         if (*p == 0) {
+                                char *k;
                                 size_t l;
 
                                 /* We found the beginning of the signature
@@ -5091,9 +5092,11 @@ int bus_message_parse_fields(sd_bus_message *m) {
                                     p[1 + l - 1] != SD_BUS_TYPE_STRUCT_END)
                                         return -EBADMSG;
 
-                                if (free_and_strndup(&m->root_container.signature,
-                                                     p + 1 + 1, l - 2) < 0)
+                                k = memdup_suffix0(p + 1 + 1, l - 2);
+                                if (!k)
                                         return -ENOMEM;
+
+                                free_and_replace(m->root_container.signature, k);
                                 break;
                         }
 
index 24f7c1439f60b1067ba1332b4433a5b4744597ff..2bab2fd2f5fe32e88e93b2cf1238aa42d4ef709f 100644 (file)
@@ -566,6 +566,17 @@ int manager_spawn_autovt(Manager *m, unsigned vtnr) {
         return 0;
 }
 
+bool manager_is_lid_closed(Manager *m) {
+        Iterator i;
+        Button *b;
+
+        HASHMAP_FOREACH(b, m->buttons, i)
+                if (b->lid_closed)
+                        return true;
+
+        return false;
+}
+
 static bool manager_is_docked(Manager *m) {
         Iterator i;
         Button *b;
@@ -670,15 +681,13 @@ bool manager_is_docked_or_external_displays(Manager *m) {
 bool manager_is_on_external_power(void) {
         int r;
 
-        /* For now we only check for AC power, but 'external power' can apply
-         * to anything that isn't an internal battery */
+        /* For now we only check for AC power, but 'external power' can apply to anything that isn't an internal
+         * battery */
         r = on_ac_power();
         if (r < 0)
                 log_warning_errno(r, "Failed to read AC power status: %m");
-        else if (r > 0)
-                return true;
 
-        return false;
+        return r != 0; /* Treat failure as 'on AC' */
 }
 
 bool manager_all_buttons_ignored(Manager *m) {
index 927e304a0ca283aa99b7439fd98971b5453958e9..c0dafa03ef0def1e74b451acbb5fd36f470fbaf4 100644 (file)
@@ -14,6 +14,7 @@
 #include "bus-error.h"
 #include "bus-unit-util.h"
 #include "bus-util.h"
+#include "cgroup-util.h"
 #include "device-util.h"
 #include "dirent-util.h"
 #include "efivars.h"
@@ -26,7 +27,6 @@
 #include "mkdir.h"
 #include "path-util.h"
 #include "process-util.h"
-#include "cgroup-util.h"
 #include "selinux-util.h"
 #include "sleep-config.h"
 #include "special.h"
@@ -274,6 +274,8 @@ static int property_get_scheduled_shutdown(
 
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
 static BUS_DEFINE_PROPERTY_GET(property_get_docked, "b", Manager, manager_is_docked_or_external_displays);
+static BUS_DEFINE_PROPERTY_GET(property_get_lid_closed, "b", Manager, manager_is_lid_closed);
+static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_on_external_power, "b", manager_is_on_external_power);
 static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_compat_user_tasks_max, "t", CGROUP_LIMIT_MAX);
 static BUS_DEFINE_PROPERTY_GET_REF(property_get_hashmap_size, "t", Hashmap *, (uint64_t) hashmap_size);
 
@@ -2265,11 +2267,13 @@ static int method_can_shutdown_or_sleep(
                 if (r < 0)
                         return r;
 
-                if (r > 0 && !result)
-                        result = "yes";
-                else if (challenge && (!result || streq(result, "yes")))
-                        result = "challenge";
-                else
+                if (r > 0) {
+                        if (!result)
+                                result = "yes";
+                } else if (challenge) {
+                        if (!result || streq(result, "yes"))
+                                result = "challenge";
+                } else
                         result = "no";
         }
 
@@ -2456,7 +2460,7 @@ static int method_can_reboot_to_firmware_setup(
         r = efi_reboot_to_firmware_supported();
         if (r < 0) {
                 if (r != -EOPNOTSUPP)
-                        log_warning_errno(errno, "Failed to determine whether reboot to firmware is supported: %m");
+                        log_warning_errno(r, "Failed to determine whether reboot to firmware is supported: %m");
 
                 return sd_bus_reply_method_return(message, "s", "na");
         }
@@ -2645,7 +2649,7 @@ const sd_bus_vtable manager_vtable[] = {
         SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, 0),
         SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
@@ -2666,6 +2670,8 @@ const sd_bus_vtable manager_vtable[] = {
         SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
         SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
         SD_BUS_PROPERTY("Docked", "b", property_get_docked, 0, 0),
+        SD_BUS_PROPERTY("LidClosed", "b", property_get_lid_closed, 0, 0),
+        SD_BUS_PROPERTY("OnExternalPower", "b", property_get_on_external_power, 0, 0),
         SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(Manager, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RuntimeDirectorySize", "t", NULL, offsetof(Manager, runtime_dir_size), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("InhibitorsMax", "t", NULL, offsetof(Manager, inhibitors_max), SD_BUS_VTABLE_PROPERTY_CONST),
index 5398cca8c4f54e75dd757cc3f64e914d47d53224..7b774f49e09b96a15dd175eb3200712027ad5ed6 100644 (file)
@@ -146,6 +146,7 @@ int manager_get_idle_hint(Manager *m, dual_timestamp *t);
 int manager_get_user_by_pid(Manager *m, pid_t pid, User **user);
 int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session);
 
+bool manager_is_lid_closed(Manager *m);
 bool manager_is_docked_or_external_displays(Manager *m);
 bool manager_is_on_external_power(void);
 bool manager_all_buttons_ignored(Manager *m);
index 78bee24b0524c98565f5963c94412780359b74ac..5ee62ab5b49eda6847beafde9f1df616b0aaaeb9 100644 (file)
                         <allow_inactive>auth_admin_keep</allow_inactive>
                         <allow_active>yes</allow_active>
                 </defaults>
+                <annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.reboot</annotate>
         </action>
 
         <action id="org.freedesktop.login1.set-wall-message">
index 86a9a58c5b97c628844a572db780c4a23ab89b64..a837414ca1946aa684c41bd386a9968142c9d2e2 100644 (file)
@@ -1378,17 +1378,13 @@ static int nsec3_is_good(DnsResourceRecord *rr, DnsResourceRecord *nsec3) {
 
         a = dns_resource_key_name(rr->key);
         r = dns_name_parent(&a); /* strip off hash */
-        if (r < 0)
+        if (r <= 0)
                 return r;
-        if (r == 0)
-                return 0;
 
         b = dns_resource_key_name(nsec3->key);
         r = dns_name_parent(&b); /* strip off hash */
-        if (r < 0)
+        if (r <= 0)
                 return r;
-        if (r == 0)
-                return 0;
 
         /* Make sure both have the same parent */
         return dns_name_equal(a, b);
@@ -2096,10 +2092,8 @@ static int dnssec_test_positive_wildcard_nsec3(
         for (;;) {
                 next_closer = name;
                 r = dns_name_parent(&name);
-                if (r < 0)
+                if (r <= 0)
                         return r;
-                if (r == 0)
-                        return 0;
 
                 r = dns_name_equal(name, source);
                 if (r < 0)
index 7a9754096ce734d83d594f4cd1ef078817d1a1d5..fbed9027c10598eefb73fcf0457984fd7ecef303 100644 (file)
@@ -246,6 +246,24 @@ int efi_get_variable(
         return 0;
 }
 
+int efi_get_variable_string(sd_id128_t vendor, const char *name, char **p) {
+        _cleanup_free_ void *s = NULL;
+        size_t ss = 0;
+        int r;
+        char *x;
+
+        r = efi_get_variable(vendor, name, NULL, &s, &ss);
+        if (r < 0)
+                return r;
+
+        x = utf16_to_utf8(s, ss);
+        if (!x)
+                return -ENOMEM;
+
+        *p = x;
+        return 0;
+}
+
 int efi_set_variable(
                 sd_id128_t vendor,
                 const char *name,
@@ -326,22 +344,14 @@ finish:
         return r;
 }
 
-int efi_get_variable_string(sd_id128_t vendor, const char *name, char **p) {
-        _cleanup_free_ void *s = NULL;
-        size_t ss = 0;
-        int r;
-        char *x;
-
-        r = efi_get_variable(vendor, name, NULL, &s, &ss);
-        if (r < 0)
-                return r;
+int efi_set_variable_string(sd_id128_t vendor, const char *name, const char *v) {
+        _cleanup_free_ char16_t *u16 = NULL;
 
-        x = utf16_to_utf8(s, ss);
-        if (!x)
+        u16 = utf8_to_utf16(v, strlen(v));
+        if (!u16)
                 return -ENOMEM;
 
-        *p = x;
-        return 0;
+        return efi_set_variable(vendor, name, u16, (char16_strlen(u16) + 1) * sizeof(char16_t));
 }
 
 static size_t utf16_size(const uint16_t *s) {
@@ -761,6 +771,16 @@ int efi_loader_get_device_part_uuid(sd_id128_t *u) {
         return 0;
 }
 
+bool efi_loader_entry_name_valid(const char *s) {
+        if (isempty(s))
+                return false;
+
+        if (strlen(s) > FILENAME_MAX) /* Make sure entry names fit in filenames */
+                return false;
+
+        return in_charset(s, ALPHANUMERICAL "-");
+}
+
 int efi_loader_get_entries(char ***ret) {
         _cleanup_free_ char16_t *entries = NULL;
         _cleanup_strv_free_ char **l = NULL;
@@ -779,7 +799,7 @@ int efi_loader_get_entries(char ***ret) {
         /* The variable contains a series of individually NUL terminated UTF-16 strings. */
 
         for (i = 0, start = 0;; i++) {
-                char *decoded;
+                _cleanup_free_ char *decoded = NULL;
                 bool end;
 
                 /* Is this the end of the variable's data? */
@@ -795,9 +815,12 @@ int efi_loader_get_entries(char ***ret) {
                 if (!decoded)
                         return -ENOMEM;
 
-                r = strv_consume(&l, decoded);
-                if (r < 0)
-                        return r;
+                if (efi_loader_entry_name_valid(decoded)) {
+                        r = strv_consume(&l, TAKE_PTR(decoded));
+                        if (r < 0)
+                                return r;
+                } else
+                        log_debug("Ignoring invalid loader entry '%s'.", decoded);
 
                 /* We reached the end of the variable */
                 if (end)
@@ -822,3 +845,53 @@ char *efi_tilt_backslashes(char *s) {
 
         return s;
 }
+
+int efi_loader_get_features(uint64_t *ret) {
+        _cleanup_free_ void *v = NULL;
+        size_t s;
+        int r;
+
+        if (!is_efi_boot()) {
+                *ret = 0;
+                return 0;
+        }
+
+        r = efi_get_variable(EFI_VENDOR_LOADER, "LoaderFeatures", NULL, &v, &s);
+        if (r == -ENOENT) {
+                _cleanup_free_ char *info = NULL;
+
+                /* The new (v240+) LoaderFeatures variable is not supported, let's see if it's systemd-boot at all */
+                r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderInfo", &info);
+                if (r < 0) {
+                        if (r != -ENOENT)
+                                return r;
+
+                        /* Variable not set, definitely means not systemd-boot */
+
+                } else if (first_word(info, "systemd-boot")) {
+
+                        /* An older systemd-boot version. Let's hardcode the feature set, since it was pretty
+                         * static in all its versions. */
+
+                        *ret = EFI_LOADER_FEATURE_CONFIG_TIMEOUT |
+                                EFI_LOADER_FEATURE_ENTRY_DEFAULT |
+                                EFI_LOADER_FEATURE_ENTRY_ONESHOT;
+
+                        return 0;
+                }
+
+                /* No features supported */
+                *ret = 0;
+                return 0;
+        }
+        if (r < 0)
+                return r;
+
+        if (s != sizeof(uint64_t)) {
+                log_debug("LoaderFeatures EFI variable doesn't have the right size.");
+                return -EINVAL;
+        }
+
+        memcpy(ret, v, sizeof(uint64_t));
+        return 0;
+}
index 9b5ab39fee2d3616032e3bd2836df7ad000aa729..92670c82c7d9c2aa5a59c248178f3071b6b14d9c 100644 (file)
 #define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002
 #define EFI_VARIABLE_RUNTIME_ACCESS     0x0000000000000004
 
+#define EFI_LOADER_FEATURE_CONFIG_TIMEOUT          (UINT64_C(1) << 0)
+#define EFI_LOADER_FEATURE_CONFIG_TIMEOUT_ONE_SHOT (UINT64_C(1) << 1)
+#define EFI_LOADER_FEATURE_ENTRY_DEFAULT           (UINT64_C(1) << 2)
+#define EFI_LOADER_FEATURE_ENTRY_ONESHOT           (UINT64_C(1) << 3)
+#define EFI_LOADER_FEATURE_BOOT_COUNTING           (UINT64_C(1) << 4)
+
 #if ENABLE_EFI
 
 bool is_efi_boot(void);
@@ -28,8 +34,9 @@ int efi_get_reboot_to_firmware(void);
 int efi_set_reboot_to_firmware(bool value);
 
 int efi_get_variable(sd_id128_t vendor, const char *name, uint32_t *attribute, void **value, size_t *size);
-int efi_set_variable(sd_id128_t vendor, const char *name, const void *value, size_t size);
 int efi_get_variable_string(sd_id128_t vendor, const char *name, char **p);
+int efi_set_variable(sd_id128_t vendor, const char *name, const void *value, size_t size);
+int efi_set_variable_string(sd_id128_t vendor, const char *name, const char *p);
 
 int efi_get_boot_option(uint16_t nr, char **title, sd_id128_t *part_uuid, char **path, bool *active);
 int efi_add_boot_option(uint16_t id, const char *title, uint32_t part, uint64_t pstart, uint64_t psize, sd_id128_t part_uuid, const char *path);
@@ -43,6 +50,10 @@ int efi_loader_get_boot_usec(usec_t *firmware, usec_t *loader);
 
 int efi_loader_get_entries(char ***ret);
 
+bool efi_loader_entry_name_valid(const char *s);
+
+int efi_loader_get_features(uint64_t *ret);
+
 #else
 
 static inline bool is_efi_boot(void) {
@@ -73,11 +84,15 @@ static inline int efi_get_variable(sd_id128_t vendor, const char *name, uint32_t
         return -EOPNOTSUPP;
 }
 
+static inline int efi_get_variable_string(sd_id128_t vendor, const char *name, char **p) {
+        return -EOPNOTSUPP;
+}
+
 static inline int efi_set_variable(sd_id128_t vendor, const char *name, const void *value, size_t size) {
         return -EOPNOTSUPP;
 }
 
-static inline int efi_get_variable_string(sd_id128_t vendor, const char *name, char **p) {
+static inline int efi_set_variable_string(sd_id128_t vendor, const char *name, const char *p) {
         return -EOPNOTSUPP;
 }
 
@@ -117,6 +132,10 @@ static inline int efi_loader_get_entries(char ***ret) {
         return -EOPNOTSUPP;
 }
 
+static inline int efi_loader_get_features(uint64_t *ret) {
+        return -EOPNOTSUPP;
+}
+
 #endif
 
 char *efi_tilt_backslashes(char *s);
index 3634534782dc2986ea2b56e62e68f59d69e807c2..6d0f24eeea253ebedacdd586aa80d95eb884b33a 100644 (file)
@@ -65,7 +65,7 @@ static void test_keymaps(void) {
 
 #define dump_glyph(x) log_info(STRINGIFY(x) ": %s", special_glyph(x))
 static void dump_special_glyphs(void) {
-        assert_cc(MU + 1 == _SPECIAL_GLYPH_MAX);
+        assert_cc(CROSS_MARK + 1 == _SPECIAL_GLYPH_MAX);
 
         log_info("/* %s */", __func__);
 
@@ -80,6 +80,9 @@ static void dump_special_glyphs(void) {
         dump_glyph(ARROW);
         dump_glyph(MDASH);
         dump_glyph(ELLIPSIS);
+        dump_glyph(MU);
+        dump_glyph(CHECK_MARK);
+        dump_glyph(CROSS_MARK);
 }
 
 int main(int argc, char *argv[]) {