LCOV - code coverage report
Current view: top level - shared - efivars.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 14 479 2.9 %
Date: 2019-08-23 13:36:53 Functions: 4 33 12.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 5 320 1.6 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <dirent.h>
       4                 :            : #include <errno.h>
       5                 :            : #include <fcntl.h>
       6                 :            : #include <limits.h>
       7                 :            : #include <linux/fs.h>
       8                 :            : #include <stdio.h>
       9                 :            : #include <stdlib.h>
      10                 :            : #include <string.h>
      11                 :            : #include <sys/stat.h>
      12                 :            : #include <unistd.h>
      13                 :            : 
      14                 :            : #include "sd-id128.h"
      15                 :            : 
      16                 :            : #include "alloc-util.h"
      17                 :            : #include "chattr-util.h"
      18                 :            : #include "dirent-util.h"
      19                 :            : #include "efivars.h"
      20                 :            : #include "fd-util.h"
      21                 :            : #include "io-util.h"
      22                 :            : #include "macro.h"
      23                 :            : #include "parse-util.h"
      24                 :            : #include "sort-util.h"
      25                 :            : #include "stdio-util.h"
      26                 :            : #include "strv.h"
      27                 :            : #include "time-util.h"
      28                 :            : #include "utf8.h"
      29                 :            : #include "virt.h"
      30                 :            : 
      31                 :            : #if ENABLE_EFI
      32                 :            : 
      33                 :            : #define LOAD_OPTION_ACTIVE            0x00000001
      34                 :            : #define MEDIA_DEVICE_PATH                   0x04
      35                 :            : #define MEDIA_HARDDRIVE_DP                  0x01
      36                 :            : #define MEDIA_FILEPATH_DP                   0x04
      37                 :            : #define SIGNATURE_TYPE_GUID                 0x02
      38                 :            : #define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02
      39                 :            : #define END_DEVICE_PATH_TYPE                0x7f
      40                 :            : #define END_ENTIRE_DEVICE_PATH_SUBTYPE      0xff
      41                 :            : #define EFI_OS_INDICATIONS_BOOT_TO_FW_UI    0x0000000000000001
      42                 :            : 
      43                 :            : #define boot_option__contents {                 \
      44                 :            :         uint32_t attr;                          \
      45                 :            :         uint16_t path_len;                      \
      46                 :            :         uint16_t title[];                       \
      47                 :            :         }
      48                 :            : 
      49                 :            : struct boot_option boot_option__contents;
      50                 :            : struct boot_option__packed boot_option__contents _packed_;
      51                 :            : assert_cc(offsetof(struct boot_option, title) == offsetof(struct boot_option__packed, title));
      52                 :            : /* sizeof(struct boot_option) != sizeof(struct boot_option__packed), so
      53                 :            :  * the *size* of the structure should not be used anywhere below. */
      54                 :            : 
      55                 :            : struct drive_path {
      56                 :            :         uint32_t part_nr;
      57                 :            :         uint64_t part_start;
      58                 :            :         uint64_t part_size;
      59                 :            :         char signature[16];
      60                 :            :         uint8_t mbr_type;
      61                 :            :         uint8_t signature_type;
      62                 :            : } _packed_;
      63                 :            : 
      64                 :            : #define device_path__contents {                 \
      65                 :            :         uint8_t type;                           \
      66                 :            :         uint8_t sub_type;                       \
      67                 :            :         uint16_t length;                        \
      68                 :            :         union {                                 \
      69                 :            :                 uint16_t path[0];               \
      70                 :            :                 struct drive_path drive;        \
      71                 :            :         };                                      \
      72                 :            :         }
      73                 :            : 
      74                 :            : struct device_path device_path__contents;
      75                 :            : struct device_path__packed device_path__contents _packed_;
      76                 :            : assert_cc(sizeof(struct device_path) == sizeof(struct device_path__packed));
      77                 :            : 
      78                 :         20 : bool is_efi_boot(void) {
      79         [ -  + ]:         20 :         if (detect_container() > 0)
      80                 :          0 :                 return false;
      81                 :            : 
      82                 :         20 :         return access("/sys/firmware/efi/", F_OK) >= 0;
      83                 :            : }
      84                 :            : 
      85                 :         12 : static int read_flag(const char *varname) {
      86                 :         12 :         _cleanup_free_ void *v = NULL;
      87                 :            :         uint8_t b;
      88                 :            :         size_t s;
      89                 :            :         int r;
      90                 :            : 
      91         [ +  - ]:         12 :         if (!is_efi_boot()) /* If this is not an EFI boot, assume the queried flags are zero */
      92                 :         12 :                 return 0;
      93                 :            : 
      94                 :          0 :         r = efi_get_variable(EFI_VENDOR_GLOBAL, varname, NULL, &v, &s);
      95         [ #  # ]:          0 :         if (r < 0)
      96                 :          0 :                 return r;
      97                 :            : 
      98         [ #  # ]:          0 :         if (s != 1)
      99                 :          0 :                 return -EINVAL;
     100                 :            : 
     101                 :          0 :         b = *(uint8_t *)v;
     102                 :          0 :         return !!b;
     103                 :            : }
     104                 :            : 
     105                 :         12 : bool is_efi_secure_boot(void) {
     106                 :         12 :         return read_flag("SecureBoot") > 0;
     107                 :            : }
     108                 :            : 
     109                 :          0 : bool is_efi_secure_boot_setup_mode(void) {
     110                 :          0 :         return read_flag("SetupMode") > 0;
     111                 :            : }
     112                 :            : 
     113                 :          0 : int efi_reboot_to_firmware_supported(void) {
     114                 :          0 :         _cleanup_free_ void *v = NULL;
     115                 :            :         uint64_t b;
     116                 :            :         size_t s;
     117                 :            :         int r;
     118                 :            : 
     119         [ #  # ]:          0 :         if (!is_efi_boot())
     120                 :          0 :                 return -EOPNOTSUPP;
     121                 :            : 
     122                 :          0 :         r = efi_get_variable(EFI_VENDOR_GLOBAL, "OsIndicationsSupported", NULL, &v, &s);
     123         [ #  # ]:          0 :         if (r == -ENOENT) /* variable doesn't exist? it's not supported then */
     124                 :          0 :                 return -EOPNOTSUPP;
     125         [ #  # ]:          0 :         if (r < 0)
     126                 :          0 :                 return r;
     127         [ #  # ]:          0 :         if (s != sizeof(uint64_t))
     128                 :          0 :                 return -EINVAL;
     129                 :            : 
     130                 :          0 :         b = *(uint64_t*) v;
     131         [ #  # ]:          0 :         if (!(b & EFI_OS_INDICATIONS_BOOT_TO_FW_UI))
     132                 :          0 :                 return -EOPNOTSUPP; /* bit unset? it's not supported then */
     133                 :            : 
     134                 :          0 :         return 0;
     135                 :            : }
     136                 :            : 
     137                 :          0 : static int get_os_indications(uint64_t *os_indication) {
     138                 :          0 :         _cleanup_free_ void *v = NULL;
     139                 :            :         size_t s;
     140                 :            :         int r;
     141                 :            : 
     142                 :            :         /* Let's verify general support first */
     143                 :          0 :         r = efi_reboot_to_firmware_supported();
     144         [ #  # ]:          0 :         if (r < 0)
     145                 :          0 :                 return r;
     146                 :            : 
     147                 :          0 :         r = efi_get_variable(EFI_VENDOR_GLOBAL, "OsIndications", NULL, &v, &s);
     148         [ #  # ]:          0 :         if (r == -ENOENT) {
     149                 :            :                 /* Some firmware implementations that do support OsIndications and report that with
     150                 :            :                  * OsIndicationsSupported will remove the OsIndications variable when it is unset. Let's pretend it's 0
     151                 :            :                  * then, to hide this implementation detail. Note that this call will return -ENOENT then only if the
     152                 :            :                  * support for OsIndications is missing entirely, as determined by efi_reboot_to_firmware_supported()
     153                 :            :                  * above. */
     154                 :          0 :                 *os_indication = 0;
     155                 :          0 :                 return 0;
     156         [ #  # ]:          0 :         } else if (r < 0)
     157                 :          0 :                 return r;
     158         [ #  # ]:          0 :         else if (s != sizeof(uint64_t))
     159                 :          0 :                 return -EINVAL;
     160                 :            : 
     161                 :          0 :         *os_indication = *(uint64_t *)v;
     162                 :          0 :         return 0;
     163                 :            : }
     164                 :            : 
     165                 :          0 : int efi_get_reboot_to_firmware(void) {
     166                 :            :         int r;
     167                 :            :         uint64_t b;
     168                 :            : 
     169                 :          0 :         r = get_os_indications(&b);
     170         [ #  # ]:          0 :         if (r < 0)
     171                 :          0 :                 return r;
     172                 :            : 
     173                 :          0 :         return !!(b & EFI_OS_INDICATIONS_BOOT_TO_FW_UI);
     174                 :            : }
     175                 :            : 
     176                 :          0 : int efi_set_reboot_to_firmware(bool value) {
     177                 :            :         int r;
     178                 :            :         uint64_t b, b_new;
     179                 :            : 
     180                 :          0 :         r = get_os_indications(&b);
     181         [ #  # ]:          0 :         if (r < 0)
     182                 :          0 :                 return r;
     183                 :            : 
     184         [ #  # ]:          0 :         if (value)
     185                 :          0 :                 b_new = b | EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
     186                 :            :         else
     187                 :          0 :                 b_new = b & ~EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
     188                 :            : 
     189                 :            :         /* Avoid writing to efi vars store if we can due to firmware bugs. */
     190         [ #  # ]:          0 :         if (b != b_new)
     191                 :          0 :                 return efi_set_variable(EFI_VENDOR_GLOBAL, "OsIndications", &b_new, sizeof(uint64_t));
     192                 :            : 
     193                 :          0 :         return 0;
     194                 :            : }
     195                 :            : 
     196                 :          0 : char* efi_variable_path(sd_id128_t vendor, const char *name) {
     197                 :            :         char *p;
     198                 :            : 
     199         [ #  # ]:          0 :         if (asprintf(&p,
     200                 :            :                      "/sys/firmware/efi/efivars/%s-" SD_ID128_UUID_FORMAT_STR,
     201                 :          0 :                      name, SD_ID128_FORMAT_VAL(vendor)) < 0)
     202                 :          0 :                 return NULL;
     203                 :            : 
     204                 :          0 :         return p;
     205                 :            : }
     206                 :            : 
     207                 :          0 : int efi_get_variable(
     208                 :            :                 sd_id128_t vendor,
     209                 :            :                 const char *name,
     210                 :            :                 uint32_t *ret_attribute,
     211                 :            :                 void **ret_value,
     212                 :            :                 size_t *ret_size) {
     213                 :            : 
     214                 :          0 :         _cleanup_close_ int fd = -1;
     215                 :          0 :         _cleanup_free_ char *p = NULL;
     216                 :          0 :         _cleanup_free_ void *buf = NULL;
     217                 :            :         struct stat st;
     218                 :            :         uint32_t a;
     219                 :            :         ssize_t n;
     220                 :            : 
     221         [ #  # ]:          0 :         assert(name);
     222                 :            : 
     223                 :          0 :         p = efi_variable_path(vendor, name);
     224         [ #  # ]:          0 :         if (!p)
     225                 :          0 :                 return -ENOMEM;
     226                 :            : 
     227   [ #  #  #  #  :          0 :         if (!ret_value && !ret_size && !ret_attribute) {
                   #  # ]
     228                 :            :                 /* If caller is not interested in anything, just check if the variable exists and is readable
     229                 :            :                  * to us. */
     230         [ #  # ]:          0 :                 if (access(p, R_OK) < 0)
     231                 :          0 :                         return -errno;
     232                 :            : 
     233                 :          0 :                 return 0;
     234                 :            :         }
     235                 :            : 
     236                 :          0 :         fd = open(p, O_RDONLY|O_NOCTTY|O_CLOEXEC);
     237         [ #  # ]:          0 :         if (fd < 0)
     238                 :          0 :                 return -errno;
     239                 :            : 
     240         [ #  # ]:          0 :         if (fstat(fd, &st) < 0)
     241                 :          0 :                 return -errno;
     242         [ #  # ]:          0 :         if (st.st_size < 4)
     243                 :          0 :                 return -ENODATA;
     244         [ #  # ]:          0 :         if (st.st_size > 4*1024*1024 + 4)
     245                 :          0 :                 return -E2BIG;
     246                 :            : 
     247   [ #  #  #  # ]:          0 :         if (ret_value || ret_attribute) {
     248                 :          0 :                 n = read(fd, &a, sizeof(a));
     249         [ #  # ]:          0 :                 if (n < 0)
     250                 :          0 :                         return -errno;
     251         [ #  # ]:          0 :                 if (n != sizeof(a))
     252                 :          0 :                         return -EIO;
     253                 :            :         }
     254                 :            : 
     255         [ #  # ]:          0 :         if (ret_value) {
     256                 :          0 :                 buf = malloc(st.st_size - 4 + 2);
     257         [ #  # ]:          0 :                 if (!buf)
     258                 :          0 :                         return -ENOMEM;
     259                 :            : 
     260                 :          0 :                 n = read(fd, buf, (size_t) st.st_size - 4);
     261         [ #  # ]:          0 :                 if (n < 0)
     262                 :          0 :                         return -errno;
     263         [ #  # ]:          0 :                 if (n != st.st_size - 4)
     264                 :          0 :                         return -EIO;
     265                 :            : 
     266                 :            :                 /* Always NUL terminate (2 bytes, to protect UTF-16) */
     267                 :          0 :                 ((char*) buf)[st.st_size - 4] = 0;
     268                 :          0 :                 ((char*) buf)[st.st_size - 4 + 1] = 0;
     269                 :            :         }
     270                 :            : 
     271                 :            :         /* Note that efivarfs interestingly doesn't require ftruncate() to update an existing EFI variable
     272                 :            :          * with a smaller value. */
     273                 :            : 
     274         [ #  # ]:          0 :         if (ret_attribute)
     275                 :          0 :                 *ret_attribute = a;
     276                 :            : 
     277         [ #  # ]:          0 :         if (ret_value)
     278                 :          0 :                 *ret_value = TAKE_PTR(buf);
     279                 :            : 
     280         [ #  # ]:          0 :         if (ret_size)
     281                 :          0 :                 *ret_size = (size_t) st.st_size - 4;
     282                 :            : 
     283                 :          0 :         return 0;
     284                 :            : }
     285                 :            : 
     286                 :          0 : int efi_get_variable_string(sd_id128_t vendor, const char *name, char **p) {
     287                 :          0 :         _cleanup_free_ void *s = NULL;
     288                 :          0 :         size_t ss = 0;
     289                 :            :         int r;
     290                 :            :         char *x;
     291                 :            : 
     292                 :          0 :         r = efi_get_variable(vendor, name, NULL, &s, &ss);
     293         [ #  # ]:          0 :         if (r < 0)
     294                 :          0 :                 return r;
     295                 :            : 
     296                 :          0 :         x = utf16_to_utf8(s, ss);
     297         [ #  # ]:          0 :         if (!x)
     298                 :          0 :                 return -ENOMEM;
     299                 :            : 
     300                 :          0 :         *p = x;
     301                 :          0 :         return 0;
     302                 :            : }
     303                 :            : 
     304                 :          0 : int efi_set_variable(
     305                 :            :                 sd_id128_t vendor,
     306                 :            :                 const char *name,
     307                 :            :                 const void *value,
     308                 :            :                 size_t size) {
     309                 :            : 
     310                 :            :         struct var {
     311                 :            :                 uint32_t attr;
     312                 :            :                 char buf[];
     313                 :          0 :         } _packed_ * _cleanup_free_ buf = NULL;
     314                 :          0 :         _cleanup_free_ char *p = NULL;
     315                 :          0 :         _cleanup_close_ int fd = -1;
     316                 :          0 :         bool saved_flags_valid = false;
     317                 :            :         unsigned saved_flags;
     318                 :            :         int r;
     319                 :            : 
     320         [ #  # ]:          0 :         assert(name);
     321   [ #  #  #  # ]:          0 :         assert(value || size == 0);
     322                 :            : 
     323                 :          0 :         p = efi_variable_path(vendor, name);
     324         [ #  # ]:          0 :         if (!p)
     325                 :          0 :                 return -ENOMEM;
     326                 :            : 
     327                 :            :         /* Newer efivarfs protects variables that are not in a whitelist with FS_IMMUTABLE_FL by default, to protect
     328                 :            :          * them for accidental removal and modification. We are not changing these variables accidentally however,
     329                 :            :          * hence let's unset the bit first. */
     330                 :            : 
     331                 :          0 :         r = chattr_path(p, 0, FS_IMMUTABLE_FL, &saved_flags);
     332   [ #  #  #  # ]:          0 :         if (r < 0 && r != -ENOENT)
     333         [ #  # ]:          0 :                 log_debug_errno(r, "Failed to drop FS_IMMUTABLE_FL flag from '%s', ignoring: %m", p);
     334                 :            : 
     335                 :          0 :         saved_flags_valid = r >= 0;
     336                 :            : 
     337         [ #  # ]:          0 :         if (size == 0) {
     338         [ #  # ]:          0 :                 if (unlink(p) < 0) {
     339                 :          0 :                         r = -errno;
     340                 :          0 :                         goto finish;
     341                 :            :                 }
     342                 :            : 
     343                 :          0 :                 return 0;
     344                 :            :         }
     345                 :            : 
     346                 :          0 :         fd = open(p, O_WRONLY|O_CREAT|O_NOCTTY|O_CLOEXEC, 0644);
     347         [ #  # ]:          0 :         if (fd < 0) {
     348                 :          0 :                 r = -errno;
     349                 :          0 :                 goto finish;
     350                 :            :         }
     351                 :            : 
     352                 :          0 :         buf = malloc(sizeof(uint32_t) + size);
     353         [ #  # ]:          0 :         if (!buf) {
     354                 :          0 :                 r = -ENOMEM;
     355                 :          0 :                 goto finish;
     356                 :            :         }
     357                 :            : 
     358                 :          0 :         buf->attr = EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS;
     359                 :          0 :         memcpy(buf->buf, value, size);
     360                 :            : 
     361                 :          0 :         r = loop_write(fd, buf, sizeof(uint32_t) + size, false);
     362         [ #  # ]:          0 :         if (r < 0)
     363                 :          0 :                 goto finish;
     364                 :            : 
     365                 :          0 :         r = 0;
     366                 :            : 
     367                 :          0 : finish:
     368         [ #  # ]:          0 :         if (saved_flags_valid) {
     369                 :            :                 int q;
     370                 :            : 
     371                 :            :                 /* Restore the original flags field, just in case */
     372         [ #  # ]:          0 :                 if (fd < 0)
     373                 :          0 :                         q = chattr_path(p, saved_flags, FS_IMMUTABLE_FL, NULL);
     374                 :            :                 else
     375                 :          0 :                         q = chattr_fd(fd, saved_flags, FS_IMMUTABLE_FL, NULL);
     376         [ #  # ]:          0 :                 if (q < 0)
     377         [ #  # ]:          0 :                         log_debug_errno(q, "Failed to restore FS_IMMUTABLE_FL on '%s', ignoring: %m", p);
     378                 :            :         }
     379                 :            : 
     380                 :          0 :         return r;
     381                 :            : }
     382                 :            : 
     383                 :          0 : int efi_set_variable_string(sd_id128_t vendor, const char *name, const char *v) {
     384                 :          0 :         _cleanup_free_ char16_t *u16 = NULL;
     385                 :            : 
     386                 :          0 :         u16 = utf8_to_utf16(v, strlen(v));
     387         [ #  # ]:          0 :         if (!u16)
     388                 :          0 :                 return -ENOMEM;
     389                 :            : 
     390                 :          0 :         return efi_set_variable(vendor, name, u16, (char16_strlen(u16) + 1) * sizeof(char16_t));
     391                 :            : }
     392                 :            : 
     393                 :          0 : static ssize_t utf16_size(const uint16_t *s, size_t buf_len_bytes) {
     394                 :          0 :         size_t l = 0;
     395                 :            : 
     396                 :            :         /* Returns the size of the string in bytes without the terminating two zero bytes */
     397                 :            : 
     398         [ #  # ]:          0 :         if (buf_len_bytes % sizeof(uint16_t) != 0)
     399                 :          0 :                 return -EINVAL;
     400                 :            : 
     401         [ #  # ]:          0 :         while (l < buf_len_bytes / sizeof(uint16_t)) {
     402         [ #  # ]:          0 :                 if (s[l] == 0)
     403                 :          0 :                         return (l + 1) * sizeof(uint16_t);
     404                 :          0 :                 l++;
     405                 :            :         }
     406                 :            : 
     407                 :          0 :         return -EINVAL; /* The terminator was not found */
     408                 :            : }
     409                 :            : 
     410                 :            : struct guid {
     411                 :            :         uint32_t u1;
     412                 :            :         uint16_t u2;
     413                 :            :         uint16_t u3;
     414                 :            :         uint8_t u4[8];
     415                 :            : } _packed_;
     416                 :            : 
     417                 :          0 : static void efi_guid_to_id128(const void *guid, sd_id128_t *id128) {
     418                 :            :         uint32_t u1;
     419                 :            :         uint16_t u2, u3;
     420                 :          0 :         const struct guid *uuid = guid;
     421                 :            : 
     422                 :          0 :         memcpy(&u1, &uuid->u1, sizeof(uint32_t));
     423                 :          0 :         id128->bytes[0] = (u1 >> 24) & 0xff;
     424                 :          0 :         id128->bytes[1] = (u1 >> 16) & 0xff;
     425                 :          0 :         id128->bytes[2] = (u1 >> 8) & 0xff;
     426                 :          0 :         id128->bytes[3] = u1 & 0xff;
     427                 :          0 :         memcpy(&u2, &uuid->u2, sizeof(uint16_t));
     428                 :          0 :         id128->bytes[4] = (u2 >> 8) & 0xff;
     429                 :          0 :         id128->bytes[5] = u2 & 0xff;
     430                 :          0 :         memcpy(&u3, &uuid->u3, sizeof(uint16_t));
     431                 :          0 :         id128->bytes[6] = (u3 >> 8) & 0xff;
     432                 :          0 :         id128->bytes[7] = u3 & 0xff;
     433                 :          0 :         memcpy(&id128->bytes[8], uuid->u4, sizeof(uuid->u4));
     434                 :          0 : }
     435                 :            : 
     436                 :          0 : int efi_get_boot_option(
     437                 :            :                 uint16_t id,
     438                 :            :                 char **title,
     439                 :            :                 sd_id128_t *part_uuid,
     440                 :            :                 char **path,
     441                 :            :                 bool *active) {
     442                 :            : 
     443                 :            :         char boot_id[9];
     444                 :          0 :         _cleanup_free_ uint8_t *buf = NULL;
     445                 :            :         size_t l;
     446                 :            :         struct boot_option *header;
     447                 :            :         ssize_t title_size;
     448                 :          0 :         _cleanup_free_ char *s = NULL, *p = NULL;
     449                 :          0 :         sd_id128_t p_uuid = SD_ID128_NULL;
     450                 :            :         int r;
     451                 :            : 
     452         [ #  # ]:          0 :         if (!is_efi_boot())
     453                 :          0 :                 return -EOPNOTSUPP;
     454                 :            : 
     455         [ #  # ]:          0 :         xsprintf(boot_id, "Boot%04X", id);
     456                 :          0 :         r = efi_get_variable(EFI_VENDOR_GLOBAL, boot_id, NULL, (void **)&buf, &l);
     457         [ #  # ]:          0 :         if (r < 0)
     458                 :          0 :                 return r;
     459         [ #  # ]:          0 :         if (l < offsetof(struct boot_option, title))
     460                 :          0 :                 return -ENOENT;
     461                 :            : 
     462                 :          0 :         header = (struct boot_option *)buf;
     463                 :          0 :         title_size = utf16_size(header->title, l - offsetof(struct boot_option, title));
     464         [ #  # ]:          0 :         if (title_size < 0)
     465                 :          0 :                 return title_size;
     466                 :            : 
     467         [ #  # ]:          0 :         if (title) {
     468                 :          0 :                 s = utf16_to_utf8(header->title, title_size);
     469         [ #  # ]:          0 :                 if (!s)
     470                 :          0 :                         return -ENOMEM;
     471                 :            :         }
     472                 :            : 
     473         [ #  # ]:          0 :         if (header->path_len > 0) {
     474                 :            :                 uint8_t *dbuf;
     475                 :            :                 size_t dnext, doff;
     476                 :            : 
     477                 :          0 :                 doff = offsetof(struct boot_option, title) + title_size;
     478                 :          0 :                 dbuf = buf + doff;
     479         [ #  # ]:          0 :                 if (header->path_len > l - doff)
     480                 :          0 :                         return -EINVAL;
     481                 :            : 
     482                 :          0 :                 dnext = 0;
     483         [ #  # ]:          0 :                 while (dnext < header->path_len) {
     484                 :            :                         struct device_path *dpath;
     485                 :            : 
     486                 :          0 :                         dpath = (struct device_path *)(dbuf + dnext);
     487         [ #  # ]:          0 :                         if (dpath->length < 4)
     488                 :          0 :                                 break;
     489                 :            : 
     490                 :            :                         /* Type 0x7F – End of Hardware Device Path, Sub-Type 0xFF – End Entire Device Path */
     491   [ #  #  #  # ]:          0 :                         if (dpath->type == END_DEVICE_PATH_TYPE && dpath->sub_type == END_ENTIRE_DEVICE_PATH_SUBTYPE)
     492                 :          0 :                                 break;
     493                 :            : 
     494                 :          0 :                         dnext += dpath->length;
     495                 :            : 
     496                 :            :                         /* Type 0x04 – Media Device Path */
     497         [ #  # ]:          0 :                         if (dpath->type != MEDIA_DEVICE_PATH)
     498                 :          0 :                                 continue;
     499                 :            : 
     500                 :            :                         /* Sub-Type 1 – Hard Drive */
     501         [ #  # ]:          0 :                         if (dpath->sub_type == MEDIA_HARDDRIVE_DP) {
     502                 :            :                                 /* 0x02 – GUID Partition Table */
     503         [ #  # ]:          0 :                                 if (dpath->drive.mbr_type != MBR_TYPE_EFI_PARTITION_TABLE_HEADER)
     504                 :          0 :                                         continue;
     505                 :            : 
     506                 :            :                                 /* 0x02 – GUID signature */
     507         [ #  # ]:          0 :                                 if (dpath->drive.signature_type != SIGNATURE_TYPE_GUID)
     508                 :          0 :                                         continue;
     509                 :            : 
     510         [ #  # ]:          0 :                                 if (part_uuid)
     511                 :          0 :                                         efi_guid_to_id128(dpath->drive.signature, &p_uuid);
     512                 :          0 :                                 continue;
     513                 :            :                         }
     514                 :            : 
     515                 :            :                         /* Sub-Type 4 – File Path */
     516   [ #  #  #  #  :          0 :                         if (dpath->sub_type == MEDIA_FILEPATH_DP && !p && path) {
                   #  # ]
     517                 :          0 :                                 p = utf16_to_utf8(dpath->path, dpath->length-4);
     518         [ #  # ]:          0 :                                 if (!p)
     519                 :          0 :                                         return  -ENOMEM;
     520                 :            : 
     521                 :          0 :                                 efi_tilt_backslashes(p);
     522                 :          0 :                                 continue;
     523                 :            :                         }
     524                 :            :                 }
     525                 :            :         }
     526                 :            : 
     527         [ #  # ]:          0 :         if (title)
     528                 :          0 :                 *title = TAKE_PTR(s);
     529         [ #  # ]:          0 :         if (part_uuid)
     530                 :          0 :                 *part_uuid = p_uuid;
     531         [ #  # ]:          0 :         if (path)
     532                 :          0 :                 *path = TAKE_PTR(p);
     533         [ #  # ]:          0 :         if (active)
     534                 :          0 :                 *active = header->attr & LOAD_OPTION_ACTIVE;
     535                 :            : 
     536                 :          0 :         return 0;
     537                 :            : }
     538                 :            : 
     539                 :          0 : static void to_utf16(uint16_t *dest, const char *src) {
     540                 :            :         int i;
     541                 :            : 
     542         [ #  # ]:          0 :         for (i = 0; src[i] != '\0'; i++)
     543                 :          0 :                 dest[i] = src[i];
     544                 :          0 :         dest[i] = '\0';
     545                 :          0 : }
     546                 :            : 
     547                 :          0 : static void id128_to_efi_guid(sd_id128_t id, void *guid) {
     548                 :          0 :         struct guid uuid = {
     549                 :          0 :                 .u1 = id.bytes[0] << 24 | id.bytes[1] << 16 | id.bytes[2] << 8 | id.bytes[3],
     550                 :          0 :                 .u2 = id.bytes[4] << 8 | id.bytes[5],
     551                 :          0 :                 .u3 = id.bytes[6] << 8 | id.bytes[7],
     552                 :            :         };
     553                 :          0 :         memcpy(uuid.u4, id.bytes+8, sizeof(uuid.u4));
     554                 :          0 :         memcpy(guid, &uuid, sizeof(uuid));
     555                 :          0 : }
     556                 :            : 
     557                 :          0 : static uint16_t *tilt_slashes(uint16_t *s) {
     558                 :            :         uint16_t *p;
     559                 :            : 
     560         [ #  # ]:          0 :         for (p = s; *p; p++)
     561         [ #  # ]:          0 :                 if (*p == '/')
     562                 :          0 :                         *p = '\\';
     563                 :            : 
     564                 :          0 :         return s;
     565                 :            : }
     566                 :            : 
     567                 :          0 : int efi_add_boot_option(
     568                 :            :                 uint16_t id,
     569                 :            :                 const char *title,
     570                 :            :                 uint32_t part,
     571                 :            :                 uint64_t pstart,
     572                 :            :                 uint64_t psize,
     573                 :            :                 sd_id128_t part_uuid,
     574                 :            :                 const char *path) {
     575                 :            : 
     576                 :            :         size_t size, title_len, path_len;
     577                 :          0 :         _cleanup_free_ char *buf = NULL;
     578                 :            :         struct boot_option *option;
     579                 :            :         struct device_path *devicep;
     580                 :            :         char boot_id[9];
     581                 :            : 
     582         [ #  # ]:          0 :         if (!is_efi_boot())
     583                 :          0 :                 return -EOPNOTSUPP;
     584                 :            : 
     585                 :          0 :         title_len = (strlen(title)+1) * 2;
     586                 :          0 :         path_len = (strlen(path)+1) * 2;
     587                 :            : 
     588                 :          0 :         buf = malloc0(offsetof(struct boot_option, title) + title_len +
     589                 :            :                       sizeof(struct drive_path) +
     590                 :            :                       sizeof(struct device_path) + path_len);
     591         [ #  # ]:          0 :         if (!buf)
     592                 :          0 :                 return -ENOMEM;
     593                 :            : 
     594                 :            :         /* header */
     595                 :          0 :         option = (struct boot_option *)buf;
     596                 :          0 :         option->attr = LOAD_OPTION_ACTIVE;
     597                 :          0 :         option->path_len = offsetof(struct device_path, drive) + sizeof(struct drive_path) +
     598                 :          0 :                            offsetof(struct device_path, path) + path_len +
     599                 :            :                            offsetof(struct device_path, path);
     600                 :          0 :         to_utf16(option->title, title);
     601                 :          0 :         size = offsetof(struct boot_option, title) + title_len;
     602                 :            : 
     603                 :            :         /* partition info */
     604                 :          0 :         devicep = (struct device_path *)(buf + size);
     605                 :          0 :         devicep->type = MEDIA_DEVICE_PATH;
     606                 :          0 :         devicep->sub_type = MEDIA_HARDDRIVE_DP;
     607                 :          0 :         devicep->length = offsetof(struct device_path, drive) + sizeof(struct drive_path);
     608                 :          0 :         memcpy(&devicep->drive.part_nr, &part, sizeof(uint32_t));
     609                 :          0 :         memcpy(&devicep->drive.part_start, &pstart, sizeof(uint64_t));
     610                 :          0 :         memcpy(&devicep->drive.part_size, &psize, sizeof(uint64_t));
     611                 :          0 :         id128_to_efi_guid(part_uuid, devicep->drive.signature);
     612                 :          0 :         devicep->drive.mbr_type = MBR_TYPE_EFI_PARTITION_TABLE_HEADER;
     613                 :          0 :         devicep->drive.signature_type = SIGNATURE_TYPE_GUID;
     614                 :          0 :         size += devicep->length;
     615                 :            : 
     616                 :            :         /* path to loader */
     617                 :          0 :         devicep = (struct device_path *)(buf + size);
     618                 :          0 :         devicep->type = MEDIA_DEVICE_PATH;
     619                 :          0 :         devicep->sub_type = MEDIA_FILEPATH_DP;
     620                 :          0 :         devicep->length = offsetof(struct device_path, path) + path_len;
     621                 :          0 :         to_utf16(devicep->path, path);
     622                 :          0 :         tilt_slashes(devicep->path);
     623                 :          0 :         size += devicep->length;
     624                 :            : 
     625                 :            :         /* end of path */
     626                 :          0 :         devicep = (struct device_path *)(buf + size);
     627                 :          0 :         devicep->type = END_DEVICE_PATH_TYPE;
     628                 :          0 :         devicep->sub_type = END_ENTIRE_DEVICE_PATH_SUBTYPE;
     629                 :          0 :         devicep->length = offsetof(struct device_path, path);
     630                 :          0 :         size += devicep->length;
     631                 :            : 
     632         [ #  # ]:          0 :         xsprintf(boot_id, "Boot%04X", id);
     633                 :          0 :         return efi_set_variable(EFI_VENDOR_GLOBAL, boot_id, buf, size);
     634                 :            : }
     635                 :            : 
     636                 :          0 : int efi_remove_boot_option(uint16_t id) {
     637                 :            :         char boot_id[9];
     638                 :            : 
     639         [ #  # ]:          0 :         if (!is_efi_boot())
     640                 :          0 :                 return -EOPNOTSUPP;
     641                 :            : 
     642         [ #  # ]:          0 :         xsprintf(boot_id, "Boot%04X", id);
     643                 :          0 :         return efi_set_variable(EFI_VENDOR_GLOBAL, boot_id, NULL, 0);
     644                 :            : }
     645                 :            : 
     646                 :          0 : int efi_get_boot_order(uint16_t **order) {
     647                 :          0 :         _cleanup_free_ void *buf = NULL;
     648                 :            :         size_t l;
     649                 :            :         int r;
     650                 :            : 
     651         [ #  # ]:          0 :         if (!is_efi_boot())
     652                 :          0 :                 return -EOPNOTSUPP;
     653                 :            : 
     654                 :          0 :         r = efi_get_variable(EFI_VENDOR_GLOBAL, "BootOrder", NULL, &buf, &l);
     655         [ #  # ]:          0 :         if (r < 0)
     656                 :          0 :                 return r;
     657                 :            : 
     658         [ #  # ]:          0 :         if (l <= 0)
     659                 :          0 :                 return -ENOENT;
     660                 :            : 
     661         [ #  # ]:          0 :         if (l % sizeof(uint16_t) > 0 ||
     662         [ #  # ]:          0 :             l / sizeof(uint16_t) > INT_MAX)
     663                 :          0 :                 return -EINVAL;
     664                 :            : 
     665                 :          0 :         *order = TAKE_PTR(buf);
     666                 :          0 :         return (int) (l / sizeof(uint16_t));
     667                 :            : }
     668                 :            : 
     669                 :          0 : int efi_set_boot_order(uint16_t *order, size_t n) {
     670                 :            : 
     671         [ #  # ]:          0 :         if (!is_efi_boot())
     672                 :          0 :                 return -EOPNOTSUPP;
     673                 :            : 
     674                 :          0 :         return efi_set_variable(EFI_VENDOR_GLOBAL, "BootOrder", order, n * sizeof(uint16_t));
     675                 :            : }
     676                 :            : 
     677                 :          0 : static int boot_id_hex(const char s[static 4]) {
     678                 :          0 :         int id = 0, i;
     679                 :            : 
     680         [ #  # ]:          0 :         assert(s);
     681                 :            : 
     682         [ #  # ]:          0 :         for (i = 0; i < 4; i++)
     683   [ #  #  #  # ]:          0 :                 if (s[i] >= '0' && s[i] <= '9')
     684                 :          0 :                         id |= (s[i] - '0') << (3 - i) * 4;
     685   [ #  #  #  # ]:          0 :                 else if (s[i] >= 'A' && s[i] <= 'F')
     686                 :          0 :                         id |= (s[i] - 'A' + 10) << (3 - i) * 4;
     687                 :            :                 else
     688                 :          0 :                         return -EINVAL;
     689                 :            : 
     690                 :          0 :         return id;
     691                 :            : }
     692                 :            : 
     693                 :          0 : static int cmp_uint16(const uint16_t *a, const uint16_t *b) {
     694         [ #  # ]:          0 :         return CMP(*a, *b);
     695                 :            : }
     696                 :            : 
     697                 :          0 : int efi_get_boot_options(uint16_t **options) {
     698                 :          0 :         _cleanup_closedir_ DIR *dir = NULL;
     699                 :          0 :         _cleanup_free_ uint16_t *list = NULL;
     700                 :            :         struct dirent *de;
     701                 :          0 :         size_t alloc = 0;
     702                 :          0 :         int count = 0;
     703                 :            : 
     704         [ #  # ]:          0 :         assert(options);
     705                 :            : 
     706         [ #  # ]:          0 :         if (!is_efi_boot())
     707                 :          0 :                 return -EOPNOTSUPP;
     708                 :            : 
     709                 :          0 :         dir = opendir("/sys/firmware/efi/efivars/");
     710         [ #  # ]:          0 :         if (!dir)
     711                 :          0 :                 return -errno;
     712                 :            : 
     713   [ #  #  #  #  :          0 :         FOREACH_DIRENT(de, dir, return -errno) {
                   #  # ]
     714                 :            :                 int id;
     715                 :            : 
     716         [ #  # ]:          0 :                 if (strncmp(de->d_name, "Boot", 4) != 0)
     717                 :          0 :                         continue;
     718                 :            : 
     719         [ #  # ]:          0 :                 if (strlen(de->d_name) != 45)
     720                 :          0 :                         continue;
     721                 :            : 
     722         [ #  # ]:          0 :                 if (strcmp(de->d_name + 8, "-8be4df61-93ca-11d2-aa0d-00e098032b8c") != 0)
     723                 :          0 :                         continue;
     724                 :            : 
     725                 :          0 :                 id = boot_id_hex(de->d_name + 4);
     726         [ #  # ]:          0 :                 if (id < 0)
     727                 :          0 :                         continue;
     728                 :            : 
     729         [ #  # ]:          0 :                 if (!GREEDY_REALLOC(list, alloc, count + 1))
     730                 :          0 :                         return -ENOMEM;
     731                 :            : 
     732                 :          0 :                 list[count++] = id;
     733                 :            :         }
     734                 :            : 
     735                 :          0 :         typesafe_qsort(list, count, cmp_uint16);
     736                 :            : 
     737                 :          0 :         *options = TAKE_PTR(list);
     738                 :            : 
     739                 :          0 :         return count;
     740                 :            : }
     741                 :            : 
     742                 :          0 : static int read_usec(sd_id128_t vendor, const char *name, usec_t *u) {
     743                 :          0 :         _cleanup_free_ char *j = NULL;
     744                 :            :         int r;
     745                 :          0 :         uint64_t x = 0;
     746                 :            : 
     747         [ #  # ]:          0 :         assert(name);
     748         [ #  # ]:          0 :         assert(u);
     749                 :            : 
     750                 :          0 :         r = efi_get_variable_string(EFI_VENDOR_LOADER, name, &j);
     751         [ #  # ]:          0 :         if (r < 0)
     752                 :          0 :                 return r;
     753                 :            : 
     754                 :          0 :         r = safe_atou64(j, &x);
     755         [ #  # ]:          0 :         if (r < 0)
     756                 :          0 :                 return r;
     757                 :            : 
     758                 :          0 :         *u = x;
     759                 :          0 :         return 0;
     760                 :            : }
     761                 :            : 
     762                 :          8 : int efi_loader_get_boot_usec(usec_t *firmware, usec_t *loader) {
     763                 :            :         uint64_t x, y;
     764                 :            :         int r;
     765                 :            : 
     766         [ -  + ]:          8 :         assert(firmware);
     767         [ -  + ]:          8 :         assert(loader);
     768                 :            : 
     769         [ +  - ]:          8 :         if (!is_efi_boot())
     770                 :          8 :                 return -EOPNOTSUPP;
     771                 :            : 
     772                 :          0 :         r = read_usec(EFI_VENDOR_LOADER, "LoaderTimeInitUSec", &x);
     773         [ #  # ]:          0 :         if (r < 0)
     774                 :          0 :                 return r;
     775                 :            : 
     776                 :          0 :         r = read_usec(EFI_VENDOR_LOADER, "LoaderTimeExecUSec", &y);
     777         [ #  # ]:          0 :         if (r < 0)
     778                 :          0 :                 return r;
     779                 :            : 
     780   [ #  #  #  # ]:          0 :         if (y == 0 || y < x)
     781                 :          0 :                 return -EIO;
     782                 :            : 
     783         [ #  # ]:          0 :         if (y > USEC_PER_HOUR)
     784                 :          0 :                 return -EIO;
     785                 :            : 
     786                 :          0 :         *firmware = x;
     787                 :          0 :         *loader = y;
     788                 :            : 
     789                 :          0 :         return 0;
     790                 :            : }
     791                 :            : 
     792                 :          0 : int efi_loader_get_device_part_uuid(sd_id128_t *u) {
     793                 :          0 :         _cleanup_free_ char *p = NULL;
     794                 :            :         int r, parsed[16];
     795                 :            : 
     796         [ #  # ]:          0 :         if (!is_efi_boot())
     797                 :          0 :                 return -EOPNOTSUPP;
     798                 :            : 
     799                 :          0 :         r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderDevicePartUUID", &p);
     800         [ #  # ]:          0 :         if (r < 0)
     801                 :          0 :                 return r;
     802                 :            : 
     803         [ #  # ]:          0 :         if (sscanf(p, SD_ID128_UUID_FORMAT_STR,
     804                 :            :                    &parsed[0], &parsed[1], &parsed[2], &parsed[3],
     805                 :            :                    &parsed[4], &parsed[5], &parsed[6], &parsed[7],
     806                 :            :                    &parsed[8], &parsed[9], &parsed[10], &parsed[11],
     807                 :            :                    &parsed[12], &parsed[13], &parsed[14], &parsed[15]) != 16)
     808                 :          0 :                 return -EIO;
     809                 :            : 
     810         [ #  # ]:          0 :         if (u) {
     811                 :            :                 unsigned i;
     812                 :            : 
     813         [ #  # ]:          0 :                 for (i = 0; i < ELEMENTSOF(parsed); i++)
     814                 :          0 :                         u->bytes[i] = parsed[i];
     815                 :            :         }
     816                 :            : 
     817                 :          0 :         return 0;
     818                 :            : }
     819                 :            : 
     820                 :          0 : int efi_loader_get_entries(char ***ret) {
     821                 :          0 :         _cleanup_free_ char16_t *entries = NULL;
     822                 :          0 :         _cleanup_strv_free_ char **l = NULL;
     823                 :            :         size_t size, i, start;
     824                 :            :         int r;
     825                 :            : 
     826         [ #  # ]:          0 :         assert(ret);
     827                 :            : 
     828         [ #  # ]:          0 :         if (!is_efi_boot())
     829                 :          0 :                 return -EOPNOTSUPP;
     830                 :            : 
     831                 :          0 :         r = efi_get_variable(EFI_VENDOR_LOADER, "LoaderEntries", NULL, (void**) &entries, &size);
     832         [ #  # ]:          0 :         if (r < 0)
     833                 :          0 :                 return r;
     834                 :            : 
     835                 :            :         /* The variable contains a series of individually NUL terminated UTF-16 strings. */
     836                 :            : 
     837                 :          0 :         for (i = 0, start = 0;; i++) {
     838   [ #  #  #  # ]:          0 :                 _cleanup_free_ char *decoded = NULL;
     839                 :            :                 bool end;
     840                 :            : 
     841                 :            :                 /* Is this the end of the variable's data? */
     842                 :          0 :                 end = i * sizeof(char16_t) >= size;
     843                 :            : 
     844                 :            :                 /* Are we in the middle of a string? (i.e. not at the end of the variable, nor at a NUL terminator?) If
     845                 :            :                  * so, let's go to the next entry. */
     846   [ #  #  #  # ]:          0 :                 if (!end && entries[i] != 0)
     847                 :          0 :                         continue;
     848                 :            : 
     849                 :            :                 /* We reached the end of a string, let's decode it into UTF-8 */
     850                 :          0 :                 decoded = utf16_to_utf8(entries + start, (i - start) * sizeof(char16_t));
     851         [ #  # ]:          0 :                 if (!decoded)
     852                 :          0 :                         return -ENOMEM;
     853                 :            : 
     854         [ #  # ]:          0 :                 if (efi_loader_entry_name_valid(decoded)) {
     855                 :          0 :                         r = strv_consume(&l, TAKE_PTR(decoded));
     856         [ #  # ]:          0 :                         if (r < 0)
     857                 :          0 :                                 return r;
     858                 :            :                 } else
     859         [ #  # ]:          0 :                         log_debug("Ignoring invalid loader entry '%s'.", decoded);
     860                 :            : 
     861                 :            :                 /* We reached the end of the variable */
     862         [ #  # ]:          0 :                 if (end)
     863                 :          0 :                         break;
     864                 :            : 
     865                 :            :                 /* Continue after the NUL byte */
     866                 :          0 :                 start = i + 1;
     867                 :            :         }
     868                 :            : 
     869                 :          0 :         *ret = TAKE_PTR(l);
     870                 :          0 :         return 0;
     871                 :            : }
     872                 :            : 
     873                 :          0 : int efi_loader_get_features(uint64_t *ret) {
     874                 :          0 :         _cleanup_free_ void *v = NULL;
     875                 :            :         size_t s;
     876                 :            :         int r;
     877                 :            : 
     878         [ #  # ]:          0 :         if (!is_efi_boot()) {
     879                 :          0 :                 *ret = 0;
     880                 :          0 :                 return 0;
     881                 :            :         }
     882                 :            : 
     883                 :          0 :         r = efi_get_variable(EFI_VENDOR_LOADER, "LoaderFeatures", NULL, &v, &s);
     884         [ #  # ]:          0 :         if (r == -ENOENT) {
     885                 :          0 :                 _cleanup_free_ char *info = NULL;
     886                 :            : 
     887                 :            :                 /* The new (v240+) LoaderFeatures variable is not supported, let's see if it's systemd-boot at all */
     888                 :          0 :                 r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderInfo", &info);
     889         [ #  # ]:          0 :                 if (r < 0) {
     890         [ #  # ]:          0 :                         if (r != -ENOENT)
     891                 :          0 :                                 return r;
     892                 :            : 
     893                 :            :                         /* Variable not set, definitely means not systemd-boot */
     894                 :            : 
     895         [ #  # ]:          0 :                 } else if (first_word(info, "systemd-boot")) {
     896                 :            : 
     897                 :            :                         /* An older systemd-boot version. Let's hardcode the feature set, since it was pretty
     898                 :            :                          * static in all its versions. */
     899                 :            : 
     900                 :          0 :                         *ret = EFI_LOADER_FEATURE_CONFIG_TIMEOUT |
     901                 :            :                                 EFI_LOADER_FEATURE_ENTRY_DEFAULT |
     902                 :            :                                 EFI_LOADER_FEATURE_ENTRY_ONESHOT;
     903                 :            : 
     904                 :          0 :                         return 0;
     905                 :            :                 }
     906                 :            : 
     907                 :            :                 /* No features supported */
     908                 :          0 :                 *ret = 0;
     909                 :          0 :                 return 0;
     910                 :            :         }
     911         [ #  # ]:          0 :         if (r < 0)
     912                 :          0 :                 return r;
     913                 :            : 
     914         [ #  # ]:          0 :         if (s != sizeof(uint64_t))
     915         [ #  # ]:          0 :                 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
     916                 :            :                                        "LoaderFeatures EFI variable doesn't have the right size.");
     917                 :            : 
     918                 :          0 :         memcpy(ret, v, sizeof(uint64_t));
     919                 :          0 :         return 0;
     920                 :            : }
     921                 :            : 
     922                 :            : #endif
     923                 :            : 
     924                 :          0 : bool efi_loader_entry_name_valid(const char *s) {
     925         [ #  # ]:          0 :         if (isempty(s))
     926                 :          0 :                 return false;
     927                 :            : 
     928         [ #  # ]:          0 :         if (strlen(s) > FILENAME_MAX) /* Make sure entry names fit in filenames */
     929                 :          0 :                 return false;
     930                 :            : 
     931                 :          0 :         return in_charset(s, ALPHANUMERICAL "+-_.");
     932                 :            : }
     933                 :            : 
     934                 :          0 : char *efi_tilt_backslashes(char *s) {
     935                 :            :         char *p;
     936                 :            : 
     937         [ #  # ]:          0 :         for (p = s; *p; p++)
     938         [ #  # ]:          0 :                 if (*p == '\\')
     939                 :          0 :                         *p = '/';
     940                 :            : 
     941                 :          0 :         return s;
     942                 :            : }

Generated by: LCOV version 1.14