]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #26203 from medhefgo/meson
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 22 Feb 2023 01:27:16 +0000 (10:27 +0900)
committerGitHub <noreply@github.com>
Wed, 22 Feb 2023 01:27:16 +0000 (10:27 +0900)
meson: Use dicts for test/fuzzer definitions

126 files changed:
.editorconfig
.github/workflows/mkosi.yml
docs/JOURNAL_FILE_FORMAT.md
man/bootctl.xml
man/systemctl.xml
man/systemd-socket-proxyd.xml
mkosi.build
mkosi.conf.d/10-systemd.conf
mkosi.extra/etc/issue [new file with mode: 0644]
mkosi.extra/etc/systemd/system/mkosi-check-and-shutdown.service [moved from test/mkosi-check-and-shutdown.service with 100% similarity]
mkosi.extra/etc/systemd/system/mkosi-check-and-shutdown.sh [moved from test/mkosi-check-and-shutdown.sh with 100% similarity, mode: 0755]
mkosi.extra/root/.gdbinit [new file with mode: 0644]
mkosi.postinst
po/lt.po
shell-completion/bash/systemctl.in
shell-completion/zsh/_systemctl.in
src/basic/process-util.c
src/basic/process-util.h
src/boot/bootctl.c
src/boot/bootctl.h
src/boot/efi/bcd.h
src/boot/efi/boot.c
src/boot/efi/console.c
src/boot/efi/console.h
src/boot/efi/cpio.c
src/boot/efi/cpio.h
src/boot/efi/devicetree.c
src/boot/efi/devicetree.h
src/boot/efi/disk.c
src/boot/efi/disk.h
src/boot/efi/drivers.c
src/boot/efi/drivers.h
src/boot/efi/efi-string.c
src/boot/efi/efi-string.h
src/boot/efi/efi.h [new file with mode: 0644]
src/boot/efi/graphics.c
src/boot/efi/graphics.h
src/boot/efi/initrd.c
src/boot/efi/initrd.h
src/boot/efi/linux.c
src/boot/efi/linux.h
src/boot/efi/linux_x86.c
src/boot/efi/log.c
src/boot/efi/measure.c
src/boot/efi/measure.h
src/boot/efi/meson.build
src/boot/efi/missing_efi.h [deleted file]
src/boot/efi/part-discovery.c
src/boot/efi/part-discovery.h
src/boot/efi/pe.c
src/boot/efi/pe.h
src/boot/efi/proto/block-io.h [new file with mode: 0644]
src/boot/efi/proto/console-control.h [new file with mode: 0644]
src/boot/efi/proto/device-path.h [new file with mode: 0644]
src/boot/efi/proto/dt-fixup.h [new file with mode: 0644]
src/boot/efi/proto/file-io.h [new file with mode: 0644]
src/boot/efi/proto/graphics-output.h [new file with mode: 0644]
src/boot/efi/proto/load-file.h [new file with mode: 0644]
src/boot/efi/proto/loaded-image.h [new file with mode: 0644]
src/boot/efi/proto/rng.h [new file with mode: 0644]
src/boot/efi/proto/security-arch.h [new file with mode: 0644]
src/boot/efi/proto/shell-parameters.h [new file with mode: 0644]
src/boot/efi/proto/simple-text-io.h [new file with mode: 0644]
src/boot/efi/proto/tcg.h [new file with mode: 0644]
src/boot/efi/random-seed.c
src/boot/efi/random-seed.h
src/boot/efi/secure-boot.c
src/boot/efi/secure-boot.h
src/boot/efi/shim.c
src/boot/efi/shim.h
src/boot/efi/splash.c
src/boot/efi/splash.h
src/boot/efi/stub.c
src/boot/efi/ticks.c
src/boot/efi/util.c
src/boot/efi/util.h
src/boot/efi/vmm.c
src/boot/efi/vmm.h
src/core/unit.c
src/fundamental/efivars-fundamental.h
src/fundamental/macro-fundamental.h
src/fundamental/string-util-fundamental.c
src/fundamental/string-util-fundamental.h
src/gpt-auto-generator/gpt-auto-generator.c
src/home/homed-home.c
src/import/import-common.c
src/import/importd.c
src/import/pull-common.c
src/journal-remote/journal-remote-main.c
src/journal/journald-server.c
src/journal/managed-journal-file.c
src/journal/test-journal-interleaving.c
src/libsystemd/sd-bus/bus-socket.c
src/libsystemd/sd-journal/journal-authenticate.c
src/libsystemd/sd-journal/journal-def.h
src/libsystemd/sd-journal/journal-file.c
src/libsystemd/sd-journal/journal-file.h
src/libsystemd/sd-journal/journal-verify.c
src/libsystemd/sd-journal/sd-journal.c
src/login/logind-brightness.c
src/login/logind-session.c
src/login/pam_systemd.c
src/nspawn/nspawn-setuid.c
src/resolve/test-resolved-stream.c
src/shared/blockdev-util.c
src/shared/blockdev-util.h
src/shared/dissect-image.c
src/shared/elf-util.c
src/shared/exec-util.c
src/shared/install.c
src/shared/pager.c
src/shared/sleep-config.c
src/shared/sleep-config.h
src/shutdown/umount.c
src/sleep/sleep.c
src/socket-proxy/socket-proxyd.c
src/systemctl/systemctl-list-units.c
src/systemctl/systemctl-list-units.h
src/systemctl/systemctl.c
src/sysupdate/sysupdate-resource.c
src/test/test-execute.c
src/test/test-process-util.c
src/udev/udev-event.c
test/test-bootctl-json.sh
test/units/testsuite-26.sh
test/units/testsuite-70.sh

index 27bb3755d60e2a06d0b871308fbf6a2e5d90d1f8..071dac0c11af317c37b9bebc7282479f94cb95f0 100644 (file)
@@ -20,7 +20,7 @@ indent_style = space
 indent_size = 8
 max_line_length = 109
 
-[*.sh]
+[*.sh,mkosi.build,mkosi.prepare,mkosi.postinst]
 indent_style = space
 indent_size = 4
 
index 22673d417a20f9905452ef96edcf4b7e9c9ca061..b4d89a7f2471e461aa4b20fa476342e72986b3fe 100644 (file)
@@ -79,7 +79,7 @@ jobs:
 
     steps:
     - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b
-    - uses: systemd/mkosi@4be912b0fa4931403fddf649aa242cd4406471c4
+    - uses: systemd/mkosi@1d131062066fe7b5a83b87319b4464b186adbb1c
 
     - name: Configure
       run: |
index 2d0debd858c0120a5ecfc688e512e81a286dd01e..712f3bce36deea6f828c646c3394d91e904b274a 100644 (file)
@@ -151,7 +151,7 @@ _packed_ struct Header {
         uint8_t reserved[7];
         sd_id128_t file_id;
         sd_id128_t machine_id;
-        sd_id128_t boot_id;    /* last writer */
+        sd_id128_t tail_entry_boot_id;
         sd_id128_t seqnum_id;
         le64_t header_size;
         le64_t arena_size;
@@ -192,8 +192,18 @@ new one.
 When journal file is first created the **file_id** is randomly and uniquely
 initialized.
 
-When a writer opens a file it shall initialize the **boot_id** to the current
-boot id of the system.
+When a writer creates a file it shall initialize the **tail_entry_boot_id** to
+the current boot ID of the system. When appending an entry it shall update the
+field to the boot ID of that entry, so that it is guaranteed that the
+**tail_entry_monotonic** field refers to a timestamp of the monotonic clock
+associated with the boot with the ID indicated by the **tail_entry_boot_id**
+field. (Compatibility note: in older versions of the journal, the field was
+also supposed to be updated whenever the file was opened for any form of
+writing, including when opened to mark it as archived. This behaviour has been
+deemed problematic since without an associated boot ID the
+**tail_entry_monotonic** field is useless. To indicate whether the boot ID is
+updated only on append the JOURNAL_COMPATIBLE_TAIL_ENTRY_BOOT_ID is set. If it
+is not set, the **tail_entry_monotonic** field is not usable).
 
 The currently used part of the file is the **header_size** plus the
 **arena_size** field of the header. If a writer needs to write to a file where
@@ -222,7 +232,12 @@ timestamp of the last or first entry in the file, respectively, or 0 if no
 entry has been written yet.
 
 **tail_entry_monotonic** is the monotonic timestamp of the last entry in the
-file, referring to monotonic time of the boot identified by **boot_id**.
+file, referring to monotonic time of the boot identified by
+**tail_entry_boot_id**, but only if the
+JOURNAL_COMPATIBLE_TAIL_ENTRY_BOOT_ID feature flag is set, see above. If it
+is not set, this field might refer to a different boot then the one in the
+**tail_entry_boot_id** field, for example when the file was ultimately
+archived.
 
 **data_hash_chain_depth** is a counter of the deepest chain in the data hash
 table, minus one. This is updated whenever a chain is found that is longer than
@@ -268,7 +283,8 @@ enum {
 };
 
 enum {
-        HEADER_COMPATIBLE_SEALED = 1 << 0,
+        HEADER_COMPATIBLE_SEALED             = 1 << 0,
+        HEADER_COMPATIBLE_TAIL_ENTRY_BOOT_ID = 1 << 1,
 };
 ```
 
@@ -288,6 +304,12 @@ format that uses less space on disk compared to the original format.
 HEADER_COMPATIBLE_SEALED indicates that the file includes TAG objects required
 for Forward Secure Sealing.
 
+HEADER_COMPATIBLE_TAIL_ENTRY_BOOT_ID indicates whether the
+**tail_entry_boot_id** field is strictly updated on initial creation of the
+file and whenever an entry is updated (in which case the flag is set), or also
+when the file is archived (in which case it is unset). New files should always
+set this flag (and thus not update the **tail_entry_boot_id** except when
+creating the file and when appending an entry to it.
 
 ## Dirty Detection
 
index 42c4b9a8e67c64905459f30936bb6debdf46b0de..4fec552ca89ac5a0481d7ae1c2423f5b65fc62a6 100644 (file)
         <command>systemd-boot</command> being installed.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>-R</option></term>
+        <term><option>--print-root-device</option></term>
+
+        <listitem><para>Print the path to the block device node backing the root file system of the local
+        OS. This prints a path such as <filename>/dev/nvme0n1p5</filename>. If the root file system is backed
+        by dm-crypt/LUKS or dm-verity the underlying block device is returned. If the root file system is
+        backed by multiple block devices (as supported by btrfs) the operation will fail. If the switch is
+        specified twice (i.e. <option>-RR</option>) and the discovered block device is a partition device the
+        "whole" block device it belongs to is determined and printed
+        (e.g. <filename>/dev/nvme0n1</filename>). If the root file system is <literal>tmpfs</literal> (or a
+        similar in-memory file system), the block device backing <filename>/usr/</filename> is returned if
+        applicable. If the root file system is a network file system (e.g. NFS, CIFS) the operation will
+        fail.</para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><option>--no-variables</option></term>
         <listitem><para>Do not touch the firmware's boot loader list stored in EFI variables.</para></listitem>
 
   <refsect1>
     <title>Exit status</title>
-    <para>On success, 0 is returned, a non-zero failure code otherwise.</para>
+    <para>On success, 0 is returned, a non-zero failure code otherwise. <command>bootctl
+    --print-root-device</command> returns exit status 80 in case the root file system is not backed by single
+    block device, and other non-zero exit statusses on other errors.</para>
   </refsect1>
 
   <refsect1>
index dfaca638c2a8ed0a2fb30ce32aba382d338c8b52..7ac3a4267d567baa509aa3343db7b53e192db24e 100644 (file)
@@ -127,6 +127,26 @@ binfmt_misc /proc/sys/fs/binfmt_misc yes     0            proc-sys-fs-binfmt_mis
           </listitem>
         </varlistentry>
 
+        <varlistentry>
+          <term><command>list-paths</command> <optional><replaceable>PATTERN</replaceable>…</optional></term>
+
+          <listitem>
+            <para>List path units currently in memory, ordered by path.  If one or more
+            <replaceable>PATTERN</replaceable>s are specified, only path units matching one of them are shown.
+            Produces output similar to
+            <programlisting>
+PATH                           CONDITION         UNIT                               ACTIVATES
+/run/systemd/ask-password      DirectoryNotEmpty systemd-ask-password-plymouth.path systemd-ask-password-plymouth.service
+/run/systemd/ask-password      DirectoryNotEmpty systemd-ask-password-wall.path     systemd-ask-password-wall.service
+/var/cache/cups/org.cups.cupsd PathExists        cups.path                          cups.service
+
+3 paths listed.</programlisting>
+            </para>
+
+            <para>Also see <option>--show-types</option>, <option>--all</option>, and <option>--state=</option>.</para>
+          </listitem>
+        </varlistentry>
+
         <varlistentry>
           <term><command>list-sockets</command> <optional><replaceable>PATTERN</replaceable>…</optional></term>
 
index e512a4334e95752b1097b150c67b3210c86d0998..bf51c0558c424f2566f4ac339d16cb5c22cbbe11 100644 (file)
@@ -104,6 +104,7 @@ Requires=proxy-to-nginx.socket
 After=proxy-to-nginx.socket
 
 [Service]
+Type=notify
 ExecStart=/usr/lib/systemd/systemd-socket-proxyd /run/nginx/socket
 PrivateTmp=yes
 PrivateNetwork=yes]]></programlisting>
@@ -151,6 +152,7 @@ After=proxy-to-nginx.socket
 JoinsNamespaceOf=nginx.service
 
 [Service]
+Type=notify
 ExecStart=/usr/lib/systemd/systemd-socket-proxyd 127.0.0.1:8080
 PrivateTmp=yes
 PrivateNetwork=yes]]></programlisting>
index b9ee0f1ae2d443405bddfdc999d0ac456e2553bc..7968051289da58c6026edc5027892dd9727adb43 100755 (executable)
@@ -5,21 +5,6 @@ set -e
 # This is a build script for OS image generation using mkosi (https://github.com/systemd/mkosi).
 # Simply invoke "mkosi" in the project directory to build an OS image.
 
-ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:disable_coredump=0:use_madv_dontdump=1
-UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1
-
-# On Fedora "ld" is (unfortunately â€” if you ask me) managed via
-# "alternatives". Since we'd like to support building images in environments
-# with only /usr/ around (e.g. mkosi's UsrOnly=1 option), we have the problem
-# that /usr/bin/ld is a symlink that points to a non-existing file in
-# /etc/alternative/ in this mode. Let's work around this for now by manually
-# redirect "ld" to "ld.bfd", i.e. circumventing the /usr/bin/ld symlink.
-if [ ! -x /usr/bin/ld ] && [ -x /usr/bin/ld.bfd ]; then
-        mkdir -p "$HOME"/bin
-        ln -s /usr/bin/ld.bfd "$HOME"/bin/ld
-        PATH="$HOME/bin:$PATH"
-fi
-
 # If mkosi.builddir/ exists mkosi will set $BUILDDIR to it, let's then use it
 # as out-of-tree build dir. Otherwise, let's make up our own builddir.
 [ -z "$BUILDDIR" ] && BUILDDIR="$PWD"/build
@@ -28,282 +13,177 @@ fi
 PATH="$BUILDDIR:$PATH"
 export PATH
 
-# Meson uses Python 3 and requires a locale with an UTF-8 character map.
-# Not running under UTF-8 makes the `ninja test` step break with a CodecError.
-# So let's ensure we're running under UTF-8.
-#
-# If our current locale already is UTF-8, then we don't need to do anything:
-if [ "$(locale charmap 2>/dev/null)" != "UTF-8" ] ; then
-        # Try using C.UTF-8 locale, if available. This locale is not shipped
-        # by upstream glibc, so it's not available in all distros.
-        # (In particular, it's not available in Arch Linux.)
-        if locale -a | grep -q -E "C.UTF-8|C.utf8"; then
-                export LC_CTYPE=C.UTF-8
-        # Finally, try something like en_US.UTF-8, which should be
-        # available in Arch Linux, but is not present in Debian's
-        # minimal image in our mkosi config.
-        elif locale -a | grep -q en_US.utf8; then
-                export LC_CTYPE=en_US.UTF-8
-        else
-                # If nothing works, fail early.
-                echo "*** Could not find a valid locale that supports UTF-8. ***" >&2
-                exit 1
-        fi
-fi
-
 # The bpftool script shipped by Ubuntu tries to find the actual program to run via querying `uname -r` and
 # using the current kernel version. This obviously doesn't work in containers. As a workaround, we override
 # the ubuntu script with a symlink to the first bpftool program we can find.
 for bpftool in /usr/lib/linux-tools/*/bpftool; do
-        [ -x "$bpftool" ] || continue
-        ln -sf "$bpftool" "$BUILDDIR"/bpftool
-        break
+    [ -x "$bpftool" ] || continue
+    ln -sf "$bpftool" "$BUILDDIR"/bpftool
+    break
 done
 
 # CentOS Stream 8 includes bpftool 4.18.0 which is lower than what we need. However, they've backported the
 # specific feature we need ("gen skeleton") to this version, so we replace bpftool with a script that reports
 # version 5.6.0 to satisfy meson which makes bpf work on CentOS Stream 8 as well.
 if [ "$(grep '^ID=' /etc/os-release)" = "ID=\"centos\"" ] && [ "$(grep '^VERSION=' /etc/os-release)" = "VERSION=\"8\"" ]; then
-        cat >"$BUILDDIR"/bpftool <<EOF
+    cat >"$BUILDDIR"/bpftool <<EOF
 #!/bin/sh
 if [ "\$1" = --version ]; then
-        echo 5.6.0
+    echo 5.6.0
 else
-        exec /usr/sbin/bpftool \$@
+    exec /usr/sbin/bpftool \$@
 fi
 EOF
-        chmod +x "$BUILDDIR"/bpftool
+    chmod +x "$BUILDDIR"/bpftool
 fi
 
 if [ ! -f "$BUILDDIR"/build.ninja ] ; then
-        sysvinit_path=$(realpath /etc/init.d)
-
-        init_path=$(realpath /sbin/init 2>/dev/null)
-        if [ -z "$init_path" ] ; then
-                rootprefix=""
-        else
-                rootprefix=${init_path%/lib/systemd/systemd}
-                rootprefix=/${rootprefix#/}
-        fi
-
-        # On debian-like systems the library directory is not /usr/lib64 but /usr/lib/<arch-triplet>/.
-        # It is important to use the right one especially for cryptsetup plugins, otherwise they will be
-        # installed in the wrong directory and not be found by cryptsetup. Assume native build.
-        if grep -q -e "ID=debian" -e "ID_LIKE=debian" /etc/os-release && command -v dpkg 2>/dev/null; then
-                LIBDIR="-Drootlibdir=/usr/lib/$(dpkg-architecture -qDEB_HOST_MULTIARCH)"
-                PAMDIR="-Dpamlibdir=/usr/lib/$(dpkg-architecture -qDEB_HOST_MULTIARCH)/security"
-        fi
-
-        # Cannot quote $LIBDIR and $PAMDIR, because they may be empty, and meson will fail.
-        # shellcheck disable=SC2086
-        meson setup "$BUILDDIR" \
-                ${LIBDIR:-} \
-                ${PAMDIR:-} \
-                -D "sysvinit-path=$sysvinit_path" \
-                -D "rootprefix=$rootprefix" \
-                -D man=false \
-                -D translations=false \
-                -D version-tag="${VERSION_TAG}" \
-                -D mode=developer \
-                -D b_sanitize="${SANITIZERS:-none}" \
-                -D install-tests=true \
-                -D tests=unsafe \
-                -D slow-tests=true \
-                -D utmp=true \
-                -D hibernate=true \
-                -D ldconfig=true \
-                -D resolve=true \
-                -D efi=true \
-                -D tpm=true \
-                -D environment-d=true \
-                -D binfmt=true \
-                -D repart=true \
-                -D sysupdate=true \
-                -D coredump=true \
-                -D pstore=true \
-                -D oomd=true \
-                -D logind=true \
-                -D hostnamed=true \
-                -D localed=true \
-                -D machined=true \
-                -D portabled=true \
-                -D sysext=true \
-                -D userdb=true \
-                -D homed=true \
-                -D networkd=true \
-                -D timedated=true \
-                -D timesyncd=true \
-                -D remote=true \
-                -D nss-myhostname=true \
-                -D nss-mymachines=true \
-                -D nss-resolve=true \
-                -D nss-systemd=true \
-                -D firstboot=true \
-                -D randomseed=true \
-                -D backlight=true \
-                -D vconsole=true \
-                -D quotacheck=true \
-                -D sysusers=true \
-                -D tmpfiles=true \
-                -D importd=true \
-                -D hwdb=true \
-                -D rfkill=true \
-                -D xdg-autostart=true \
-                -D translations=true \
-                -D polkit=true \
-                -D acl=true \
-                -D audit=true \
-                -D blkid=true \
-                -D fdisk=true \
-                -D kmod=true  \
-                -D pam=true \
-                -D pwquality=true \
-                -D microhttpd=true \
-                -D libcryptsetup=true \
-                -D libcurl=true \
-                -D idn=true \
-                -D libidn2=true \
-                -D qrencode=true \
-                -D gcrypt=true \
-                -D gnutls=true \
-                -D openssl=true \
-                -D cryptolib=openssl \
-                -D p11kit=true \
-                -D libfido2=true \
-                -D tpm2=true \
-                -D elfutils=true \
-                -D zstd=true \
-                -D xkbcommon=true \
-                -D pcre2=true \
-                -D glib=true \
-                -D dbus=true \
-                -D gnu-efi=true \
-                -D kernel-install=true \
-                -D analyze=true \
-                -D bpf-framework=true \
-                -D ukify=true
+    sysvinit_path=$(realpath /etc/init.d)
+
+    init_path=$(realpath /sbin/init 2>/dev/null)
+    if [ -z "$init_path" ] ; then
+        rootprefix=""
+    else
+        rootprefix=${init_path%/lib/systemd/systemd}
+        rootprefix=/${rootprefix#/}
+    fi
+
+    # On debian-like systems the library directory is not /usr/lib64 but /usr/lib/<arch-triplet>/.
+    # It is important to use the right one especially for cryptsetup plugins, otherwise they will be
+    # installed in the wrong directory and not be found by cryptsetup. Assume native build.
+    if grep -q -e "ID=debian" -e "ID_LIKE=debian" /etc/os-release && command -v dpkg 2>/dev/null; then
+        LIBDIR="-Drootlibdir=/usr/lib/$(dpkg-architecture -qDEB_HOST_MULTIARCH)"
+        PAMDIR="-Dpamlibdir=/usr/lib/$(dpkg-architecture -qDEB_HOST_MULTIARCH)/security"
+    fi
+
+    # Cannot quote $LIBDIR and $PAMDIR, because they may be empty, and meson will fail.
+    # shellcheck disable=SC2086
+    meson setup "$BUILDDIR" \
+            ${LIBDIR:-} \
+            ${PAMDIR:-} \
+            -D "sysvinit-path=$sysvinit_path" \
+            -D "rootprefix=$rootprefix" \
+            -D man=false \
+            -D translations=false \
+            -D version-tag="${VERSION_TAG}" \
+            -D mode=developer \
+            -D b_sanitize="${SANITIZERS:-none}" \
+            -D install-tests=true \
+            -D tests=unsafe \
+            -D slow-tests=true \
+            -D utmp=true \
+            -D hibernate=true \
+            -D ldconfig=true \
+            -D resolve=true \
+            -D efi=true \
+            -D tpm=true \
+            -D environment-d=true \
+            -D binfmt=true \
+            -D repart=true \
+            -D sysupdate=true \
+            -D coredump=true \
+            -D pstore=true \
+            -D oomd=true \
+            -D logind=true \
+            -D hostnamed=true \
+            -D localed=true \
+            -D machined=true \
+            -D portabled=true \
+            -D sysext=true \
+            -D userdb=true \
+            -D homed=true \
+            -D networkd=true \
+            -D timedated=true \
+            -D timesyncd=true \
+            -D remote=true \
+            -D nss-myhostname=true \
+            -D nss-mymachines=true \
+            -D nss-resolve=true \
+            -D nss-systemd=true \
+            -D firstboot=true \
+            -D randomseed=true \
+            -D backlight=true \
+            -D vconsole=true \
+            -D quotacheck=true \
+            -D sysusers=true \
+            -D tmpfiles=true \
+            -D importd=true \
+            -D hwdb=true \
+            -D rfkill=true \
+            -D xdg-autostart=true \
+            -D translations=true \
+            -D polkit=true \
+            -D acl=true \
+            -D audit=true \
+            -D blkid=true \
+            -D fdisk=true \
+            -D kmod=true  \
+            -D pam=true \
+            -D pwquality=true \
+            -D microhttpd=true \
+            -D libcryptsetup=true \
+            -D libcurl=true \
+            -D idn=true \
+            -D libidn2=true \
+            -D qrencode=true \
+            -D gcrypt=true \
+            -D gnutls=true \
+            -D openssl=true \
+            -D cryptolib=openssl \
+            -D p11kit=true \
+            -D libfido2=true \
+            -D tpm2=true \
+            -D elfutils=true \
+            -D zstd=true \
+            -D xkbcommon=true \
+            -D pcre2=true \
+            -D glib=true \
+            -D dbus=true \
+            -D gnu-efi=true \
+            -D kernel-install=true \
+            -D analyze=true \
+            -D bpf-framework=true \
+            -D ukify=true
 fi
 
-cd "$BUILDDIR"
-ninja "$@"
+ninja -C "$BUILDDIR" "$@"
 if [ "$WITH_TESTS" = 1 ] ; then
-        if [ -n "$SANITIZERS" ]; then
-                export ASAN_OPTIONS="$ASAN_OPTIONS"
-                export UBSAN_OPTIONS="$UBSAN_OPTIONS"
-                TIMEOUT_MULTIPLIER=3
-        else
-                TIMEOUT_MULTIPLIER=1
-        fi
-
-        meson test --print-errorlogs --timeout-multiplier=$TIMEOUT_MULTIPLIER
+    if [ -n "$SANITIZERS" ]; then
+        export ASAN_OPTIONS="$MKOSI_ASAN_OPTIONS"
+        export UBSAN_OPTIONS="$MKOSI_UBSAN_OPTIONS"
+        TIMEOUT_MULTIPLIER=3
+    else
+        TIMEOUT_MULTIPLIER=1
+    fi
+
+    meson test -C "$BUILDDIR" --print-errorlogs --timeout-multiplier=$TIMEOUT_MULTIPLIER
 fi
-cd "$SRCDIR"
 
 meson install -C "$BUILDDIR" --quiet --no-rebuild --only-changed
 
-mkdir -p "$DESTDIR"/etc
-
-cat >"$DESTDIR"/etc/issue <<EOF
-\S (built from systemd tree)
-Kernel \r on an \m (\l)
-
-EOF
-
-if [ -n "$IMAGE_ID" ] ; then
-        mkdir -p "$DESTDIR"/usr/lib
-        sed -n \
-                -e '/^IMAGE_ID=/!p' \
-                -e "\$aIMAGE_ID=$IMAGE_ID" <"/usr/lib/os-release" >"${DESTDIR}/usr/lib/os-release"
-
-        OSRELEASEFILE="$DESTDIR"/usr/lib/os-release
-else
-        OSRELEASEFILE=/usr/lib/os-release
-fi
-
-
-if [ -n "$IMAGE_VERSION" ] ; then
-        mkdir -p "$DESTDIR"/usr/lib
-        sed -n \
-                -e '/^IMAGE_VERSION=/!p' \
-                -e "\$aIMAGE_VERSION=$IMAGE_VERSION" <$OSRELEASEFILE >"/tmp/os-release.tmp"
-
-        cat /tmp/os-release.tmp >"$DESTDIR"/usr/lib/os-release
-        rm /tmp/os-release.tmp
-fi
-
-# If $CI_BUILD is set, copy over the CI service which executes a service check
-# after boot and then shuts down the machine
-if [ -n "$CI_BUILD" ]; then
-        mkdir -p "$DESTDIR/usr/lib/systemd/system"
-        cp -v "$SRCDIR/test/mkosi-check-and-shutdown.service" "$DESTDIR/usr/lib/systemd/system/mkosi-check-and-shutdown.service"
-        cp -v "$SRCDIR/test/mkosi-check-and-shutdown.sh" "$DESTDIR/usr/lib/systemd/mkosi-check-and-shutdown.sh"
-        chmod +x "$DESTDIR/usr/lib/systemd/mkosi-check-and-shutdown.sh"
-fi
-
-if [ -n "$SANITIZERS" ]; then
-        LD_PRELOAD=$(ldd "$BUILDDIR"/systemd | grep libasan.so | awk '{print $3}')
-
-        mkdir -p "$DESTDIR/etc/systemd/system.conf.d"
-
-        cat >"$DESTDIR/etc/systemd/system.conf.d/10-asan.conf" <<EOF
-[Manager]
-ManagerEnvironment=ASAN_OPTIONS=$ASAN_OPTIONS\\
-                   UBSAN_OPTIONS=$UBSAN_OPTIONS\\
-                   LD_PRELOAD=$LD_PRELOAD
-DefaultEnvironment=ASAN_OPTIONS=$ASAN_OPTIONS\\
-                   UBSAN_OPTIONS=$UBSAN_OPTIONS\\
-                   LD_PRELOAD=$LD_PRELOAD
-EOF
-
-        # ASAN logs to stderr by default. However, journald's stderr is connected to /dev/null, so we lose
-        # all the ASAN logs. To rectify that, let's connect journald's stdout to the console so that any
-        # sanitizer failures appear directly on the user's console.
-        mkdir -p "$DESTDIR/etc/systemd/system/systemd-journald.service.d"
-
-        cat >"$DESTDIR/etc/systemd/system/systemd-journald.service.d/10-stdout-tty.conf" <<EOF
-[Service]
-StandardOutput=tty
-EOF
-
-        # Both systemd and util-linux's login call vhangup() on /dev/console which disconnects all users.
-        # This means systemd-journald can't log to /dev/console even if we configure `StandardOutput=tty`. As
-        # a workaround, we modify console-getty.service to disable systemd's vhangup() and disallow login
-        # from calling vhangup() so that journald's ASAN logs correctly end up in the console.
-
-        mkdir -p "$DESTDIR/etc/systemd/system/console-getty.service.d"
-
-        cat >"$DESTDIR/etc/systemd/system/console-getty.service.d/10-no-vhangup.conf" <<EOF
-[Service]
-TTYVHangup=no
-CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG
-EOF
-fi
-
-# Make sure services aren't enabled by default on Debian/Ubuntu.
-mkdir -p "$DESTDIR/etc/systemd/system-preset"
-echo "disable *" >"$DESTDIR/etc/systemd/system-preset/99-mkosi.preset"
-
 if [ -d mkosi.kernel/ ]; then
-        cd "$SRCDIR/mkosi.kernel"
-        mkdir -p "$BUILDDIR/mkosi.kernel"
-
-        # Ensure fast incremental builds by fixating these values which usually change for each build.
-        export KBUILD_BUILD_TIMESTAMP="Fri Jun  5 15:58:00 CEST 2015"
-        export KBUILD_BUILD_HOST="mkosi"
-
-        scripts/kconfig/merge_config.sh -O "$BUILDDIR/mkosi.kernel" \
-                ../mkosi.kernel.config \
-                tools/testing/selftests/bpf/config.x86_64 \
-                tools/testing/selftests/bpf/config
-
-        make O="$BUILDDIR/mkosi.kernel" -j "$(nproc)"
-
-        KERNEL_RELEASE=$(make O="$BUILDDIR"/mkosi.kernel -s kernelrelease)
-        mkdir -p "$DESTDIR/usr/lib/modules/$KERNEL_RELEASE"
-        make O="$BUILDDIR/mkosi.kernel" INSTALL_MOD_PATH="$DESTDIR/usr" modules_install
-        make O="$BUILDDIR/mkosi.kernel" INSTALL_PATH="$DESTDIR/usr/lib/modules/$KERNEL_RELEASE" install
-        mkdir -p "$DESTDIR/usr/lib/kernel/selftests"
-        make -C tools/testing/selftests -j "$(nproc)" O="$BUILDDIR/mkosi.kernel" KSFT_INSTALL_PATH="$DESTDIR/usr/lib/kernel/selftests" SKIP_TARGETS="" install
-
-        ln -sf /usr/lib/kernel/selftests/bpf/bpftool "$DESTDIR/usr/bin/bpftool"
+    SRCDIR="$SRCDIR/mkosi.kernel"
+    BUILDDIR="$BUILDDIR/mkosi.kernel"
+    cd "$SRCDIR"
+    mkdir -p "$BUILDDIR"
+
+    # Ensure fast incremental builds by fixating these values which usually change for each build.
+    export KBUILD_BUILD_TIMESTAMP="Fri Jun  5 15:58:00 CEST 2015"
+    export KBUILD_BUILD_HOST="mkosi"
+
+    scripts/kconfig/merge_config.sh -O "$BUILDDIR" \
+            ../mkosi.kernel.config \
+            tools/testing/selftests/bpf/config.x86_64 \
+            tools/testing/selftests/bpf/config
+
+    make O="$BUILDDIR" -j "$(nproc)"
+
+    KERNEL_RELEASE=$(make O="$BUILDDIR" -s kernelrelease)
+    mkdir -p "$DESTDIR/usr/lib/modules/$KERNEL_RELEASE"
+    make O="$BUILDDIR" INSTALL_MOD_PATH="$DESTDIR/usr" modules_install
+    make O="$BUILDDIR" INSTALL_PATH="$DESTDIR/usr/lib/modules/$KERNEL_RELEASE" install
+    mkdir -p "$DESTDIR/usr/lib/kernel/selftests"
+    make -C tools/testing/selftests -j "$(nproc)" O="$BUILDDIR" KSFT_INSTALL_PATH="$DESTDIR/usr/lib/kernel/selftests" SKIP_TARGETS="" install
+
+    ln -sf /usr/lib/kernel/selftests/bpf/bpftool "$DESTDIR/usr/bin/bpftool"
 fi
index 57db7ecda900f17d4d98041608db15a099b044b9..0eeee89052a105d1403eb6d5fbb1777618cc0bec 100644 (file)
@@ -4,8 +4,10 @@
 
 [Output]
 Bootable=yes
-# Prevent ASAN warnings when building the image
+# Prevent ASAN warnings when building the image and ship the real ASAN options prefixed with MKOSI_.
 Environment=ASAN_OPTIONS=verify_asan_link_order=false
+            MKOSI_ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:disable_coredump=0:use_madv_dontdump=1
+            MKOSI_UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1
 OutputDirectory=mkosi.output
 
 [Content]
diff --git a/mkosi.extra/etc/issue b/mkosi.extra/etc/issue
new file mode 100644 (file)
index 0000000..6aa6fc0
--- /dev/null
@@ -0,0 +1,2 @@
+\S (built from systemd tree)
+Kernel \r on an \m (\l)
diff --git a/mkosi.extra/root/.gdbinit b/mkosi.extra/root/.gdbinit
new file mode 100644 (file)
index 0000000..522e1fe
--- /dev/null
@@ -0,0 +1,2 @@
+set debuginfod enabled off
+set build-id-verbose 0
index cebbf29250dc826e82d336472ea0759664895382..43cc818393a245ac592e335f5920a14fb2ef6ea1 100755 (executable)
@@ -1,34 +1,67 @@
 #!/bin/sh
 # SPDX-License-Identifier: LGPL-2.1-or-later
 
-if [ "$1" = "final" ]; then
-    if command -v bootctl >/dev/null && [ -d "/efi" ]; then
-        bootctl install
-    fi
-
-    cat >>/root/.gdbinit <<EOF
-set debuginfod enabled off
-set build-id-verbose 0
+if [ "$1" = "build" ]; then
+    exit 0
+fi
+
+if [ -n "$SANITIZERS" ]; then
+    LD_PRELOAD=$(ldd /usr/lib/systemd/systemd | grep libasan.so | awk '{print $3}')
+
+    mkdir -p /etc/systemd/system.conf.d
+
+    cat >/etc/systemd/system.conf.d/10-asan.conf <<EOF
+[Manager]
+ManagerEnvironment=ASAN_OPTIONS=$MKOSI_ASAN_OPTIONS\\
+                   UBSAN_OPTIONS=$MKOSI_UBSAN_OPTIONS\\
+                   LD_PRELOAD=$LD_PRELOAD
+DefaultEnvironment=ASAN_OPTIONS=$MKOSI_ASAN_OPTIONS\\
+                   UBSAN_OPTIONS=$MKOSI_UBSAN_OPTIONS\\
+                   LD_PRELOAD=$LD_PRELOAD
+EOF
+
+    # ASAN logs to stderr by default. However, journald's stderr is connected to /dev/null, so we lose
+    # all the ASAN logs. To rectify that, let's connect journald's stdout to the console so that any
+    # sanitizer failures appear directly on the user's console.
+    mkdir -p /etc/systemd/system/systemd-journald.service.d
+    cat >/etc/systemd/system/systemd-journald.service.d/10-stdout-tty.conf <<EOF
+[Service]
+StandardOutput=tty
 EOF
 
-    if [ -n "$SANITIZERS" ]; then
-        # ASAN and syscall filters aren't compatible with each other.
-        find / -name '*.service' -type f -exec sed -i 's/^\(MemoryDeny\|SystemCall\)/# \1/' {} +
+    # Both systemd and util-linux's login call vhangup() on /dev/console which disconnects all users.
+    # This means systemd-journald can't log to /dev/console even if we configure `StandardOutput=tty`. As
+    # a workaround, we modify console-getty.service to disable systemd's vhangup() and disallow login
+    # from calling vhangup() so that journald's ASAN logs correctly end up in the console.
+
+    mkdir -p /etc/systemd/system/console-getty.service.d
+    cat >/etc/systemd/system/console-getty.service.d/10-no-vhangup.conf <<EOF
+[Service]
+TTYVHangup=no
+CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG
+EOF
+    # ASAN and syscall filters aren't compatible with each other.
+    find / -name '*.service' -type f -exec sed -i 's/^\(MemoryDeny\|SystemCall\)/# \1/' {} +
+
+    # `systemd-hwdb update` takes > 50s when built with sanitizers so let's not run it by default.
+    systemctl mask systemd-hwdb-update.service
+fi
 
-        # `systemd-hwdb update` takes > 50s when built with sanitizers so let's not run it by default.
-        systemctl mask systemd-hwdb-update.service
-    fi
+# Make sure dnsmasq.service doesn't start on boot on Debian/Ubuntu.
+rm -f /etc/systemd/system/multi-user.target.wants/dnsmasq.service
 
-    # Make sure dnsmasq.service doesn't start on boot on Debian/Ubuntu.
-    rm -f /etc/systemd/system/multi-user.target.wants/dnsmasq.service
+if [ -n "$IMAGE_ID" ] ; then
+    sed -n \
+        -i \
+        -e '/^IMAGE_ID=/!p' \
+        -e "\$aIMAGE_ID=$IMAGE_ID" \
+        /usr/lib/os-release
 fi
 
-# Temporary workaround until https://github.com/openSUSE/suse-module-tools/commit/158643414ddb8d8208016a5f03a4484d58944d7a
-# gets into OpenSUSE repos
-if [ "$1" = "final" ] && grep -q openSUSE /etc/os-release; then
-    if [ -e "/usr/lib/systemd/system/boot-sysctl.service" ] && \
-       ! grep -F -q 'ConditionPathExists=/boot/sysctl.conf' "/usr/lib/systemd/system/boot-sysctl.service"; then
-        mkdir -p "/etc/systemd/system/boot-sysctl.service.d/"
-        printf '[Unit]\nConditionPathExists=/boot/sysctl.conf-%%v' >"/etc/systemd/system/boot-sysctl.service.d/99-temporary-workaround.conf"
-    fi
+if [ -n "$IMAGE_VERSION" ] ; then
+    sed -n \
+        -i \
+        -e '/^IMAGE_VERSION=/!p' \
+        -e "\$aIMAGE_VERSION=$IMAGE_VERSION" \
+        /usr/lib/os-release
 fi
index dba667b2b30076f6d50ae5a4dfa0f8d9b1c21259..d4d0c5ac4f95cdeeafd16096d3b135e76510dea2 100644 (file)
--- a/po/lt.po
+++ b/po/lt.po
@@ -1,20 +1,22 @@
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
 # Moo, 2018. #zanata
+# mooo <hazap@hotmail.com>, 2023.
 msgid ""
 msgstr ""
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2022-10-20 10:35+0200\n"
-"PO-Revision-Date: 2019-04-08 22:01+0300\n"
-"Last-Translator: Moo\n"
-"Language-Team: Lithuanian\n"
+"PO-Revision-Date: 2023-02-21 23:20+0000\n"
+"Last-Translator: mooo <hazap@hotmail.com>\n"
+"Language-Team: Lithuanian <https://translate.fedoraproject.org/projects/"
+"systemd/master/lt/>\n"
 "Language: lt\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 2.2.1\n"
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n"
-"%100<10 || n%100>=20) ? 1 : 2);\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && ("
+"n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Generator: Weblate 4.15.2\n"
 
 #: src/core/org.freedesktop.systemd1.policy.in:22
 msgid "Send passphrase back to system"
@@ -176,14 +178,12 @@ msgid "Authentication is required to get hardware serial number."
 msgstr "Norint nustatyti sistemos laikÄ…, reikia nustatyti tapatybÄ™."
 
 #: src/hostname/org.freedesktop.hostname1.policy:71
-#, fuzzy
 msgid "Get system description"
-msgstr "Nustatyti sistemos laiko juostÄ…"
+msgstr "Gauti sistemos apraÅ¡Ä…"
 
 #: src/hostname/org.freedesktop.hostname1.policy:72
-#, fuzzy
 msgid "Authentication is required to get system description."
-msgstr "Norint nustatyti sistemos laiko juostÄ…, reikia nustatyti tapatybÄ™."
+msgstr "Norint gauti sistemos apraÅ¡Ä…, reikia nustatyti tapatybÄ™."
 
 #: src/import/org.freedesktop.import1.policy:22
 msgid "Import a VM or container image"
@@ -617,7 +617,7 @@ msgstr "Norint nustatyti sienos praneÅ¡imÄ…, reikia nustatyti tapatybÄ™"
 
 #: src/login/org.freedesktop.login1.policy:406
 msgid "Change Session"
-msgstr ""
+msgstr "Keisti seansÄ…"
 
 #: src/login/org.freedesktop.login1.policy:407
 #, fuzzy
@@ -712,15 +712,13 @@ msgstr "Norint nustatyti sistemos laikÄ…, reikia nustatyti tapatybÄ™."
 
 #: src/network/org.freedesktop.network1.policy:33
 #: src/resolve/org.freedesktop.resolve1.policy:44
-#, fuzzy
 msgid "Set DNS servers"
-msgstr "Registruoti DNS-SD tarnybÄ…"
+msgstr "Nustatyti DNS serverius"
 
 #: src/network/org.freedesktop.network1.policy:34
 #: src/resolve/org.freedesktop.resolve1.policy:45
-#, fuzzy
 msgid "Authentication is required to set DNS servers."
-msgstr "Norint registruoti DNS-SD tarnybÄ…, reikia nustatyti tapatybÄ™"
+msgstr "Norint nustatyti DNS serverius, reikia nustatyti tapatybÄ™."
 
 #: src/network/org.freedesktop.network1.policy:44
 #: src/resolve/org.freedesktop.resolve1.policy:55
@@ -736,25 +734,22 @@ msgstr "Norint stabdyti \"$(unit)\", reikia nustatyti tapatybÄ™."
 #: src/network/org.freedesktop.network1.policy:55
 #: src/resolve/org.freedesktop.resolve1.policy:66
 msgid "Set default route"
-msgstr ""
+msgstr "Nustatyti numatytÄ…jį marÅ¡rutÄ…"
 
 #: src/network/org.freedesktop.network1.policy:56
 #: src/resolve/org.freedesktop.resolve1.policy:67
-#, fuzzy
 msgid "Authentication is required to set default route."
-msgstr ""
-"Norint nustatyti vietinio serverio pavadinimÄ…, reikia nustatyti tapatybÄ™."
+msgstr "Norint nustatyti numatytÄ…jį marÅ¡rutÄ…, reikia nustatyti tapatybÄ™."
 
 #: src/network/org.freedesktop.network1.policy:66
 #: src/resolve/org.freedesktop.resolve1.policy:77
 msgid "Enable/disable LLMNR"
-msgstr ""
+msgstr "Ä®jungti/iÅ¡jungti LLMNR"
 
 #: src/network/org.freedesktop.network1.policy:67
 #: src/resolve/org.freedesktop.resolve1.policy:78
-#, fuzzy
 msgid "Authentication is required to enable or disable LLMNR."
-msgstr "Norint užmigdyti sistemÄ…, reikia nustatyti tapatybÄ™."
+msgstr "Norint Ä¯jungti ar iÅ¡jungti LLMNR, reikia nustatyti tapatybÄ™."
 
 #: src/network/org.freedesktop.network1.policy:77
 #: src/resolve/org.freedesktop.resolve1.policy:88
@@ -770,24 +765,22 @@ msgstr "Norint gauti produkto UUID, reikia nustatyti tapatybÄ™."
 #: src/network/org.freedesktop.network1.policy:88
 #: src/resolve/org.freedesktop.resolve1.policy:99
 msgid "Enable/disable DNS over TLS"
-msgstr ""
+msgstr "Ä®jungti/iÅ¡jungti DNS per TLS"
 
 #: src/network/org.freedesktop.network1.policy:89
 #: src/resolve/org.freedesktop.resolve1.policy:100
-#, fuzzy
 msgid "Authentication is required to enable or disable DNS over TLS."
-msgstr "Norint registruoti DNS-SD tarnybÄ…, reikia nustatyti tapatybÄ™"
+msgstr "Norint Ä¯jungti ar iÅ¡jungti DNS per TLS, reikia nustatyti tapatybÄ™."
 
 #: src/network/org.freedesktop.network1.policy:99
 #: src/resolve/org.freedesktop.resolve1.policy:110
 msgid "Enable/disable DNSSEC"
-msgstr ""
+msgstr "Ä®jungti/iÅ¡jungti DNSSEC"
 
 #: src/network/org.freedesktop.network1.policy:100
 #: src/resolve/org.freedesktop.resolve1.policy:111
-#, fuzzy
 msgid "Authentication is required to enable or disable DNSSEC."
-msgstr "Norint užmigdyti sistemÄ…, reikia nustatyti tapatybÄ™."
+msgstr "Norint Ä¯jungti ar iÅ¡jungti DNSSEC, reikia nustatyti tapatybÄ™."
 
 #: src/network/org.freedesktop.network1.policy:110
 #: src/resolve/org.freedesktop.resolve1.policy:121
index 3c64467e2fc45f44b5dd630e7aa2d032273d6eec..0e411f5a5fa8dd84934205a3de44aaedf768a178 100644 (file)
@@ -216,7 +216,7 @@ _systemctl () {
                              suspend-then-hibernate kexec list-jobs list-sockets
                              list-timers list-units list-unit-files poweroff
                              reboot rescue show-environment suspend get-default
-                             is-system-running preset-all list-automounts'
+                             is-system-running preset-all list-automounts list-paths'
         [FILE]='link switch-root bind mount-image'
         [TARGETS]='set-default'
         [MACHINES]='list-machines'
index 2811582236dd69fb976c921eccf8d213369d66b4..9df9e571a1b765921da99d2af7da6c08204cd417 100644 (file)
@@ -8,6 +8,7 @@
     local -a unit_commands=(
         # Unit Commands
         "list-automounts:List automounts"
+        "list-paths:List paths"
         "list-sockets:List sockets"
         "list-timers:List timers"
         "list-units:List units"
index 4df369dd2a153a7f4fcce87d8df66846374a8053..919387f958030053056c59668691c3562221b08c 100644 (file)
@@ -1134,6 +1134,7 @@ static void restore_sigsetp(sigset_t **ssp) {
 
 int safe_fork_full(
                 const char *name,
+                const int stdio_fds[3],
                 const int except_fds[],
                 size_t n_except_fds,
                 ForkFlags flags,
@@ -1292,6 +1293,27 @@ int safe_fork_full(
                 }
         }
 
+        if (flags & FORK_REARRANGE_STDIO) {
+                if (stdio_fds) {
+                        r = rearrange_stdio(stdio_fds[0], stdio_fds[1], stdio_fds[2]);
+                        if (r < 0) {
+                                log_full_errno(prio, r, "Failed to rearrange stdio fds: %m");
+                                _exit(EXIT_FAILURE);
+                        }
+                } else {
+                        r = make_null_stdio();
+                        if (r < 0) {
+                                log_full_errno(prio, r, "Failed to connect stdin/stdout to /dev/null: %m");
+                                _exit(EXIT_FAILURE);
+                        }
+                }
+        } else if (flags & FORK_STDOUT_TO_STDERR) {
+                if (dup2(STDERR_FILENO, STDOUT_FILENO) < 0) {
+                        log_full_errno(prio, errno, "Failed to connect stdout to stderr: %m");
+                        _exit(EXIT_FAILURE);
+                }
+        }
+
         if (flags & FORK_CLOSE_ALL_FDS) {
                 /* Close the logs here in case it got reopened above, as close_all_fds() would close them for us */
                 log_close();
@@ -1317,20 +1339,6 @@ int safe_fork_full(
                 log_set_open_when_needed(false);
         }
 
-        if (flags & FORK_NULL_STDIO) {
-                r = make_null_stdio();
-                if (r < 0) {
-                        log_full_errno(prio, r, "Failed to connect stdin/stdout to /dev/null: %m");
-                        _exit(EXIT_FAILURE);
-                }
-
-        } else if (flags & FORK_STDOUT_TO_STDERR) {
-                if (dup2(STDERR_FILENO, STDOUT_FILENO) < 0) {
-                        log_full_errno(prio, errno, "Failed to connect stdout to stderr: %m");
-                        _exit(EXIT_FAILURE);
-                }
-        }
-
         if (flags & FORK_RLIMIT_NOFILE_SAFE) {
                 r = rlimit_nofile_safe();
                 if (r < 0) {
@@ -1364,7 +1372,10 @@ int namespace_fork(
          * process. This ensures that we are fully a member of the destination namespace, with pidns an all, so that
          * /proc/self/fd works correctly. */
 
-        r = safe_fork_full(outer_name, except_fds, n_except_fds, (flags|FORK_DEATHSIG) & ~(FORK_REOPEN_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE), ret_pid);
+        r = safe_fork_full(outer_name,
+                           NULL,
+                           except_fds, n_except_fds,
+                           (flags|FORK_DEATHSIG) & ~(FORK_REOPEN_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE), ret_pid);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -1379,7 +1390,10 @@ int namespace_fork(
                 }
 
                 /* We mask a few flags here that either make no sense for the grandchild, or that we don't have to do again */
-                r = safe_fork_full(inner_name, except_fds, n_except_fds, flags & ~(FORK_WAIT|FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_NULL_STDIO), &pid);
+                r = safe_fork_full(inner_name,
+                                   NULL,
+                                   except_fds, n_except_fds,
+                                   flags & ~(FORK_WAIT|FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REARRANGE_STDIO), &pid);
                 if (r < 0)
                         _exit(EXIT_FAILURE);
                 if (r == 0) {
index 279f5d6e6b70a290311b79aa1c665b41408ab70a..6f6fc7d94e7111f0a39b1630daacd44c16075703 100644 (file)
@@ -143,7 +143,7 @@ typedef enum ForkFlags {
         FORK_CLOSE_ALL_FDS      = 1 <<  1, /* Close all open file descriptors in the child, except for 0,1,2 */
         FORK_DEATHSIG           = 1 <<  2, /* Set PR_DEATHSIG in the child to SIGTERM */
         FORK_DEATHSIG_SIGINT    = 1 <<  3, /* Set PR_DEATHSIG in the child to SIGINT */
-        FORK_NULL_STDIO         = 1 <<  4, /* Connect 0,1,2 to /dev/null */
+        FORK_REARRANGE_STDIO    = 1 <<  4, /* Connect 0,1,2 to specified fds or /dev/null */
         FORK_REOPEN_LOG         = 1 <<  5, /* Reopen log connection */
         FORK_LOG                = 1 <<  6, /* Log above LOG_DEBUG log level about failures */
         FORK_WAIT               = 1 <<  7, /* Wait until child exited */
@@ -157,10 +157,16 @@ typedef enum ForkFlags {
         FORK_CLOEXEC_OFF        = 1 << 15, /* In the child: turn off O_CLOEXEC on all fds in except_fds[] */
 } ForkFlags;
 
-int safe_fork_full(const char *name, const int except_fds[], size_t n_except_fds, ForkFlags flags, pid_t *ret_pid);
+int safe_fork_full(
+                const char *name,
+                const int stdio_fds[3],
+                const int except_fds[],
+                size_t n_except_fds,
+                ForkFlags flags,
+                pid_t *ret_pid);
 
 static inline int safe_fork(const char *name, ForkFlags flags, pid_t *ret_pid) {
-        return safe_fork_full(name, NULL, 0, flags, ret_pid);
+        return safe_fork_full(name, NULL, NULL, 0, flags, ret_pid);
 }
 
 int namespace_fork(const char *outer_name, const char *inner_name, const int except_fds[], size_t n_except_fds, ForkFlags flags, int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd, pid_t *ret_pid);
index 53794d1b7a1851a73f17a6f9f1e3ade5211f6904..d8de09cab5470b2b7cd561e0d7688637c23b018c 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <getopt.h>
 
+#include "blockdev-util.h"
 #include "bootctl.h"
 #include "bootctl-install.h"
 #include "bootctl-random-seed.h"
@@ -11,6 +12,7 @@
 #include "bootctl-systemd-efi-options.h"
 #include "bootctl-uki.h"
 #include "build.h"
+#include "devnum-util.h"
 #include "dissect-image.h"
 #include "escape.h"
 #include "find-esp.h"
@@ -33,6 +35,7 @@ char *arg_esp_path = NULL;
 char *arg_xbootldr_path = NULL;
 bool arg_print_esp_path = false;
 bool arg_print_dollar_boot_path = false;
+unsigned arg_print_root_device = 0;
 bool arg_touch_variables = true;
 PagerFlags arg_pager_flags = 0;
 bool arg_graceful = false;
@@ -167,8 +170,10 @@ static int help(int argc, char *argv[], void *userdata) {
                "     --image=PATH      Operate on disk image as filesystem root\n"
                "     --install-source=auto|image|host\n"
                "                       Where to pick files when using --root=/--image=\n"
-               "  -p --print-esp-path  Print path to the EFI System Partition\n"
-               "  -x --print-boot-path Print path to the $BOOT partition\n"
+               "  -p --print-esp-path  Print path to the EFI System Partition mount point\n"
+               "  -x --print-boot-path Print path to the $BOOT partition mount point\n"
+               "  -R --print-root-device\n"
+               "                       Print path to the root device node\n"
                "     --no-variables    Don't touch EFI variables\n"
                "     --no-pager        Do not pipe output into a pager\n"
                "     --graceful        Don't fail when the ESP cannot be found or EFI\n"
@@ -227,6 +232,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "print-esp-path",              no_argument,       NULL, 'p'                             },
                 { "print-path",                  no_argument,       NULL, 'p'                             }, /* Compatibility alias */
                 { "print-boot-path",             no_argument,       NULL, 'x'                             },
+                { "print-root-device",           no_argument,       NULL, 'R'                             },
                 { "no-variables",                no_argument,       NULL, ARG_NO_VARIABLES                },
                 { "no-pager",                    no_argument,       NULL, ARG_NO_PAGER                    },
                 { "graceful",                    no_argument,       NULL, ARG_GRACEFUL                    },
@@ -247,7 +253,7 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "hpx", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "hpxR", options, NULL)) >= 0)
                 switch (c) {
 
                 case 'h':
@@ -295,19 +301,17 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 'p':
-                        if (arg_print_dollar_boot_path)
-                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                                       "--print-boot-path/-x cannot be combined with --print-esp-path/-p");
                         arg_print_esp_path = true;
                         break;
 
                 case 'x':
-                        if (arg_print_esp_path)
-                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                                       "--print-boot-path/-x cannot be combined with --print-esp-path/-p");
                         arg_print_dollar_boot_path = true;
                         break;
 
+                case 'R':
+                        arg_print_root_device ++;
+                        break;
+
                 case ARG_NO_VARIABLES:
                         arg_touch_variables = false;
                         break;
@@ -398,6 +402,10 @@ static int parse_argv(int argc, char *argv[]) {
                         assert_not_reached();
                 }
 
+        if (!!arg_print_esp_path + !!arg_print_dollar_boot_path + (arg_print_root_device > 0) > 1)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                                       "--print-esp-path/-p, --print-boot-path/-x, --print-root-device=/-R cannot be combined.");
+
         if ((arg_root || arg_image) && argv[optind] && !STR_IN_SET(argv[optind], "status", "list",
                         "install", "update", "remove", "is-installed", "random-seed", "unlink", "cleanup"))
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
@@ -458,6 +466,32 @@ static int run(int argc, char *argv[]) {
         if (r <= 0)
                 return r;
 
+        if (arg_print_root_device > 0) {
+                _cleanup_free_ char *path = NULL;
+                dev_t devno;
+
+                r = blockdev_get_root(LOG_ERR, &devno);
+                if (r < 0)
+                        return r;
+                if (r == 0) {
+                        log_error("Root file system not backed by a (single) whole block device.");
+                        return 80; /* some recognizable error code */
+                }
+
+                if (arg_print_root_device > 1) {
+                        r = block_get_whole_disk(devno, &devno);
+                        if (r < 0)
+                                log_debug_errno(r, "Unable to find whole block device for root block device, ignoring: %m");
+                }
+
+                r = device_path_make_canonical(S_IFBLK, devno, &path);
+                if (r < 0)
+                        return log_oom();
+
+                puts(path);
+                return EXIT_SUCCESS;
+        }
+
         /* Open up and mount the image */
         if (arg_image) {
                 assert(!arg_root);
index 311b954c2c8b3fdec90e1589c2e1bf591b03eb16..9012bf932bbde6bb6295b6dcb96986127f86478c 100644 (file)
@@ -24,6 +24,7 @@ extern char *arg_esp_path;
 extern char *arg_xbootldr_path;
 extern bool arg_print_esp_path;
 extern bool arg_print_dollar_boot_path;
+extern unsigned arg_print_root_device;
 extern bool arg_touch_variables;
 extern PagerFlags arg_pager_flags;
 extern bool arg_graceful;
index c27af55c1e3f802decded850d38ccd5eb52e2dd7..bb12d891aef4ff0da7fae4c3365149b1241322c0 100644 (file)
@@ -1,7 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <stdint.h>
-#include <uchar.h>
+#include "efi.h"
 
 char16_t *get_bcd_title(uint8_t *bcd, size_t bcd_len);
index 6d4da0c51c624e910165a38c529d93774b585c74..ea19dd82d2c79e038a0308645ed839fd7d9f7df1 100644 (file)
@@ -1,10 +1,5 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <efi.h>
-#include <efigpt.h>
-#include <efilib.h>
-#include <inttypes.h>
-
 #include "bcd.h"
 #include "bootspec-fundamental.h"
 #include "console.h"
 #include "measure.h"
 #include "part-discovery.h"
 #include "pe.h"
-#include "vmm.h"
+#include "proto/block-io.h"
+#include "proto/device-path.h"
+#include "proto/simple-text-io.h"
 #include "random-seed.h"
 #include "secure-boot.h"
 #include "shim.h"
 #include "ticks.h"
 #include "util.h"
+#include "vmm.h"
 
 #ifndef GNU_EFI_USE_MS_ABI
         /* We do not use uefi_call_wrapper() in systemd-boot. As such, we rely on the
@@ -32,8 +30,6 @@
         #error systemd-boot requires compilation with GNU_EFI_USE_MS_ABI defined.
 #endif
 
-#define TEXT_ATTR_SWAP(c) EFI_TEXT_ATTR(((c) & 0b11110000) >> 4, (c) & 0b1111)
-
 /* Magic string for recognizing our own binaries */
 _used_ _section_(".sdmagic") static const char magic[] =
         "#### LoaderInfo: systemd-boot " GIT_VERSION " ####";
@@ -152,7 +148,7 @@ static bool line_edit(char16_t **line_in, size_t x_max, size_t y_pos) {
         for (;;) {
                 EFI_STATUS err;
                 uint64_t key;
-                size_t j, cursor_color = TEXT_ATTR_SWAP(COLOR_EDIT);
+                size_t j, cursor_color = EFI_TEXT_ATTR_SWAP(COLOR_EDIT);
 
                 j = MIN(len - first, x_max);
                 memcpy(print, line + first, j * sizeof(char16_t));
@@ -170,7 +166,7 @@ static bool line_edit(char16_t **line_in, size_t x_max, size_t y_pos) {
                 print[cursor+1] = '\0';
                 do {
                         print_at(cursor + 1, y_pos, cursor_color, print + cursor);
-                        cursor_color = TEXT_ATTR_SWAP(cursor_color);
+                        cursor_color = EFI_TEXT_ATTR_SWAP(cursor_color);
 
                         err = console_key_read(&key, 750 * 1000);
                         if (!IN_SET(err, EFI_SUCCESS, EFI_TIMEOUT, EFI_NOT_READY))
@@ -264,7 +260,7 @@ static bool line_edit(char16_t **line_in, size_t x_max, size_t y_pos) {
 
                 case KEYPRESS(EFI_CONTROL_PRESSED, 0, 'w'):
                 case KEYPRESS(EFI_CONTROL_PRESSED, 0, CHAR_CTRL('w')):
-                case KEYPRESS(EFI_ALT_PRESSED, 0, CHAR_BACKSPACE):
+                case KEYPRESS(EFI_ALT_PRESSED, 0, '\b'):
                         /* backward-kill-word */
                         clear = 0;
                         if ((first + cursor) > 0 && line[first + cursor-1] == ' ') {
@@ -307,17 +303,17 @@ static bool line_edit(char16_t **line_in, size_t x_max, size_t y_pos) {
                         len = first + cursor;
                         continue;
 
-                case KEYPRESS(0, 0, CHAR_LINEFEED):
-                case KEYPRESS(0, 0, CHAR_CARRIAGE_RETURN):
+                case KEYPRESS(0, 0, '\n'):
+                case KEYPRESS(0, 0, '\r'):
                 case KEYPRESS(0, SCAN_F3, 0): /* EZpad Mini 4s firmware sends malformed events */
-                case KEYPRESS(0, SCAN_F3, CHAR_CARRIAGE_RETURN): /* Teclast X98+ II firmware sends malformed events */
+                case KEYPRESS(0, SCAN_F3, '\r'): /* Teclast X98+ II firmware sends malformed events */
                         if (!streq16(line, *line_in)) {
                                 free(*line_in);
                                 *line_in = TAKE_PTR(line);
                         }
                         return true;
 
-                case KEYPRESS(0, 0, CHAR_BACKSPACE):
+                case KEYPRESS(0, 0, '\b'):
                         if (len == 0)
                                 continue;
                         if (first == 0 && cursor == 0)
@@ -828,7 +824,7 @@ static bool menu_run(
 
                 if (firmware_setup) {
                         firmware_setup = false;
-                        if (key == KEYPRESS(0, 0, CHAR_CARRIAGE_RETURN))
+                        if (IN_SET(key, KEYPRESS(0, 0, '\r'), KEYPRESS(0, 0, '\n')))
                                 reboot_into_firmware();
                         continue;
                 }
@@ -877,10 +873,10 @@ static bool menu_run(
                                 idx_highlight = config->entry_count-1;
                         break;
 
-                case KEYPRESS(0, 0, CHAR_LINEFEED):
-                case KEYPRESS(0, 0, CHAR_CARRIAGE_RETURN):
+                case KEYPRESS(0, 0, '\n'):
+                case KEYPRESS(0, 0, '\r'):
                 case KEYPRESS(0, SCAN_F3, 0): /* EZpad Mini 4s firmware sends malformed events */
-                case KEYPRESS(0, SCAN_F3, CHAR_CARRIAGE_RETURN): /* Teclast X98+ II firmware sends malformed events */
+                case KEYPRESS(0, SCAN_F3, '\r'): /* Teclast X98+ II firmware sends malformed events */
                 case KEYPRESS(0, SCAN_RIGHT, 0):
                         exit = true;
                         break;
@@ -1377,7 +1373,7 @@ static void config_entry_bump_counters(ConfigEntry *entry, EFI_FILE *root_dir) {
         if (err != EFI_SUCCESS)
                 return;
 
-        err = get_file_info_harder(handle, &file_info, &file_info_size);
+        err = get_file_info(handle, &file_info, &file_info_size);
         if (err != EFI_SUCCESS)
                 return;
 
@@ -1650,7 +1646,7 @@ static void config_load_entries(
         for (;;) {
                 _cleanup_free_ char *content = NULL;
 
-                err = readdir_harder(entries_dir, &f, &f_size);
+                err = readdir(entries_dir, &f, &f_size);
                 if (err != EFI_SUCCESS || !f)
                         break;
 
@@ -2119,7 +2115,7 @@ static void config_entry_add_unified(
                 size_t offs[_SECTION_MAX] = {}, szs[_SECTION_MAX] = {}, pos = 0;
                 char *line, *key, *value;
 
-                err = readdir_harder(linux_dir, &f, &f_size);
+                err = readdir(linux_dir, &f, &f_size);
                 if (err != EFI_SUCCESS || !f)
                         break;
 
@@ -2302,7 +2298,7 @@ static EFI_STATUS initrd_prepare(
                         return err;
 
                 _cleanup_free_ EFI_FILE_INFO *info = NULL;
-                err = get_file_info_harder(handle, &info, NULL);
+                err = get_file_info(handle, &info, NULL);
                 if (err != EFI_SUCCESS)
                         return err;
 
@@ -2495,7 +2491,7 @@ static EFI_STATUS secure_boot_discover_keys(Config *config, EFI_FILE *root_dir)
                 size_t dirent_size = 0;
                 ConfigEntry *entry = NULL;
 
-                err = readdir_harder(keys_basedir, &dirent, &dirent_size);
+                err = readdir(keys_basedir, &dirent, &dirent_size);
                 if (err != EFI_SUCCESS || !dirent)
                         return err;
 
index 343d96569289a3b9e9519f77ae86fd16df051d7f..41ad03cb4627f8f4409a503af697ce437894f70b 100644 (file)
@@ -1,9 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <efi.h>
-#include <efilib.h>
-
 #include "console.h"
+#include "proto/graphics-output.h"
 #include "util.h"
 
 #define SYSTEM_FONT_WIDTH 8
index 83c219bc734186d7c57e91b2c6f935b7fc5a6d35..c4d821a48131195d73487be1530ed4474dbdfb4a 100644 (file)
@@ -1,7 +1,8 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include "missing_efi.h"
+#include "efi.h"
+#include "proto/simple-text-io.h"
 
 enum {
         EFI_SHIFT_PRESSED   = EFI_RIGHT_SHIFT_PRESSED|EFI_LEFT_SHIFT_PRESSED,
index 1fd16a98d16412a705feda51432139acdfd0370e..2e971a91679d41b14e1b79f2452d695eef1e5a4f 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "cpio.h"
 #include "measure.h"
+#include "proto/device-path.h"
 #include "util.h"
 
 static char *write_cpio_word(char *p, uint32_t v) {
@@ -372,7 +373,7 @@ EFI_STATUS pack_cpio(
         for (;;) {
                 _cleanup_free_ char16_t *d = NULL;
 
-                err = readdir_harder(extra_dir, &dirent, &dirent_size);
+                err = readdir(extra_dir, &dirent, &dirent_size);
                 if (err != EFI_SUCCESS)
                         return log_error_status(err, "Failed to read extra directory of loaded image: %m");
                 if (!dirent) /* End of directory */
index afd689f61e6f617250fd9a18298b4592e8896668..26851e3c158c08f063977eda935b810fb5b43d17 100644 (file)
@@ -1,9 +1,8 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <efi.h>
-#include <stdbool.h>
-#include <uchar.h>
+#include "efi.h"
+#include "proto/loaded-image.h"
 
 EFI_STATUS pack_cpio(
                 EFI_LOADED_IMAGE_PROTOCOL *loaded_image,
index eef08985f17519dcbe4fc26b0e3f51a8d9abffa2..3916bca946f115132e4e04f2562a1b671f554143 100644 (file)
@@ -1,9 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <efi.h>
-
 #include "devicetree.h"
-#include "missing_efi.h"
+#include "proto/dt-fixup.h"
 #include "util.h"
 
 #define FDT_V1_SIZE (7*4)
@@ -81,7 +79,7 @@ EFI_STATUS devicetree_install(struct devicetree_state *state, EFI_FILE *root_dir
         if (err != EFI_SUCCESS)
                 return err;
 
-        err = get_file_info_harder(handle, &info, NULL);
+        err = get_file_info(handle, &info, NULL);
         if (err != EFI_SUCCESS)
                 return err;
         if (info->FileSize < FDT_V1_SIZE || info->FileSize > 32 * 1024 * 1024)
index 1a05c85d855c55ece85c77cfaf9503f8af1d1ddd..33eaa2256c46c1f05b1557b7f4905e6307dacf4a 100644 (file)
@@ -1,8 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <efi.h>
-#include <uchar.h>
+#include "efi.h"
 
 struct devicetree_state {
         EFI_PHYSICAL_ADDRESS addr;
index a7ad2dd0e2d3c86e440de482f81a4ca5f2bb8d46..44be3232eedaceccb5a02d85c50ef683d0680d75 100644 (file)
@@ -1,9 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <efi.h>
-#include <efilib.h>
-
 #include "disk.h"
+#include "proto/device-path.h"
 #include "util.h"
 
 EFI_STATUS disk_get_part_uuid(EFI_HANDLE *handle, char16_t uuid[static 37]) {
index 1a5a18733e7d4144643f908f2129468e260a4c30..2da5bca13338ff3af72d81f4f336142641165173 100644 (file)
@@ -1,7 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <efi.h>
-#include <uchar.h>
+#include "efi.h"
 
 EFI_STATUS disk_get_part_uuid(EFI_HANDLE *handle, char16_t uuid[static 37]);
index 7b4164513cdf652f1084417bd54f0ad408d98ad6..25bf6947236e12e32d47ced52801d765380ffc33 100644 (file)
@@ -1,8 +1,5 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <efi.h>
-#include <efilib.h>
-
 #include "drivers.h"
 #include "util.h"
 
@@ -90,7 +87,7 @@ EFI_STATUS load_drivers(
                 return log_error_status(err, "Failed to open \\EFI\\systemd\\drivers: %m");
 
         for (;;) {
-                err = readdir_harder(drivers_dir, &dirent, &dirent_size);
+                err = readdir(drivers_dir, &dirent, &dirent_size);
                 if (err != EFI_SUCCESS)
                         return log_error_status(err, "Failed to read extra directory of loaded image: %m");
                 if (!dirent) /* End of directory */
index 4ad526e83edc320251eaaa223234b4a8837ee718..ecd0b4ea568d500f829134f251eec36e86e5bbe3 100644 (file)
@@ -1,7 +1,8 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <efi.h>
+#include "efi.h"
+#include "proto/loaded-image.h"
 
 EFI_STATUS reconnect_all_drivers(void);
 EFI_STATUS load_drivers(
index 22923d60f62bf4541ed867c07a2f7d88a57650bc..ee3dc1c4a9540e73286e0f9fd801bad63b77fd5e 100644 (file)
@@ -1,13 +1,9 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <stdbool.h>
-#include <stdint.h>
-#include <wchar.h>
-
 #include "efi-string.h"
 
 #if SD_BOOT
-#  include "missing_efi.h"
+#  include "proto/simple-text-io.h"
 #  include "util.h"
 #else
 #  include <stdlib.h>
@@ -382,7 +378,6 @@ DEFINE_PARSE_NUMBER(char16_t, parse_number16);
 
 static const char * const warn_table[] = {
         [EFI_SUCCESS]               = "Success",
-#if SD_BOOT
         [EFI_WARN_UNKNOWN_GLYPH]    = "Unknown glyph",
         [EFI_WARN_DELETE_FAILURE]   = "Delete failure",
         [EFI_WARN_WRITE_FAILURE]    = "Write failure",
@@ -390,7 +385,6 @@ static const char * const warn_table[] = {
         [EFI_WARN_STALE_DATA]       = "Stale data",
         [EFI_WARN_FILE_SYSTEM]      = "File system",
         [EFI_WARN_RESET_REQUIRED]   = "Reset required",
-#endif
 };
 
 /* Errors have MSB set, remove it to keep the table compact. */
@@ -399,7 +393,6 @@ static const char * const warn_table[] = {
 static const char * const err_table[] = {
         [NOERR(EFI_ERROR_MASK)]           = "Error",
         [NOERR(EFI_LOAD_ERROR)]           = "Load error",
-#if SD_BOOT
         [NOERR(EFI_INVALID_PARAMETER)]    = "Invalid parameter",
         [NOERR(EFI_UNSUPPORTED)]          = "Unsupported",
         [NOERR(EFI_BAD_BUFFER_SIZE)]      = "Bad buffer size",
@@ -427,14 +420,13 @@ static const char * const err_table[] = {
         [NOERR(EFI_SECURITY_VIOLATION)]   = "Security violation",
         [NOERR(EFI_CRC_ERROR)]            = "CRC error",
         [NOERR(EFI_END_OF_MEDIA)]         = "End of media",
-        [29]                              = "Reserved (29)",
-        [30]                              = "Reserved (30)",
+        [NOERR(EFI_ERROR_RESERVED_29)]    = "Reserved (29)",
+        [NOERR(EFI_ERROR_RESERVED_30)]    = "Reserved (30)",
         [NOERR(EFI_END_OF_FILE)]          = "End of file",
         [NOERR(EFI_INVALID_LANGUAGE)]     = "Invalid language",
         [NOERR(EFI_COMPROMISED_DATA)]     = "Compromised data",
         [NOERR(EFI_IP_ADDRESS_CONFLICT)]  = "IP address conflict",
         [NOERR(EFI_HTTP_ERROR)]           = "HTTP error",
-#endif
 };
 
 static const char *status_to_string(EFI_STATUS status) {
index 2a28db3593c8ae11af3c05f498eb03158fdc35ac..6b6b0d57b4601b5fde6851aae04ff2e49b84c5be 100644 (file)
@@ -1,11 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <uchar.h>
-
+#include "efi.h"
 #include "macro-fundamental.h"
 
 size_t strnlen8(const char *s, size_t n);
@@ -110,17 +106,6 @@ bool efi_fnmatch(const char16_t *pattern, const char16_t *haystack);
 bool parse_number8(const char *s, uint64_t *ret_u, const char **ret_tail);
 bool parse_number16(const char16_t *s, uint64_t *ret_u, const char16_t **ret_tail);
 
-typedef size_t EFI_STATUS;
-
-#if !SD_BOOT
-/* Provide these for unit testing. */
-enum {
-        EFI_ERROR_MASK = ((EFI_STATUS) 1 << (sizeof(EFI_STATUS) * CHAR_BIT - 1)),
-        EFI_SUCCESS = 0,
-        EFI_LOAD_ERROR = 1 | EFI_ERROR_MASK,
-};
-#endif
-
 #ifdef __clang__
 #  define _gnu_printf_(a, b) _printf_(a, b)
 #else
@@ -136,6 +121,32 @@ _gnu_printf_(2, 0) _warn_unused_result_ char16_t *xvasprintf_status(EFI_STATUS s
 #  define printf(...) printf_status(EFI_SUCCESS, __VA_ARGS__)
 #  define xasprintf(...) xasprintf_status(EFI_SUCCESS, __VA_ARGS__)
 
+/* inttypes.h is provided by libc instead of the compiler and is not supposed to be used in freestanding
+ * environments. We could use clang __*_FMT*__ constants for this, bug gcc does not have them. :( */
+
+#  if defined(__ILP32__)
+#    define PRI64_PREFIX "ll"
+#  elif defined(__LP64__)
+#    define PRI64_PREFIX "l"
+#  elif defined(__LLP64__) || (__SIZEOF_LONG__ == 4 && __SIZEOF_POINTER__ == 8)
+#    define PRI64_PREFIX "ll"
+#  else
+#    error Unknown 64-bit data model
+#  endif
+
+#  define PRIi32 "i"
+#  define PRIu32 "u"
+#  define PRIx32 "x"
+#  define PRIX32 "X"
+#  define PRIiPTR "zi"
+#  define PRIuPTR "zu"
+#  define PRIxPTR "zx"
+#  define PRIXPTR "zX"
+#  define PRIi64 PRI64_PREFIX "i"
+#  define PRIu64 PRI64_PREFIX "u"
+#  define PRIx64 PRI64_PREFIX "x"
+#  define PRIX64 PRI64_PREFIX "X"
+
 /* The compiler normally has knowledge about standard functions such as memcmp, but this is not the case when
  * compiling with -ffreestanding. By referring to builtins, the compiler can check arguments and do
  * optimizations again. Note that we still need to provide implementations as the compiler is free to not
diff --git a/src/boot/efi/efi.h b/src/boot/efi/efi.h
new file mode 100644 (file)
index 0000000..4e51078
--- /dev/null
@@ -0,0 +1,446 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "macro-fundamental.h"
+
+#if SD_BOOT
+/* uchar.h/wchar.h are not suitable for freestanding environments. */
+typedef __WCHAR_TYPE__ wchar_t;
+typedef __CHAR16_TYPE__ char16_t;
+typedef __CHAR32_TYPE__ char32_t;
+
+/* Let's be paranoid and do some sanity checks. */
+assert_cc(__STDC_HOSTED__ == 0);
+assert_cc(sizeof(bool) == 1);
+assert_cc(sizeof(uint8_t) == 1);
+assert_cc(sizeof(uint16_t) == 2);
+assert_cc(sizeof(uint32_t) == 4);
+assert_cc(sizeof(uint64_t) == 8);
+assert_cc(sizeof(wchar_t) == 2);
+assert_cc(sizeof(char16_t) == 2);
+assert_cc(sizeof(char32_t) == 4);
+assert_cc(sizeof(size_t) == sizeof(void *));
+assert_cc(sizeof(size_t) == sizeof(uintptr_t));
+#else
+#  include <uchar.h>
+#  include <wchar.h>
+#endif
+
+/* We use size_t/ssize_t to represent UEFI UINTN/INTN. */
+typedef size_t EFI_STATUS;
+typedef intptr_t ssize_t;
+
+typedef void* EFI_HANDLE;
+typedef void* EFI_EVENT;
+typedef size_t EFI_TPL;
+typedef uint64_t EFI_LBA;
+typedef uint64_t EFI_PHYSICAL_ADDRESS;
+
+#if defined(__x86_64__)
+#  define EFIAPI __attribute__((ms_abi))
+#else
+#  define EFIAPI
+#endif
+
+#if __SIZEOF_POINTER__ == 8
+#  define EFI_ERROR_MASK 0x8000000000000000ULL
+#elif __SIZEOF_POINTER__ == 4
+#  define EFI_ERROR_MASK 0x80000000ULL
+#else
+#  error Unsupported pointer size
+#endif
+
+#define EFIWARN(s) ((EFI_STATUS) s)
+#define EFIERR(s) ((EFI_STATUS) (s | EFI_ERROR_MASK))
+
+#define EFI_SUCCESS               EFIWARN(0)
+#define EFI_WARN_UNKNOWN_GLYPH    EFIWARN(1)
+#define EFI_WARN_DELETE_FAILURE   EFIWARN(2)
+#define EFI_WARN_WRITE_FAILURE    EFIWARN(3)
+#define EFI_WARN_BUFFER_TOO_SMALL EFIWARN(4)
+#define EFI_WARN_STALE_DATA       EFIWARN(5)
+#define EFI_WARN_FILE_SYSTEM      EFIWARN(6)
+#define EFI_WARN_RESET_REQUIRED   EFIWARN(7)
+
+#define EFI_LOAD_ERROR           EFIERR(1)
+#define EFI_INVALID_PARAMETER    EFIERR(2)
+#define EFI_UNSUPPORTED          EFIERR(3)
+#define EFI_BAD_BUFFER_SIZE      EFIERR(4)
+#define EFI_BUFFER_TOO_SMALL     EFIERR(5)
+#define EFI_NOT_READY            EFIERR(6)
+#define EFI_DEVICE_ERROR         EFIERR(7)
+#define EFI_WRITE_PROTECTED      EFIERR(8)
+#define EFI_OUT_OF_RESOURCES     EFIERR(9)
+#define EFI_VOLUME_CORRUPTED     EFIERR(10)
+#define EFI_VOLUME_FULL          EFIERR(11)
+#define EFI_NO_MEDIA             EFIERR(12)
+#define EFI_MEDIA_CHANGED        EFIERR(13)
+#define EFI_NOT_FOUND            EFIERR(14)
+#define EFI_ACCESS_DENIED        EFIERR(15)
+#define EFI_NO_RESPONSE          EFIERR(16)
+#define EFI_NO_MAPPING           EFIERR(17)
+#define EFI_TIMEOUT              EFIERR(18)
+#define EFI_NOT_STARTED          EFIERR(19)
+#define EFI_ALREADY_STARTED      EFIERR(20)
+#define EFI_ABORTED              EFIERR(21)
+#define EFI_ICMP_ERROR           EFIERR(22)
+#define EFI_TFTP_ERROR           EFIERR(23)
+#define EFI_PROTOCOL_ERROR       EFIERR(24)
+#define EFI_INCOMPATIBLE_VERSION EFIERR(25)
+#define EFI_SECURITY_VIOLATION   EFIERR(26)
+#define EFI_CRC_ERROR            EFIERR(27)
+#define EFI_END_OF_MEDIA         EFIERR(28)
+#define EFI_ERROR_RESERVED_29    EFIERR(29)
+#define EFI_ERROR_RESERVED_30    EFIERR(30)
+#define EFI_END_OF_FILE          EFIERR(31)
+#define EFI_INVALID_LANGUAGE     EFIERR(32)
+#define EFI_COMPROMISED_DATA     EFIERR(33)
+#define EFI_IP_ADDRESS_CONFLICT  EFIERR(34)
+#define EFI_HTTP_ERROR           EFIERR(35)
+
+typedef struct {
+        uint32_t Data1;
+        uint16_t Data2;
+        uint16_t Data3;
+        uint8_t Data4[8];
+} EFI_GUID;
+
+#define GUID_DEF(d1, d2, d3, d4_1, d4_2, d4_3, d4_4, d4_5, d4_6, d4_7, d4_8) \
+    { d1, d2, d3, { d4_1, d4_2, d4_3, d4_4, d4_5, d4_6, d4_7, d4_8 } }
+
+/* Creates a EFI_GUID pointer suitable for EFI APIs. Use of const allows the compiler to merge multiple
+ * uses (although, currently compilers do that regardless). Most EFI APIs declare their EFI_GUID input
+ * as non-const, but almost all of them are in fact const. */
+#define MAKE_GUID_PTR(name) ((EFI_GUID *) &(const EFI_GUID) name##_GUID)
+
+/* These allow MAKE_GUID_PTR() to work without requiring an extra _GUID in the passed name. We want to
+ * keep the GUID definitions in line with the UEFI spec. */
+#define EFI_GLOBAL_VARIABLE_GUID EFI_GLOBAL_VARIABLE
+#define EFI_FILE_INFO_GUID EFI_FILE_INFO_ID
+
+#define EFI_GLOBAL_VARIABLE \
+        GUID_DEF(0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c)
+#define EFI_IMAGE_SECURITY_DATABASE_GUID \
+        GUID_DEF(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f)
+
+#define EVT_TIMER                         0x80000000U
+#define EVT_RUNTIME                       0x40000000U
+#define EVT_NOTIFY_WAIT                   0x00000100U
+#define EVT_NOTIFY_SIGNAL                 0x00000200U
+#define EVT_SIGNAL_EXIT_BOOT_SERVICES     0x00000201U
+#define EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202U
+
+#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL  0x01U
+#define EFI_OPEN_PROTOCOL_GET_PROTOCOL        0x02U
+#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL       0x04U
+#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x08U
+#define EFI_OPEN_PROTOCOL_BY_DRIVER           0x10U
+#define EFI_OPEN_PROTOCOL_EXCLUSIVE           0x20U
+
+#define EFI_VARIABLE_NON_VOLATILE                          0x01U
+#define EFI_VARIABLE_BOOTSERVICE_ACCESS                    0x02U
+#define EFI_VARIABLE_RUNTIME_ACCESS                        0x04U
+#define EFI_VARIABLE_HARDWARE_ERROR_RECORD                 0x08U
+#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS            0x10U
+#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x20U
+#define EFI_VARIABLE_APPEND_WRITE                          0x40U
+#define EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS         0x80U
+
+#define EFI_TIME_ADJUST_DAYLIGHT 0x001U
+#define EFI_TIME_IN_DAYLIGHT     0x002U
+#define EFI_UNSPECIFIED_TIMEZONE 0x7FFU
+
+#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI                   0x01U
+#define EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION            0x02U
+#define EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED 0x04U
+#define EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED           0x08U
+#define EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED    0x10U
+#define EFI_OS_INDICATIONS_START_OS_RECOVERY               0x20U
+#define EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY         0x40U
+#define EFI_OS_INDICATIONS_JSON_CONFIG_DATA_REFRESH        0x80U
+
+#define EFI_PAGE_SIZE 4096U
+#define EFI_SIZE_TO_PAGES(s) ((s) + 0xFFFU) >> 12U
+
+/* These are common enough to warrant forward declaration. We also give them a
+ * shorter name for convenience. */
+typedef struct EFI_FILE_PROTOCOL EFI_FILE;
+typedef struct EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH;
+
+typedef struct EFI_SIMPLE_TEXT_INPUT_PROTOCOL EFI_SIMPLE_TEXT_INPUT_PROTOCOL;
+typedef struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
+
+typedef enum {
+        TimerCancel,
+        TimerPeriodic,
+        TimerRelative,
+} EFI_TIMER_DELAY;
+
+typedef enum {
+        AllocateAnyPages,
+        AllocateMaxAddress,
+        AllocateAddress,
+        MaxAllocateType,
+} EFI_ALLOCATE_TYPE;
+
+typedef enum {
+        EfiReservedMemoryType,
+        EfiLoaderCode,
+        EfiLoaderData,
+        EfiBootServicesCode,
+        EfiBootServicesData,
+        EfiRuntimeServicesCode,
+        EfiRuntimeServicesData,
+        EfiConventionalMemory,
+        EfiUnusableMemory,
+        EfiACPIReclaimMemory,
+        EfiACPIMemoryNVS,
+        EfiMemoryMappedIO,
+        EfiMemoryMappedIOPortSpace,
+        EfiPalCode,
+        EfiPersistentMemory,
+        EfiUnacceptedMemoryType,
+        EfiMaxMemoryType,
+} EFI_MEMORY_TYPE;
+
+typedef enum {
+        AllHandles,
+        ByRegisterNotify,
+        ByProtocol,
+} EFI_LOCATE_SEARCH_TYPE;
+
+typedef enum {
+        EfiResetCold,
+        EfiResetWarm,
+        EfiResetShutdown,
+        EfiResetPlatformSpecific,
+} EFI_RESET_TYPE;
+
+typedef struct {
+        uint16_t Year;
+        uint8_t Month;
+        uint8_t Day;
+        uint8_t Hour;
+        uint8_t Minute;
+        uint8_t Second;
+        uint8_t Pad1;
+        uint32_t Nanosecond;
+        int16_t TimeZone;
+        uint8_t Daylight;
+        uint8_t Pad2;
+} EFI_TIME;
+
+typedef struct {
+        uint32_t Resolution;
+        uint32_t Accuracy;
+        bool SetsToZero;
+} EFI_TIME_CAPABILITIES;
+
+typedef struct {
+        uint64_t Signature;
+        uint32_t Revision;
+        uint32_t HeaderSize;
+        uint32_t CRC32;
+        uint32_t Reserved;
+} EFI_TABLE_HEADER;
+
+typedef struct {
+        EFI_TABLE_HEADER Hdr;
+        void *RaiseTPL;
+        void *RestoreTPL;
+        EFI_STATUS (EFIAPI *AllocatePages)(
+                        EFI_ALLOCATE_TYPE Type,
+                        EFI_MEMORY_TYPE MemoryType,
+                        size_t Pages,
+                        EFI_PHYSICAL_ADDRESS *Memory);
+        EFI_STATUS (EFIAPI *FreePages)(
+                        EFI_PHYSICAL_ADDRESS Memory,
+                        size_t Pages);
+        void *GetMemoryMap;
+        EFI_STATUS (EFIAPI *AllocatePool)(
+                        EFI_MEMORY_TYPE PoolType,
+                        size_t Size,
+                        void **Buffer);
+        EFI_STATUS (EFIAPI *FreePool)(void *Buffer);
+        EFI_STATUS (EFIAPI *CreateEvent)(
+                        uint32_t Type,
+                        EFI_TPL NotifyTpl,
+                        void *NotifyFunction,
+                        void *NotifyContext,
+                        EFI_EVENT *Event);
+        EFI_STATUS (EFIAPI *SetTimer)(
+                        EFI_EVENT Event,
+                        EFI_TIMER_DELAY Type,
+                        uint64_t TriggerTime);
+        EFI_STATUS (EFIAPI *WaitForEvent)(
+                        size_t NumberOfEvents,
+                        EFI_EVENT *Event,
+                        size_t *Index);
+        void *SignalEvent;
+        EFI_STATUS (EFIAPI *CloseEvent)(EFI_EVENT Event);
+        EFI_STATUS (EFIAPI *CheckEvent)(EFI_EVENT Event);
+        void *InstallProtocolInterface;
+        EFI_STATUS (EFIAPI *ReinstallProtocolInterface)(
+                        EFI_HANDLE Handle,
+                        EFI_GUID *Protocol,
+                        void *OldInterface,
+                        void *NewInterface);
+        void *UninstallProtocolInterface;
+        EFI_STATUS (EFIAPI *HandleProtocol)(
+                        EFI_HANDLE Handle,
+                        EFI_GUID *Protocol,
+                        void **Interface);
+        void *Reserved;
+        void *RegisterProtocolNotify;
+        EFI_STATUS (EFIAPI *LocateHandle)(
+                        EFI_LOCATE_SEARCH_TYPE SearchType,
+                        EFI_GUID *Protocol,
+                        void *SearchKey,
+                        size_t *BufferSize,
+                        EFI_HANDLE *Buffer);
+        EFI_STATUS (EFIAPI *LocateDevicePath)(
+                        EFI_GUID *Protocol,
+                        EFI_DEVICE_PATH **DevicePath,
+                        EFI_HANDLE *Device);
+        EFI_STATUS (EFIAPI *InstallConfigurationTable)(
+                        EFI_GUID *Guid,
+                        void *Table);
+        EFI_STATUS (EFIAPI *LoadImage)(
+                        bool BootPolicy,
+                        EFI_HANDLE ParentImageHandle,
+                        EFI_DEVICE_PATH *DevicePath,
+                        void *SourceBuffer,
+                        size_t SourceSize,
+                        EFI_HANDLE *ImageHandle);
+        EFI_STATUS (EFIAPI *StartImage)(
+                        EFI_HANDLE ImageHandle,
+                        size_t *ExitDataSize,
+                        char16_t **ExitData);
+        EFI_STATUS (EFIAPI *Exit)(
+                        EFI_HANDLE ImageHandle,
+                        EFI_STATUS ExitStatus,
+                        size_t ExitDataSize,
+                        char16_t *ExitData);
+        EFI_STATUS (EFIAPI *UnloadImage)(EFI_HANDLE ImageHandle);
+        void *ExitBootServices;
+        EFI_STATUS (EFIAPI *GetNextMonotonicCount)(uint64_t *Count);
+        EFI_STATUS (EFIAPI *Stall)(size_t Microseconds);
+        EFI_STATUS (EFIAPI *SetWatchdogTimer)(
+                        size_t Timeout,
+                        uint64_t WatchdogCode,
+                        size_t DataSize,
+                        char16_t *WatchdogData);
+        EFI_STATUS (EFIAPI *ConnectController)(
+                        EFI_HANDLE ControllerHandle,
+                        EFI_HANDLE *DriverImageHandle,
+                        EFI_DEVICE_PATH *RemainingDevicePath,
+                        bool Recursive);
+        EFI_STATUS (EFIAPI *DisconnectController)(
+                        EFI_HANDLE ControllerHandle,
+                        EFI_HANDLE DriverImageHandle,
+                        EFI_HANDLE ChildHandle);
+        EFI_STATUS (EFIAPI *OpenProtocol)(
+                        EFI_HANDLE Handle,
+                        EFI_GUID *Protocol,
+                        void **Interface,
+                        EFI_HANDLE AgentHandle,
+                        EFI_HANDLE ControllerHandle,
+                        uint32_t Attributes);
+        EFI_STATUS (EFIAPI *CloseProtocol)(
+                        EFI_HANDLE Handle,
+                        EFI_GUID *Protocol,
+                        EFI_HANDLE AgentHandle,
+                        EFI_HANDLE ControllerHandle);
+        void *OpenProtocolInformation;
+        EFI_STATUS (EFIAPI *ProtocolsPerHandle)(
+                        EFI_HANDLE Handle,
+                        EFI_GUID ***ProtocolBuffer,
+                        size_t *ProtocolBufferCount);
+        EFI_STATUS (EFIAPI *LocateHandleBuffer)(
+                        EFI_LOCATE_SEARCH_TYPE SearchType,
+                        EFI_GUID *Protocol,
+                        void *SearchKey,
+                        size_t *NoHandles,
+                        EFI_HANDLE **Buffer);
+        EFI_STATUS (EFIAPI *LocateProtocol)(
+                        EFI_GUID *Protocol,
+                        void *Registration,
+                        void **Interface);
+        EFI_STATUS (EFIAPI *InstallMultipleProtocolInterfaces)(EFI_HANDLE *Handle, ...);
+        EFI_STATUS (EFIAPI *UninstallMultipleProtocolInterfaces)(EFI_HANDLE Handle, ...);
+        EFI_STATUS (EFIAPI *CalculateCrc32)(
+                        void *Data,
+                        size_t DataSize,
+                        uint32_t *Crc32);
+        void (EFIAPI *CopyMem)(
+                        void *Destination,
+                        void *Source,
+                        size_t Length);
+        void (EFIAPI *SetMem)(
+                        void *Buffer,
+                        size_t Size,
+                        uint8_t Value);
+        void *CreateEventEx;
+} EFI_BOOT_SERVICES;
+
+typedef struct {
+        EFI_TABLE_HEADER Hdr;
+        EFI_STATUS (EFIAPI *GetTime)(
+                        EFI_TIME *Time,
+                        EFI_TIME_CAPABILITIES *Capabilities);
+        EFI_STATUS (EFIAPI *SetTime)(EFI_TIME *Time);
+        void *GetWakeupTime;
+        void *SetWakeupTime;
+        void *SetVirtualAddressMap;
+        void *ConvertPointer;
+        EFI_STATUS (EFIAPI *GetVariable)(
+                        char16_t *VariableName,
+                        EFI_GUID *VendorGuid,
+                        uint32_t *Attributes,
+                        size_t *DataSize,
+                        void *Data);
+        void *GetNextVariableName;
+        EFI_STATUS (EFIAPI *SetVariable)(
+                        char16_t *VariableName,
+                        EFI_GUID *VendorGuid,
+                        uint32_t Attributes,
+                        size_t  DataSize,
+                        void *Data);
+        EFI_STATUS (EFIAPI *GetNextHighMonotonicCount)(uint32_t *HighCount);
+        void (EFIAPI *ResetSystem)(
+                        EFI_RESET_TYPE ResetType,
+                        EFI_STATUS ResetStatus,
+                        size_t DataSize,
+                        void *ResetData);
+        void *UpdateCapsule;
+        void *QueryCapsuleCapabilities;
+        void *QueryVariableInfo;
+} EFI_RUNTIME_SERVICES;
+
+typedef struct {
+        EFI_TABLE_HEADER Hdr;
+        char16_t *FirmwareVendor;
+        uint32_t FirmwareRevision;
+        EFI_HANDLE ConsoleInHandle;
+        EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
+        EFI_HANDLE ConsoleOutHandle;
+        EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
+        EFI_HANDLE StandardErrorHandle;
+        EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *StdErr;
+        EFI_RUNTIME_SERVICES *RuntimeServices;
+        EFI_BOOT_SERVICES *BootServices;
+        size_t NumberOfTableEntries;
+        struct {
+                EFI_GUID VendorGuid;
+                void *VendorTable;
+        } *ConfigurationTable;
+} EFI_SYSTEM_TABLE;
+
+extern EFI_SYSTEM_TABLE *ST;
+extern EFI_BOOT_SERVICES *BS;
+extern EFI_RUNTIME_SERVICES *RT;
index d68123df589e95bdd79f69ceb8ad3fffb3a7093d..496fc6918991c226cc902ad468945c301df096ba 100644 (file)
@@ -4,22 +4,19 @@
  *   Authored by Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
  */
 
-#include <efi.h>
-#include <efilib.h>
-
 #include "graphics.h"
-#include "missing_efi.h"
+#include "proto/console-control.h"
+#include "proto/simple-text-io.h"
 #include "util.h"
 
 EFI_STATUS graphics_mode(bool on) {
         EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
         EFI_CONSOLE_CONTROL_SCREEN_MODE new;
         EFI_CONSOLE_CONTROL_SCREEN_MODE current;
-        BOOLEAN uga_exists;
-        BOOLEAN stdin_locked;
+        bool uga_exists, stdin_locked;
         EFI_STATUS err;
 
-        err = BS->LocateProtocol(MAKE_GUID_PTR(EFI_CONSOLE_CONTROL), NULL, (void **) &ConsoleControl);
+        err = BS->LocateProtocol(MAKE_GUID_PTR(EFI_CONSOLE_CONTROL_PROTOCOL), NULL, (void **) &ConsoleControl);
         if (err != EFI_SUCCESS)
                 /* console control protocol is nonstandard and might not exist. */
                 return err == EFI_NOT_FOUND ? EFI_SUCCESS : err;
index 9dadd3985eecd488cfb0fbc4d84cf3b3aded3251..33ab7f8c5e3ae5ca6f08581187d5a6de0e1e90da 100644 (file)
@@ -5,7 +5,6 @@
  */
 #pragma once
 
-#include <efi.h>
-#include <stdbool.h>
+#include "efi.h"
 
 EFI_STATUS graphics_mode(bool on);
index 6d362435c40de0db4da8bd068e53e55a3da7c7c2..e8af9995086ea78f15bb9aace04ee8d9317fccc6 100644 (file)
@@ -1,13 +1,14 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <efi.h>
-#include <efilib.h>
-
 #include "initrd.h"
 #include "macro-fundamental.h"
-#include "missing_efi.h"
+#include "proto/device-path.h"
+#include "proto/load-file.h"
 #include "util.h"
 
+#define LINUX_INITRD_MEDIA_GUID \
+        GUID_DEF(0x5568e427, 0x68fc, 0x4f3d, 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68)
+
 /* extend LoadFileProtocol */
 struct initrd_loader {
         EFI_LOAD_FILE_PROTOCOL load_file;
@@ -26,21 +27,21 @@ static const struct {
                 .Header = {
                         .Type = MEDIA_DEVICE_PATH,
                         .SubType = MEDIA_VENDOR_DP,
-                        .Length = { sizeof(efi_initrd_device_path.vendor), 0 }
+                        .Length = sizeof(efi_initrd_device_path.vendor),
                 },
                 .Guid = LINUX_INITRD_MEDIA_GUID
         },
         .end = {
                 .Type = END_DEVICE_PATH_TYPE,
                 .SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE,
-                .Length = { sizeof(efi_initrd_device_path.end), 0 }
+                .Length = sizeof(efi_initrd_device_path.end),
         }
 };
 
 static EFIAPI EFI_STATUS initrd_load_file(
                 EFI_LOAD_FILE_PROTOCOL *this,
                 EFI_DEVICE_PATH *file_path,
-                BOOLEAN boot_policy,
+                bool boot_policy,
                 size_t *buffer_size,
                 void *buffer) {
 
index c3dda6d8c1be59c7d2bdd4a482b8d98e6ec4c5fc..e7685aeb4a65875c238eb1b0af28f8b75ef095eb 100644 (file)
@@ -1,8 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <efi.h>
-#include <stddef.h>
+#include "efi.h"
 
 EFI_STATUS initrd_register(
                 const void *initrd_address,
index 8feea1d3c995179a996f18ea06c3ee9359459ca2..65bc176df779e7f0f41a1fc0051062f62f097028 100644 (file)
@@ -8,12 +8,11 @@
  * This method works for Linux 5.8 and newer on ARM/Aarch64, x86/x68_64 and RISC-V.
  */
 
-#include <efi.h>
-#include <efilib.h>
-
 #include "initrd.h"
 #include "linux.h"
 #include "pe.h"
+#include "proto/device-path.h"
+#include "proto/loaded-image.h"
 #include "secure-boot.h"
 #include "util.h"
 
@@ -57,14 +56,14 @@ static EFI_STATUS load_image(EFI_HANDLE parent, const void *source, size_t len,
                         .Header = {
                                 .Type = MEDIA_DEVICE_PATH,
                                 .SubType = MEDIA_VENDOR_DP,
-                                .Length = { sizeof(payload_device_path.payload), 0 },
+                                .Length = sizeof(payload_device_path.payload),
                         },
                         .Guid = STUB_PAYLOAD_GUID,
                 },
                 .end = {
                         .Type = END_DEVICE_PATH_TYPE,
                         .SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE,
-                        .Length = { sizeof(payload_device_path.end), 0 },
+                        .Length = sizeof(payload_device_path.end),
                 },
         };
 
index f0a6a37ed1bd514d5eedf7f0cc563ba8d45f8182..46b5f4f4d7c3a8a1de0df854b40c593bd60bff19 100644 (file)
@@ -1,8 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <efi.h>
-#include <uchar.h>
+#include "efi.h"
 
 EFI_STATUS linux_exec(
                 EFI_HANDLE parent,
index eaae988d975579fad441843abf376aad264a9425..5021b076cb2391cd94170e3711d3ecfc26dfbf05 100644 (file)
@@ -10,9 +10,6 @@
  * see https://docs.kernel.org/x86/boot.html
  */
 
-#include <efi.h>
-#include <efilib.h>
-
 #include "initrd.h"
 #include "linux.h"
 #include "macro-fundamental.h"
index b1a613e4e5981ae5739ffd4738fa8dee94ee497a..4d8ad937168ccaab86394b9d647f8dd7a52761a8 100644 (file)
@@ -1,9 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <efi.h>
-#include <efilib.h>
-
 #include "log.h"
+#include "proto/simple-text-io.h"
 
 static unsigned log_count = 0;
 
@@ -20,7 +18,7 @@ EFI_STATUS log_internal(EFI_STATUS status, const char *format, ...) {
 
         if (ST->ConOut->Mode->CursorColumn > 0)
                 ST->ConOut->OutputString(ST->ConOut, (char16_t *) u"\r\n");
-        ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTRED | EFI_BACKGROUND_BLACK);
+        ST->ConOut->SetAttribute(ST->ConOut, EFI_TEXT_ATTR(EFI_LIGHTRED, EFI_BLACK));
 
         va_list ap;
         va_start(ap, format);
index 2f9b2b9e9daaff8b653aa3b8620f004cfd31daf2..c2552268d5ec4a0ee2fc7723ecba828e362d6d20 100644 (file)
@@ -2,17 +2,14 @@
 
 #if ENABLE_TPM
 
-#include <efi.h>
-#include <efilib.h>
-
-#include "tpm-pcr.h"
 #include "macro-fundamental.h"
 #include "measure.h"
-#include "missing_efi.h"
+#include "proto/tcg.h"
+#include "tpm-pcr.h"
 #include "util.h"
 
 static EFI_STATUS tpm1_measure_to_pcr_and_event_log(
-                const EFI_TCG *tcg,
+                const EFI_TCG_PROTOCOL *tcg,
                 uint32_t pcrindex,
                 EFI_PHYSICAL_ADDRESS buffer,
                 size_t buffer_size,
@@ -37,7 +34,7 @@ static EFI_STATUS tpm1_measure_to_pcr_and_event_log(
         memcpy(tcg_event->Event, description, desc_len);
 
         return tcg->HashLogExtendEvent(
-                        (EFI_TCG *) tcg,
+                        (EFI_TCG_PROTOCOL *) tcg,
                         buffer, buffer_size,
                         TCG_ALG_SHA,
                         tcg_event,
@@ -46,7 +43,7 @@ static EFI_STATUS tpm1_measure_to_pcr_and_event_log(
 }
 
 static EFI_STATUS tpm2_measure_to_pcr_and_event_log(
-                EFI_TCG2 *tcg,
+                EFI_TCG2_PROTOCOL *tcg,
                 uint32_t pcrindex,
                 EFI_PHYSICAL_ADDRESS buffer,
                 uint64_t buffer_size,
@@ -78,16 +75,16 @@ static EFI_STATUS tpm2_measure_to_pcr_and_event_log(
                         tcg_event);
 }
 
-static EFI_TCGtcg1_interface_check(void) {
+static EFI_TCG_PROTOCOL *tcg1_interface_check(void) {
         EFI_PHYSICAL_ADDRESS event_log_location, event_log_last_entry;
-        TCG_BOOT_SERVICE_CAPABILITY capability = {
+        EFI_TCG_BOOT_SERVICE_CAPABILITY capability = {
                 .Size = sizeof(capability),
         };
         EFI_STATUS err;
         uint32_t features;
-        EFI_TCG *tcg;
+        EFI_TCG_PROTOCOL *tcg;
 
-        err = BS->LocateProtocol(MAKE_GUID_PTR(EFI_TCG), NULL, (void **) &tcg);
+        err = BS->LocateProtocol(MAKE_GUID_PTR(EFI_TCG_PROTOCOL), NULL, (void **) &tcg);
         if (err != EFI_SUCCESS)
                 return NULL;
 
@@ -109,14 +106,14 @@ static EFI_TCG* tcg1_interface_check(void) {
         return tcg;
 }
 
-static EFI_TCG2tcg2_interface_check(void) {
+static EFI_TCG2_PROTOCOL *tcg2_interface_check(void) {
         EFI_TCG2_BOOT_SERVICE_CAPABILITY capability = {
                 .Size = sizeof(capability),
         };
         EFI_STATUS err;
-        EFI_TCG2 *tcg;
+        EFI_TCG2_PROTOCOL *tcg;
 
-        err = BS->LocateProtocol(MAKE_GUID_PTR(EFI_TCG2), NULL, (void **) &tcg);
+        err = BS->LocateProtocol(MAKE_GUID_PTR(EFI_TCG2_PROTOCOL), NULL, (void **) &tcg);
         if (err != EFI_SUCCESS)
                 return NULL;
 
@@ -126,8 +123,8 @@ static EFI_TCG2* tcg2_interface_check(void) {
 
         if (capability.StructureVersion.Major == 1 &&
             capability.StructureVersion.Minor == 0) {
-                TCG_BOOT_SERVICE_CAPABILITY *caps_1_0 =
-                        (TCG_BOOT_SERVICE_CAPABILITY*) &capability;
+                EFI_TCG_BOOT_SERVICE_CAPABILITY *caps_1_0 =
+                        (EFI_TCG_BOOT_SERVICE_CAPABILITY*) &capability;
                 if (caps_1_0->TPMPresentFlag)
                         return tcg;
         }
@@ -143,7 +140,7 @@ bool tpm_present(void) {
 }
 
 EFI_STATUS tpm_log_event(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, size_t buffer_size, const char16_t *description, bool *ret_measured) {
-        EFI_TCG2 *tpm2;
+        EFI_TCG2_PROTOCOL *tpm2;
         EFI_STATUS err;
 
         assert(description || pcrindex == UINT32_MAX);
@@ -162,7 +159,7 @@ EFI_STATUS tpm_log_event(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, size_t
         if (tpm2)
                 err = tpm2_measure_to_pcr_and_event_log(tpm2, pcrindex, buffer, buffer_size, description);
         else {
-                EFI_TCG *tpm1;
+                EFI_TCG_PROTOCOL *tpm1;
 
                 tpm1 = tcg1_interface_check();
                 if (tpm1)
index 44d23fe75c8c5b287290c2bbd5cae15ac25c0674..d252f0f832b466810ea11cd26a68722c2adb8a43 100644 (file)
@@ -1,9 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <efi.h>
-#include <stdbool.h>
-#include <uchar.h>
+#include "efi.h"
 
 #if ENABLE_TPM
 
index 8c509458a0700be9db062fb8d3fe420bc1947f19..8d85dac84448bfeccaa2ef247f6703aa23db33f9 100644 (file)
@@ -184,8 +184,6 @@ efi_cflags = [
         '-I', meson.current_source_dir(),
         '-include', efi_config_h,
         '-include', version_h,
-        '-isystem', efi_incdir / efi_arch[1],
-        '-isystem', efi_incdir,
         '-std=gnu11',
         '-Wall',
         '-Wextra',
@@ -257,6 +255,7 @@ efi_ldflags = [
         '-Wl,--warn-common',
         '-Wl,-Bsymbolic',
         '-z', 'nocombreloc',
+        '-z', 'noexecstack',
         efi_crt0,
 ]
 
@@ -337,14 +336,27 @@ efi_headers = files(
         'disk.h',
         'drivers.h',
         'efi-string.h',
+        'efi.h',
         'graphics.h',
         'initrd.h',
         'linux.h',
         'log.h',
         'measure.h',
-        'missing_efi.h',
         'part-discovery.h',
         'pe.h',
+        'proto/block-io.h',
+        'proto/console-control.h',
+        'proto/device-path.h',
+        'proto/dt-fixup.h',
+        'proto/file-io.h',
+        'proto/graphics-output.h',
+        'proto/load-file.h',
+        'proto/loaded-image.h',
+        'proto/rng.h',
+        'proto/security-arch.h',
+        'proto/shell-parameters.h',
+        'proto/simple-text-io.h',
+        'proto/tcg.h',
         'random-seed.h',
         'secure-boot.h',
         'shim.h',
diff --git a/src/boot/efi/missing_efi.h b/src/boot/efi/missing_efi.h
deleted file mode 100644 (file)
index 3c35a85..0000000
+++ /dev/null
@@ -1,412 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#pragma once
-
-#include <efi.h>
-
-#include "macro-fundamental.h"
-
-/* gnu-efi 3.0.13 */
-#ifndef EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID
-
-#define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \
-    { 0xdd9e7534, 0x7762, 0x4698, {0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa} }
-#define SimpleTextInputExProtocol ((EFI_GUID)EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID)
-
-#define EFI_SHIFT_STATE_VALID           0x80000000
-#define EFI_RIGHT_SHIFT_PRESSED         0x00000001
-#define EFI_LEFT_SHIFT_PRESSED          0x00000002
-#define EFI_RIGHT_CONTROL_PRESSED       0x00000004
-#define EFI_LEFT_CONTROL_PRESSED        0x00000008
-#define EFI_RIGHT_ALT_PRESSED           0x00000010
-#define EFI_LEFT_ALT_PRESSED            0x00000020
-#define EFI_RIGHT_LOGO_PRESSED          0x00000040
-#define EFI_LEFT_LOGO_PRESSED           0x00000080
-
-struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL;
-
-typedef EFI_STATUS (EFIAPI *EFI_INPUT_RESET_EX)(
-        struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
-        BOOLEAN ExtendedVerification
-);
-
-typedef UINT8 EFI_KEY_TOGGLE_STATE;
-
-typedef struct {
-        UINT32 KeyShiftState;
-        EFI_KEY_TOGGLE_STATE KeyToggleState;
-} EFI_KEY_STATE;
-
-typedef struct {
-        EFI_INPUT_KEY Key;
-        EFI_KEY_STATE KeyState;
-} EFI_KEY_DATA;
-
-typedef EFI_STATUS (EFIAPI *EFI_INPUT_READ_KEY_EX)(
-        struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
-        EFI_KEY_DATA *KeyData
-);
-
-typedef EFI_STATUS (EFIAPI *EFI_SET_STATE)(
-        struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
-        EFI_KEY_TOGGLE_STATE *KeyToggleState
-);
-
-typedef EFI_STATUS (EFIAPI *EFI_KEY_NOTIFY_FUNCTION)(
-        EFI_KEY_DATA *KeyData
-);
-
-typedef EFI_STATUS (EFIAPI *EFI_REGISTER_KEYSTROKE_NOTIFY)(
-        struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
-        EFI_KEY_DATA KeyData,
-        EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
-        VOID **NotifyHandle
-);
-
-typedef EFI_STATUS (EFIAPI *EFI_UNREGISTER_KEYSTROKE_NOTIFY)(
-        struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
-        VOID *NotificationHandle
-);
-
-typedef struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL {
-        EFI_INPUT_RESET_EX Reset;
-        EFI_INPUT_READ_KEY_EX ReadKeyStrokeEx;
-        EFI_EVENT WaitForKeyEx;
-        EFI_SET_STATE SetState;
-        EFI_REGISTER_KEYSTROKE_NOTIFY RegisterKeyNotify;
-        EFI_UNREGISTER_KEYSTROKE_NOTIFY UnregisterKeyNotify;
-} EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL;
-
-#endif
-
-/* gnu-efi 3.0.14 */
-#ifndef EFI_IMAGE_MACHINE_RISCV64
-        #define EFI_IMAGE_MACHINE_RISCV64 0x5064
-#endif
-
-/* gnu-efi 3.0.14 */
-#ifndef EFI_DTB_TABLE_GUID
-#define EFI_DTB_TABLE_GUID \
-        { 0xb1b621d5, 0xf19c, 0x41a5, {0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0} }
-#define EfiDtbTableGuid ((EFI_GUID)EFI_DTB_TABLE_GUID)
-#endif
-
-#ifndef EFI_DT_FIXUP_PROTOCOL_GUID
-#define EFI_DT_FIXUP_PROTOCOL_GUID \
-        { 0xe617d64c, 0xfe08, 0x46da, {0xf4, 0xdc, 0xbb, 0xd5, 0x87, 0x0c, 0x73, 0x00} }
-#define EfiDtFixupProtocol ((EFI_GUID)EFI_DT_FIXUP_PROTOCOL_GUID)
-
-#define EFI_DT_FIXUP_PROTOCOL_REVISION 0x00010000
-
-/* Add nodes and update properties */
-#define EFI_DT_APPLY_FIXUPS    0x00000001
-/*
- * Reserve memory according to the /reserved-memory node
- * and the memory reservation block
- */
-#define EFI_DT_RESERVE_MEMORY  0x00000002
-
-typedef struct _EFI_DT_FIXUP_PROTOCOL EFI_DT_FIXUP_PROTOCOL;
-
-typedef EFI_STATUS (EFIAPI *EFI_DT_FIXUP) (
-        IN EFI_DT_FIXUP_PROTOCOL *This,
-        IN VOID                  *Fdt,
-        IN OUT UINTN             *BufferSize,
-        IN UINT32                Flags);
-
-struct _EFI_DT_FIXUP_PROTOCOL {
-        UINT64         Revision;
-        EFI_DT_FIXUP   Fixup;
-};
-
-#endif
-
-/* TCG EFI Protocol Specification */
-#ifndef EFI_TCG_GUID
-
-#define EFI_TCG_GUID \
-        { 0xf541796d, 0xa62e, 0x4954, { 0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd } }
-
-typedef struct _TCG_VERSION {
-        UINT8 Major;
-        UINT8 Minor;
-        UINT8 RevMajor;
-        UINT8 RevMinor;
-} TCG_VERSION;
-
-typedef struct tdEFI_TCG2_VERSION {
-        UINT8 Major;
-        UINT8 Minor;
-} EFI_TCG2_VERSION;
-
-typedef struct _TCG_BOOT_SERVICE_CAPABILITY {
-        UINT8 Size;
-        struct _TCG_VERSION StructureVersion;
-        struct _TCG_VERSION ProtocolSpecVersion;
-        UINT8 HashAlgorithmBitmap;
-        BOOLEAN TPMPresentFlag;
-        BOOLEAN TPMDeactivatedFlag;
-} TCG_BOOT_SERVICE_CAPABILITY;
-
-typedef struct tdTREE_BOOT_SERVICE_CAPABILITY {
-        UINT8 Size;
-        EFI_TCG2_VERSION StructureVersion;
-        EFI_TCG2_VERSION ProtocolVersion;
-        UINT32 HashAlgorithmBitmap;
-        UINT32 SupportedEventLogs;
-        BOOLEAN TrEEPresentFlag;
-        UINT16 MaxCommandSize;
-        UINT16 MaxResponseSize;
-        UINT32 ManufacturerID;
-} TREE_BOOT_SERVICE_CAPABILITY;
-
-typedef UINT32 TCG_ALGORITHM_ID;
-#define TCG_ALG_SHA 0x00000004  // The SHA1 algorithm
-
-#define SHA1_DIGEST_SIZE 20
-
-typedef struct _TCG_DIGEST {
-        UINT8 Digest[SHA1_DIGEST_SIZE];
-} TCG_DIGEST;
-
-#define EV_IPL 13
-
-typedef struct _TCG_PCR_EVENT {
-        UINT32 PCRIndex;
-        UINT32 EventType;
-        struct _TCG_DIGEST digest;
-        UINT32 EventSize;
-        UINT8 Event[1];
-} TCG_PCR_EVENT;
-
-INTERFACE_DECL(_EFI_TCG);
-
-typedef EFI_STATUS(EFIAPI * EFI_TCG_STATUS_CHECK) (IN struct _EFI_TCG * This,
-                                                   OUT struct _TCG_BOOT_SERVICE_CAPABILITY * ProtocolCapability,
-                                                   OUT UINT32 * TCGFeatureFlags,
-                                                   OUT EFI_PHYSICAL_ADDRESS * EventLogLocation,
-                                                   OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry);
-
-typedef EFI_STATUS(EFIAPI * EFI_TCG_HASH_ALL) (IN struct _EFI_TCG * This,
-                                               IN UINT8 * HashData,
-                                               IN UINT64 HashDataLen,
-                                               IN TCG_ALGORITHM_ID AlgorithmId,
-                                               IN OUT UINT64 * HashedDataLen, IN OUT UINT8 ** HashedDataResult);
-
-typedef EFI_STATUS(EFIAPI * EFI_TCG_LOG_EVENT) (IN struct _EFI_TCG * This,
-                                                IN struct _TCG_PCR_EVENT * TCGLogData,
-                                                IN OUT UINT32 * EventNumber, IN UINT32 Flags);
-
-typedef EFI_STATUS(EFIAPI * EFI_TCG_PASS_THROUGH_TO_TPM) (IN struct _EFI_TCG * This,
-                                                          IN UINT32 TpmInputParameterBlockSize,
-                                                          IN UINT8 * TpmInputParameterBlock,
-                                                          IN UINT32 TpmOutputParameterBlockSize,
-                                                          IN UINT8 * TpmOutputParameterBlock);
-
-typedef EFI_STATUS(EFIAPI * EFI_TCG_HASH_LOG_EXTEND_EVENT) (IN struct _EFI_TCG * This,
-                                                            IN EFI_PHYSICAL_ADDRESS HashData,
-                                                            IN UINT64 HashDataLen,
-                                                            IN TCG_ALGORITHM_ID AlgorithmId,
-                                                            IN struct _TCG_PCR_EVENT * TCGLogData,
-                                                            IN OUT UINT32 * EventNumber,
-                                                            OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry);
-
-typedef struct _EFI_TCG {
-        EFI_TCG_STATUS_CHECK StatusCheck;
-        EFI_TCG_HASH_ALL HashAll;
-        EFI_TCG_LOG_EVENT LogEvent;
-        EFI_TCG_PASS_THROUGH_TO_TPM PassThroughToTPM;
-        EFI_TCG_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
-} EFI_TCG;
-
-#endif
-
-/* TCG EFI Protocol Specification */
-#ifndef EFI_TCG2_GUID
-
-#define EFI_TCG2_GUID \
-        { 0x607f766c, 0x7455, 0x42be, { 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f } }
-
-typedef struct tdEFI_TCG2_PROTOCOL EFI_TCG2_PROTOCOL;
-
-typedef UINT32 EFI_TCG2_EVENT_LOG_BITMAP;
-typedef UINT32 EFI_TCG2_EVENT_LOG_FORMAT;
-typedef UINT32 EFI_TCG2_EVENT_ALGORITHM_BITMAP;
-
-typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY {
-        UINT8 Size;
-        EFI_TCG2_VERSION StructureVersion;
-        EFI_TCG2_VERSION ProtocolVersion;
-        EFI_TCG2_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap;
-        EFI_TCG2_EVENT_LOG_BITMAP SupportedEventLogs;
-        BOOLEAN TPMPresentFlag;
-        UINT16 MaxCommandSize;
-        UINT16 MaxResponseSize;
-        UINT32 ManufacturerID;
-        UINT32 NumberOfPCRBanks;
-        EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrBanks;
-} EFI_TCG2_BOOT_SERVICE_CAPABILITY;
-
-#define EFI_TCG2_EVENT_HEADER_VERSION  1
-
-typedef struct {
-        UINT32 HeaderSize;
-        UINT16 HeaderVersion;
-        UINT32 PCRIndex;
-        UINT32 EventType;
-} _packed_ EFI_TCG2_EVENT_HEADER;
-
-typedef struct tdEFI_TCG2_EVENT {
-        UINT32 Size;
-        EFI_TCG2_EVENT_HEADER Header;
-        UINT8 Event[1];
-} _packed_ EFI_TCG2_EVENT;
-
-typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_CAPABILITY) (IN EFI_TCG2_PROTOCOL * This,
-                                                      IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY * ProtocolCapability);
-
-typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_EVENT_LOG) (IN EFI_TCG2_PROTOCOL * This,
-                                                     IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,
-                                                     OUT EFI_PHYSICAL_ADDRESS * EventLogLocation,
-                                                     OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry,
-                                                     OUT BOOLEAN * EventLogTruncated);
-
-typedef EFI_STATUS(EFIAPI * EFI_TCG2_HASH_LOG_EXTEND_EVENT) (IN EFI_TCG2_PROTOCOL * This,
-                                                             IN UINT64 Flags,
-                                                             IN EFI_PHYSICAL_ADDRESS DataToHash,
-                                                             IN UINT64 DataToHashLen, IN EFI_TCG2_EVENT * EfiTcgEvent);
-
-typedef EFI_STATUS(EFIAPI * EFI_TCG2_SUBMIT_COMMAND) (IN EFI_TCG2_PROTOCOL * This,
-                                                      IN UINT32 InputParameterBlockSize,
-                                                      IN UINT8 * InputParameterBlock,
-                                                      IN UINT32 OutputParameterBlockSize, IN UINT8 * OutputParameterBlock);
-
-typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This, OUT UINT32 * ActivePcrBanks);
-
-typedef EFI_STATUS(EFIAPI * EFI_TCG2_SET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This, IN UINT32 ActivePcrBanks);
-
-typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This,
-                                                                          OUT UINT32 * OperationPresent, OUT UINT32 * Response);
-
-typedef struct tdEFI_TCG2_PROTOCOL {
-        EFI_TCG2_GET_CAPABILITY GetCapability;
-        EFI_TCG2_GET_EVENT_LOG GetEventLog;
-        EFI_TCG2_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
-        EFI_TCG2_SUBMIT_COMMAND SubmitCommand;
-        EFI_TCG2_GET_ACTIVE_PCR_BANKS GetActivePcrBanks;
-        EFI_TCG2_SET_ACTIVE_PCR_BANKS SetActivePcrBanks;
-        EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS GetResultOfSetActivePcrBanks;
-} EFI_TCG2;
-
-#endif
-
-#ifndef EFI_LOAD_FILE2_PROTOCOL_GUID
-#define EFI_LOAD_FILE2_PROTOCOL_GUID \
-        {0x4006c0c1, 0xfcb3, 0x403e, {0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d} }
-#define EfiLoadFile2Protocol ((EFI_GUID)EFI_LOAD_FILE2_PROTOCOL_GUID)
-#endif
-
-#define LINUX_INITRD_MEDIA_GUID \
-        {0x5568e427, 0x68fc, 0x4f3d, {0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68} }
-
-/* UEFI Platform Initialization (Vol2: DXE) */
-#ifndef EFI_SECURITY_ARCH_PROTOCOL_GUID
-
-#define EFI_SECURITY_ARCH_PROTOCOL_GUID \
-        { 0xa46423e3, 0x4617, 0x49f1, { 0xb9, 0xff, 0xd1, 0xbf, 0xa9, 0x11, 0x58, 0x39 } }
-#define EFI_SECURITY2_ARCH_PROTOCOL_GUID \
-        { 0x94ab2f58, 0x1438, 0x4ef1, { 0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } }
-
-typedef struct EFI_SECURITY_ARCH_PROTOCOL EFI_SECURITY_ARCH_PROTOCOL;
-typedef struct EFI_SECURITY2_ARCH_PROTOCOL EFI_SECURITY2_ARCH_PROTOCOL;
-
-typedef EFI_STATUS (EFIAPI *EFI_SECURITY_FILE_AUTHENTICATION_STATE)(
-                const EFI_SECURITY_ARCH_PROTOCOL *This,
-                uint32_t AuthenticationStatus,
-                const EFI_DEVICE_PATH *File);
-
-struct EFI_SECURITY_ARCH_PROTOCOL {
-        EFI_SECURITY_FILE_AUTHENTICATION_STATE FileAuthenticationState;
-};
-
-typedef EFI_STATUS (EFIAPI *EFI_SECURITY2_FILE_AUTHENTICATION)(
-                const EFI_SECURITY2_ARCH_PROTOCOL *This,
-                const EFI_DEVICE_PATH *DevicePath,
-                void *FileBuffer,
-                UINTN FileSize,
-                BOOLEAN BootPolicy);
-
-struct EFI_SECURITY2_ARCH_PROTOCOL {
-        EFI_SECURITY2_FILE_AUTHENTICATION FileAuthentication;
-};
-
-#endif
-
-#ifndef EFI_CONSOLE_CONTROL_GUID
-
-#define EFI_CONSOLE_CONTROL_GUID \
-        { 0xf42f7782, 0x12e, 0x4c12, { 0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21 } }
-
-struct _EFI_CONSOLE_CONTROL_PROTOCOL;
-
-typedef enum {
-        EfiConsoleControlScreenText,
-        EfiConsoleControlScreenGraphics,
-        EfiConsoleControlScreenMaxValue,
-} EFI_CONSOLE_CONTROL_SCREEN_MODE;
-
-typedef EFI_STATUS (EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE)(
-        struct _EFI_CONSOLE_CONTROL_PROTOCOL *This,
-        EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode,
-        BOOLEAN *UgaExists,
-        BOOLEAN *StdInLocked
-);
-
-typedef EFI_STATUS (EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE)(
-        struct _EFI_CONSOLE_CONTROL_PROTOCOL *This,
-        EFI_CONSOLE_CONTROL_SCREEN_MODE Mode
-);
-
-typedef EFI_STATUS (EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN)(
-        struct _EFI_CONSOLE_CONTROL_PROTOCOL *This,
-        CHAR16 *Password
-);
-
-typedef struct _EFI_CONSOLE_CONTROL_PROTOCOL {
-        EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE GetMode;
-        EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE SetMode;
-        EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN LockStdIn;
-} EFI_CONSOLE_CONTROL_PROTOCOL;
-
-#endif
-
-#ifndef EFI_IMAGE_SECURITY_DATABASE_VARIABLE
-
-#define EFI_IMAGE_SECURITY_DATABASE_VARIABLE \
-        { 0xd719b2cb, 0x3d3a, 0x4596, {0xa3, 0xbc, 0xda, 0xd0,  0xe, 0x67, 0x65, 0x6f }}
-
-#endif
-
-#ifndef EFI_SHELL_PARAMETERS_PROTOCOL_GUID
-#  define EFI_SHELL_PARAMETERS_PROTOCOL_GUID \
-        { 0x752f3136, 0x4e16, 0x4fdc, { 0xa2, 0x2a, 0xe5, 0xf4, 0x68, 0x12, 0xf4, 0xca } }
-
-typedef struct {
-        CHAR16 **Argv;
-        UINTN Argc;
-        void *StdIn;
-        void *StdOut;
-        void *StdErr;
-} EFI_SHELL_PARAMETERS_PROTOCOL;
-#endif
-
-#ifndef EFI_WARN_UNKNOWN_GLYPH
-#  define EFI_WARN_UNKNOWN_GLYPH 1
-#endif
-
-#ifndef EFI_WARN_RESET_REQUIRED
-#  define EFI_WARN_STALE_DATA 5
-#  define EFI_WARN_FILE_SYSTEM 6
-#  define EFI_WARN_RESET_REQUIRED 7
-#  define EFI_IP_ADDRESS_CONFLICT EFIERR(34)
-#  define EFI_HTTP_ERROR EFIERR(35)
-#endif
index eb22df95b6a4394cb0f03309fef4f1df75cbe654..e25905ff48284a367ca118b6324b91e5163f439f 100644 (file)
@@ -1,16 +1,33 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <efi.h>
-#include <efigpt.h>
-#include <efilib.h>
-
 #include "part-discovery.h"
+#include "proto/block-io.h"
+#include "proto/device-path.h"
 #include "util.h"
 
-union GptHeaderBuffer {
-        EFI_PARTITION_TABLE_HEADER gpt_header;
-        uint8_t space[CONST_ALIGN_TO(sizeof(EFI_PARTITION_TABLE_HEADER), 512)];
-};
+typedef struct {
+        EFI_GUID PartitionTypeGUID;
+        EFI_GUID UniquePartitionGUID;
+        EFI_LBA StartingLBA;
+        EFI_LBA EndingLBA;
+        uint64_t Attributes;
+        char16_t PartitionName[36];
+} EFI_PARTITION_ENTRY;
+
+typedef struct {
+        EFI_TABLE_HEADER Header;
+        EFI_LBA MyLBA;
+        EFI_LBA AlternateLBA;
+        EFI_LBA FirstUsableLBA;
+        EFI_LBA LastUsableLBA;
+        EFI_GUID DiskGUID;
+        EFI_LBA PartitionEntryLBA;
+        uint32_t NumberOfPartitionEntries;
+        uint32_t SizeOfPartitionEntry;
+        uint32_t PartitionEntryArrayCRC32;
+        uint8_t _pad[420];
+} _packed_ GptHeader;
+assert_cc(sizeof(GptHeader) == 512);
 
 static EFI_DEVICE_PATH *path_replace_hd(
                 const EFI_DEVICE_PATH *path,
@@ -27,7 +44,7 @@ static EFI_DEVICE_PATH *path_replace_hd(
         if (new_node)
                 new_node_len = DevicePathNodeLength(&new_node->Header);
 
-        EFI_DEVICE_PATH *ret = xmalloc(len + new_node_len + END_DEVICE_PATH_LENGTH);
+        EFI_DEVICE_PATH *ret = xmalloc(len + new_node_len + sizeof(EFI_DEVICE_PATH));
         EFI_DEVICE_PATH *end = mempcpy(ret, path, len);
 
         if (new_node)
@@ -37,14 +54,11 @@ static EFI_DEVICE_PATH *path_replace_hd(
         return ret;
 }
 
-static bool verify_gpt(union GptHeaderBuffer *gpt_header_buffer, EFI_LBA lba_expected) {
-        EFI_PARTITION_TABLE_HEADER *h;
+static bool verify_gpt(/*const*/ GptHeader *h, EFI_LBA lba_expected) {
         uint32_t crc32, crc32_saved;
         EFI_STATUS err;
 
-        assert(gpt_header_buffer);
-
-        h = &gpt_header_buffer->gpt_header;
+        assert(h);
 
         /* Some superficial validation of the GPT header */
         if (memcmp(&h->Header.Signature, "EFI PART", sizeof(h->Header.Signature)) != 0)
@@ -59,7 +73,7 @@ static bool verify_gpt(union GptHeaderBuffer *gpt_header_buffer, EFI_LBA lba_exp
         /* Calculate CRC check */
         crc32_saved = h->Header.CRC32;
         h->Header.CRC32 = 0;
-        err = BS->CalculateCrc32(gpt_header_buffer, h->Header.HeaderSize, &crc32);
+        err = BS->CalculateCrc32(h, h->Header.HeaderSize, &crc32);
         h->Header.CRC32 = crc32_saved;
         if (err != EFI_SUCCESS || crc32 != crc32_saved)
                 return false;
@@ -88,7 +102,7 @@ static EFI_STATUS try_gpt(
                 HARDDRIVE_DEVICE_PATH *ret_hd) {
 
         _cleanup_free_ EFI_PARTITION_ENTRY *entries = NULL;
-        union GptHeaderBuffer gpt;
+        GptHeader gpt;
         EFI_STATUS err;
         uint32_t crc32;
         size_t size;
@@ -107,32 +121,32 @@ static EFI_STATUS try_gpt(
 
         /* Indicate the location of backup LBA even if the rest of the header is corrupt. */
         if (ret_backup_lba)
-                *ret_backup_lba = gpt.gpt_header.AlternateLBA;
+                *ret_backup_lba = gpt.AlternateLBA;
 
         if (!verify_gpt(&gpt, lba))
                 return EFI_NOT_FOUND;
 
         /* Now load the GPT entry table */
-        size = ALIGN_TO((size_t) gpt.gpt_header.SizeOfPartitionEntry * (size_t) gpt.gpt_header.NumberOfPartitionEntries, 512);
+        size = ALIGN_TO((size_t) gpt.SizeOfPartitionEntry * (size_t) gpt.NumberOfPartitionEntries, 512);
         entries = xmalloc(size);
 
         err = block_io->ReadBlocks(
                         block_io,
                         block_io->Media->MediaId,
-                        gpt.gpt_header.PartitionEntryLBA,
+                        gpt.PartitionEntryLBA,
                         size, entries);
         if (err != EFI_SUCCESS)
                 return err;
 
         /* Calculate CRC of entries array, too */
         err = BS->CalculateCrc32(entries, size, &crc32);
-        if (err != EFI_SUCCESS || crc32 != gpt.gpt_header.PartitionEntryArrayCRC32)
+        if (err != EFI_SUCCESS || crc32 != gpt.PartitionEntryArrayCRC32)
                 return EFI_CRC_ERROR;
 
         /* Now we can finally look for xbootloader partitions. */
-        for (size_t i = 0; i < gpt.gpt_header.NumberOfPartitionEntries; i++) {
+        for (size_t i = 0; i < gpt.NumberOfPartitionEntries; i++) {
                 EFI_PARTITION_ENTRY *entry =
-                                (EFI_PARTITION_ENTRY *) ((uint8_t *) entries + gpt.gpt_header.SizeOfPartitionEntry * i);
+                                (EFI_PARTITION_ENTRY *) ((uint8_t *) entries + gpt.SizeOfPartitionEntry * i);
 
                 if (!efi_guid_equal(&entry->PartitionTypeGUID, type))
                         continue;
@@ -144,6 +158,7 @@ static EFI_STATUS try_gpt(
                         .Header = {
                                 .Type = MEDIA_DEVICE_PATH,
                                 .SubType = MEDIA_HARDDRIVE_DP,
+                                .Length = sizeof(HARDDRIVE_DEVICE_PATH),
                         },
                         .PartitionNumber = i + 1,
                         .PartitionStart = entry->StartingLBA,
@@ -153,11 +168,6 @@ static EFI_STATUS try_gpt(
                 };
                 memcpy(ret_hd->Signature, &entry->UniquePartitionGUID, sizeof(ret_hd->Signature));
 
-                /* HARDDRIVE_DEVICE_PATH has padding, which at least OVMF does not like. */
-                SetDevicePathNodeLength(
-                                &ret_hd->Header,
-                                offsetof(HARDDRIVE_DEVICE_PATH, SignatureType) + sizeof(ret_hd->SignatureType));
-
                 return EFI_SUCCESS;
         }
 
index 18d34ec7f8c2b53ba4e568ae775971429a65b0fa..597ded3b3ea30d60b346b92949df972feadab147 100644 (file)
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <efi.h>
+#include "efi.h"
 
 #define XBOOTLDR_GUID \
         { 0xbc13c2ff, 0x59e6, 0x4262, { 0xa3, 0x52, 0xb2, 0x75, 0xfd, 0x6f, 0x71, 0x72 } }
index c946ce2b0ace12781757f4dfb2efc94327ba6d4c..5128eeecb5674597d96dd2de1b63004c0aefbe6f 100644 (file)
@@ -1,9 +1,5 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <efi.h>
-#include <efilib.h>
-
-#include "missing_efi.h"
 #include "pe.h"
 #include "util.h"
 
 #define MAX_SECTIONS 96
 
 #if defined(__i386__)
-#  define TARGET_MACHINE_TYPE EFI_IMAGE_MACHINE_IA32
-#  define TARGET_MACHINE_TYPE_COMPATIBILITY EFI_IMAGE_MACHINE_X64
+#  define TARGET_MACHINE_TYPE 0x014CU
+#  define TARGET_MACHINE_TYPE_COMPATIBILITY 0x8664U
 #elif defined(__x86_64__)
-#  define TARGET_MACHINE_TYPE EFI_IMAGE_MACHINE_X64
+#  define TARGET_MACHINE_TYPE 0x8664U
 #elif defined(__aarch64__)
-#  define TARGET_MACHINE_TYPE EFI_IMAGE_MACHINE_AARCH64
+#  define TARGET_MACHINE_TYPE 0xAA64U
 #elif defined(__arm__)
-#  define TARGET_MACHINE_TYPE EFI_IMAGE_MACHINE_ARMTHUMB_MIXED
+#  define TARGET_MACHINE_TYPE 0x01C2U
 #elif defined(__riscv) && __riscv_xlen == 64
-#  define TARGET_MACHINE_TYPE EFI_IMAGE_MACHINE_RISCV64
+#  define TARGET_MACHINE_TYPE 0x5064U
 #else
 #  error Unknown EFI arch
 #endif
index 99dcbb3a1b432278e04c1f2677dd5c4b16585170..7e2258fceb970c6d4e860988566b46b9a269cfaf 100644 (file)
@@ -1,8 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <efidef.h>
-#include <uchar.h>
+#include "efi.h"
 
 EFI_STATUS pe_memory_locate_sections(
                 const void *base,
diff --git a/src/boot/efi/proto/block-io.h b/src/boot/efi/proto/block-io.h
new file mode 100644 (file)
index 0000000..e977f70
--- /dev/null
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "efi.h"
+
+#define EFI_BLOCK_IO_PROTOCOL_GUID \
+        GUID_DEF(0x0964e5b21, 0x6459, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
+
+typedef struct EFI_BLOCK_IO_PROTOCOL EFI_BLOCK_IO_PROTOCOL;
+struct EFI_BLOCK_IO_PROTOCOL {
+        uint64_t Revision;
+        struct {
+                uint32_t MediaId;
+                bool RemovableMedia;
+                bool MediaPresent;
+                bool LogicalPartition;
+                bool ReadOnly;
+                bool WriteCaching;
+                uint32_t BlockSize;
+                uint32_t IoAlign;
+                EFI_LBA LastBlock;
+                EFI_LBA LowestAlignedLba;
+                uint32_t LogicalBlocksPerPhysicalBlock;
+                uint32_t OptimalTransferLengthGranularity;
+        } *Media;
+
+        EFI_STATUS (EFIAPI *Reset)(
+                        EFI_BLOCK_IO_PROTOCOL *This,
+                        bool ExtendedVerification);
+        EFI_STATUS (EFIAPI *ReadBlocks)(
+                        EFI_BLOCK_IO_PROTOCOL *This,
+                        uint32_t MediaId,
+                        EFI_LBA LBA,
+                        size_t BufferSize,
+                        void *Buffer);
+        EFI_STATUS (EFIAPI *WriteBlocks)(
+                        EFI_BLOCK_IO_PROTOCOL *This,
+                        uint32_t MediaId,
+                        EFI_LBA LBA,
+                        size_t BufferSize,
+                        void *Buffer);
+        EFI_STATUS (EFIAPI *FlushBlocks)(EFI_BLOCK_IO_PROTOCOL *This);
+};
diff --git a/src/boot/efi/proto/console-control.h b/src/boot/efi/proto/console-control.h
new file mode 100644 (file)
index 0000000..d3a92ea
--- /dev/null
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "efi.h"
+
+#define EFI_CONSOLE_CONTROL_PROTOCOL_GUID \
+        GUID_DEF(0xf42f7782, 0x12e, 0x4c12, 0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21)
+
+typedef enum {
+        EfiConsoleControlScreenText,
+        EfiConsoleControlScreenGraphics,
+        EfiConsoleControlScreenMaxValue,
+} EFI_CONSOLE_CONTROL_SCREEN_MODE;
+
+typedef struct EFI_CONSOLE_CONTROL_PROTOCOL EFI_CONSOLE_CONTROL_PROTOCOL;
+struct EFI_CONSOLE_CONTROL_PROTOCOL {
+        EFI_STATUS (EFIAPI *GetMode)(
+                        EFI_CONSOLE_CONTROL_PROTOCOL *This,
+                        EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode,
+                        bool *UgaExists,
+                        bool *StdInLocked);
+        EFI_STATUS (EFIAPI *SetMode)(
+                        EFI_CONSOLE_CONTROL_PROTOCOL *This,
+                        EFI_CONSOLE_CONTROL_SCREEN_MODE Mode);
+        EFI_STATUS(EFIAPI *LockStdIn)(
+                        EFI_CONSOLE_CONTROL_PROTOCOL *This,
+                        char16_t *Password);
+};
diff --git a/src/boot/efi/proto/device-path.h b/src/boot/efi/proto/device-path.h
new file mode 100644 (file)
index 0000000..8d8bd0c
--- /dev/null
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "efi.h"
+
+#define EFI_DEVICE_PATH_PROTOCOL_GUID \
+        GUID_DEF(0x09576e91, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
+#define EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID \
+        GUID_DEF(0x8b843e20, 0x8132, 0x4852, 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c)
+#define EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID \
+        GUID_DEF(0x05c99a21, 0xc70f, 0x4ad2, 0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e)
+
+/* Device path types. */
+enum {
+        HARDWARE_DEVICE_PATH  = 0x01,
+        ACPI_DEVICE_PATH      = 0x02,
+        MESSAGING_DEVICE_PATH = 0x03,
+        MEDIA_DEVICE_PATH     = 0x04,
+        BBS_DEVICE_PATH       = 0x05,
+        END_DEVICE_PATH_TYPE  = 0x7f,
+};
+
+/* Device path sub-types. */
+enum {
+        END_INSTANCE_DEVICE_PATH_SUBTYPE = 0x01,
+        END_ENTIRE_DEVICE_PATH_SUBTYPE   = 0xff,
+
+        MEDIA_HARDDRIVE_DP               = 0x01,
+        MEDIA_VENDOR_DP                  = 0x03,
+        MEDIA_FILEPATH_DP                = 0x04,
+        MEDIA_PIWG_FW_FILE_DP            = 0x06,
+        MEDIA_PIWG_FW_VOL_DP             = 0x07,
+};
+
+struct _packed_ EFI_DEVICE_PATH_PROTOCOL {
+        uint8_t Type;
+        uint8_t SubType;
+        uint16_t Length;
+};
+
+typedef struct {
+        EFI_DEVICE_PATH Header;
+        EFI_GUID Guid;
+} _packed_ VENDOR_DEVICE_PATH;
+
+#define MBR_TYPE_PCAT                        0x01U
+#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER  0x02U
+#define NO_DISK_SIGNATURE    0x00U
+#define SIGNATURE_TYPE_MBR   0x01U
+#define SIGNATURE_TYPE_GUID  0x02U
+
+typedef struct {
+        EFI_DEVICE_PATH Header;
+        uint32_t PartitionNumber;
+        uint64_t PartitionStart;
+        uint64_t PartitionSize;
+        uint8_t Signature[16];
+        uint8_t MBRType;
+        uint8_t SignatureType;
+} _packed_ HARDDRIVE_DEVICE_PATH;
+
+typedef struct {
+        EFI_DEVICE_PATH Header;
+        char16_t PathName[];
+} _packed_ FILEPATH_DEVICE_PATH;
+
+typedef struct {
+        char16_t* (EFIAPI *ConvertDeviceNodeToText)(
+                        const EFI_DEVICE_PATH *DeviceNode,
+                        bool DisplayOnly,
+                        bool AllowShortcuts);
+        char16_t* (EFIAPI *ConvertDevicePathToText)(
+                        const EFI_DEVICE_PATH *DevicePath,
+                        bool DisplayOnly,
+                        bool AllowShortcuts);
+} EFI_DEVICE_PATH_TO_TEXT_PROTOCOL;
+
+typedef struct {
+        EFI_DEVICE_PATH* (EFIAPI *ConvertTextToDevicNode)(
+                        const char16_t *TextDeviceNode);
+        EFI_DEVICE_PATH* (EFIAPI *ConvertTextToDevicPath)(
+                        const char16_t *ConvertTextToDevicPath);
+} EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL;
+
+#define DevicePathType(dp) ((dp)->Type)
+#define DevicePathSubType(dp) ((dp)->SubType)
+#define DevicePathNodeLength(dp) ((dp)->Length)
+
+static inline EFI_DEVICE_PATH *NextDevicePathNode(const EFI_DEVICE_PATH *dp) {
+        assert(dp);
+        return (EFI_DEVICE_PATH *) ((uint8_t *) dp + dp->Length);
+}
+
+static inline bool IsDevicePathEnd(const EFI_DEVICE_PATH *dp) {
+        assert(dp);
+        return dp->Type == END_DEVICE_PATH_TYPE && dp->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE;
+}
+
+static inline void SetDevicePathEndNode(EFI_DEVICE_PATH *dp) {
+        assert(dp);
+        dp->Type = END_DEVICE_PATH_TYPE;
+        dp->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
+        dp->Length = sizeof(EFI_DEVICE_PATH);
+}
diff --git a/src/boot/efi/proto/dt-fixup.h b/src/boot/efi/proto/dt-fixup.h
new file mode 100644 (file)
index 0000000..6edbef5
--- /dev/null
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "efi.h"
+
+#define EFI_DTB_TABLE_GUID \
+        GUID_DEF(0xb1b621d5, 0xf19c, 0x41a5, 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0)
+#define EFI_DT_FIXUP_PROTOCOL_GUID \
+        GUID_DEF(0xe617d64c, 0xfe08, 0x46da, 0xf4, 0xdc, 0xbb, 0xd5, 0x87, 0x0c, 0x73, 0x00)
+
+#define EFI_DT_FIXUP_PROTOCOL_REVISION 0x00010000
+
+/* Add nodes and update properties */
+#define EFI_DT_APPLY_FIXUPS 0x00000001
+
+/*
+ * Reserve memory according to the /reserved-memory node
+ * and the memory reservation block
+ */
+#define EFI_DT_RESERVE_MEMORY 0x00000002
+
+typedef struct EFI_DT_FIXUP_PROTOCOL EFI_DT_FIXUP_PROTOCOL;
+struct EFI_DT_FIXUP_PROTOCOL {
+        uint64_t Revision;
+        EFI_STATUS (EFIAPI *Fixup)(
+                EFI_DT_FIXUP_PROTOCOL *This,
+                void *Fdt,
+                size_t *BufferSize,
+                uint32_t Flags);
+};
diff --git a/src/boot/efi/proto/file-io.h b/src/boot/efi/proto/file-io.h
new file mode 100644 (file)
index 0000000..106c267
--- /dev/null
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "efi.h"
+
+#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \
+        GUID_DEF(0x0964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
+#define EFI_FILE_INFO_ID \
+        GUID_DEF(0x009576e92, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
+
+#define EFI_FILE_MODE_READ   0x0000000000000001U
+#define EFI_FILE_MODE_WRITE  0x0000000000000002U
+#define EFI_FILE_MODE_CREATE 0x8000000000000000U
+
+#define EFI_FILE_READ_ONLY  0x01U
+#define EFI_FILE_HIDDEN     0x02U
+#define EFI_FILE_SYSTEM     0x04U
+#define EFI_FILE_RESERVED   0x08U
+#define EFI_FILE_DIRECTORY  0x10U
+#define EFI_FILE_ARCHIVE    0x20U
+#define EFI_FILE_VALID_ATTR 0x37U
+
+typedef struct {
+        uint64_t Size;
+        uint64_t FileSize;
+        uint64_t PhysicalSize;
+        EFI_TIME CreateTime;
+        EFI_TIME LastAccessTime;
+        EFI_TIME ModificationTime;
+        uint64_t Attribute;
+        char16_t FileName[];
+} EFI_FILE_INFO;
+
+typedef struct EFI_SIMPLE_FILE_SYSTEM_PROTOCOL EFI_SIMPLE_FILE_SYSTEM_PROTOCOL;
+struct EFI_SIMPLE_FILE_SYSTEM_PROTOCOL {
+        uint64_t Revision;
+        EFI_STATUS (EFIAPI *OpenVolume)(
+                        EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
+                        EFI_FILE **Root);
+};
+
+struct EFI_FILE_PROTOCOL {
+        uint64_t Revision;
+        EFI_STATUS (EFIAPI *Open)(
+                        EFI_FILE *This,
+                        EFI_FILE **NewHandle,
+                        char16_t *FileName,
+                        uint64_t OpenMode,
+                        uint64_t Attributes);
+        EFI_STATUS (EFIAPI *Close)(EFI_FILE *This);
+        EFI_STATUS (EFIAPI *Delete)(EFI_FILE *This);
+        EFI_STATUS (EFIAPI *Read)(
+                        EFI_FILE *This,
+                        size_t *BufferSize,
+                        void *Buffer);
+        EFI_STATUS (EFIAPI *Write)(
+                        EFI_FILE *This,
+                        size_t *BufferSize,
+                        void *Buffer);
+        EFI_STATUS (EFIAPI *GetPosition)(EFI_FILE *This, uint64_t *Position);
+        EFI_STATUS (EFIAPI *SetPosition)(EFI_FILE *This, uint64_t Position);
+        EFI_STATUS (EFIAPI *GetInfo)(
+                        EFI_FILE *This,
+                        EFI_GUID *InformationType,
+                        size_t *BufferSize,
+                        void *Buffer);
+        EFI_STATUS (EFIAPI *SetInfo)(
+                        EFI_FILE *This,
+                        EFI_GUID *InformationType,
+                        size_t BufferSize,
+                        void *Buffer);
+        EFI_STATUS (EFIAPI *Flush)(EFI_FILE *This);
+        void *OpenEx;
+        void *ReadEx;
+        void *WriteEx;
+        void *FlushEx;
+};
diff --git a/src/boot/efi/proto/graphics-output.h b/src/boot/efi/proto/graphics-output.h
new file mode 100644 (file)
index 0000000..f49e580
--- /dev/null
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "efi.h"
+
+#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \
+        GUID_DEF(0x9042a9de, 0x23dc, 0x4a38, 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a)
+
+typedef enum {
+        PixelRedGreenBlueReserved8BitPerColor,
+        PixelBlueGreenRedReserved8BitPerColor,
+        PixelBitMask,
+        PixelBltOnly,
+        PixelFormatMax,
+} EFI_GRAPHICS_PIXEL_FORMAT;
+
+typedef enum {
+        EfiBltVideoFill,
+        EfiBltVideoToBltBuffer,
+        EfiBltBufferToVideo,
+        EfiBltVideoToVideo,
+        EfiGraphicsOutputBltOperationMax,
+} EFI_GRAPHICS_OUTPUT_BLT_OPERATION;
+
+typedef struct {
+        uint32_t RedMask;
+        uint32_t GreenMask;
+        uint32_t BlueMask;
+        uint32_t ReservedMask;
+} EFI_PIXEL_BITMASK;
+
+typedef struct {
+        uint8_t Blue;
+        uint8_t Green;
+        uint8_t Red;
+        uint8_t Reserved;
+} EFI_GRAPHICS_OUTPUT_BLT_PIXEL;
+
+typedef struct {
+        uint32_t Version;
+        uint32_t HorizontalResolution;
+        uint32_t VerticalResolution;
+        EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
+        EFI_PIXEL_BITMASK PixelInformation;
+        uint32_t PixelsPerScanLine;
+} EFI_GRAPHICS_OUTPUT_MODE_INFORMATION;
+
+typedef struct EFI_GRAPHICS_OUTPUT_PROTOCOL EFI_GRAPHICS_OUTPUT_PROTOCOL;
+struct EFI_GRAPHICS_OUTPUT_PROTOCOL {
+        EFI_STATUS (EFIAPI *QueryMode)(
+                        EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+                        uint32_t ModeNumber,
+                        size_t *SizeOfInfo,
+                        EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info);
+        EFI_STATUS(EFIAPI *SetMode)(
+                        EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+                        uint32_t ModeNumber);
+        EFI_STATUS (EFIAPI *Blt)(
+                        EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+                        EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
+                        EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
+                        size_t SourceX,
+                        size_t SourceY,
+                        size_t DestinationX,
+                        size_t DestinationY,
+                        size_t Width,
+                        size_t Height,
+                        size_t Delta);
+
+        struct {
+                uint32_t MaxMode;
+                uint32_t Mode;
+                EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
+                size_t SizeOfInfo;
+                EFI_PHYSICAL_ADDRESS FrameBufferBase;
+                size_t FrameBufferSize;
+        } *Mode;
+};
diff --git a/src/boot/efi/proto/load-file.h b/src/boot/efi/proto/load-file.h
new file mode 100644 (file)
index 0000000..2e01ce5
--- /dev/null
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "efi.h"
+
+#define EFI_LOAD_FILE_PROTOCOL_GUID \
+        GUID_DEF(0x56EC3091, 0x954C, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
+#define EFI_LOAD_FILE2_PROTOCOL_GUID \
+        GUID_DEF(0x4006c0c1, 0xfcb3, 0x403e, 0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d)
+
+typedef struct EFI_LOAD_FILE_PROTOCOL EFI_LOAD_FILE_PROTOCOL;
+typedef EFI_LOAD_FILE_PROTOCOL EFI_LOAD_FILE2_PROTOCOL;
+
+struct EFI_LOAD_FILE_PROTOCOL {
+        EFI_STATUS (EFIAPI *LoadFile)(
+                        EFI_LOAD_FILE_PROTOCOL *This,
+                        EFI_DEVICE_PATH *FilePath,
+                        bool BootPolicy,
+                        size_t *BufferSize,
+                        void *Buffer);
+};
diff --git a/src/boot/efi/proto/loaded-image.h b/src/boot/efi/proto/loaded-image.h
new file mode 100644 (file)
index 0000000..46371e7
--- /dev/null
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "efi.h"
+
+#define EFI_LOADED_IMAGE_PROTOCOL_GUID \
+        GUID_DEF(0x5B1B31A1, 0x9562, 0x11d2, 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B)
+#define EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID \
+        GUID_DEF(0xbc62157e, 0x3e33, 0x4fec, 0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf)
+
+typedef EFI_STATUS (EFIAPI *EFI_IMAGE_ENTRY_POINT)(
+        EFI_HANDLE ImageHandle,
+        EFI_SYSTEM_TABLE *SystemTable);
+
+typedef struct {
+        uint32_t Revision;
+        EFI_HANDLE ParentHandle;
+        EFI_SYSTEM_TABLE *SystemTable;
+        EFI_HANDLE DeviceHandle;
+        EFI_DEVICE_PATH *FilePath;
+        void *Reserved;
+        uint32_t LoadOptionsSize;
+        void *LoadOptions;
+        void *ImageBase;
+        uint64_t ImageSize;
+        EFI_MEMORY_TYPE ImageCodeType;
+        EFI_MEMORY_TYPE ImageDataType;
+        EFI_STATUS (EFIAPI *Unload)(EFI_HANDLE ImageHandle);
+} EFI_LOADED_IMAGE_PROTOCOL;
diff --git a/src/boot/efi/proto/rng.h b/src/boot/efi/proto/rng.h
new file mode 100644 (file)
index 0000000..8ed1fd4
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "efi.h"
+
+#define EFI_RNG_PROTOCOL_GUID \
+        GUID_DEF(0x3152bca5, 0xeade, 0x433d, 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44)
+
+typedef struct EFI_RNG_PROTOCOL EFI_RNG_PROTOCOL;
+struct EFI_RNG_PROTOCOL {
+        EFI_STATUS (EFIAPI *GetInfo)(
+                        EFI_RNG_PROTOCOL *This,
+                        size_t *RNGAlgorithmListSize,
+                        EFI_GUID *RNGAlgorithmList);
+        EFI_STATUS (EFIAPI *GetRNG)(
+                        EFI_RNG_PROTOCOL *This,
+                        EFI_GUID *RNGAlgorithm,
+                        size_t RNGValueLength,
+                        uint8_t *RNGValue);
+};
diff --git a/src/boot/efi/proto/security-arch.h b/src/boot/efi/proto/security-arch.h
new file mode 100644 (file)
index 0000000..2675c61
--- /dev/null
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "efi.h"
+
+#define EFI_SECURITY_ARCH_PROTOCOL_GUID \
+        GUID_DEF(0xA46423E3, 0x4617, 0x49f1, 0xB9, 0xFF, 0xD1, 0xBF, 0xA9, 0x11, 0x58, 0x39)
+#define EFI_SECURITY2_ARCH_PROTOCOL_GUID \
+        GUID_DEF(0x94ab2f58, 0x1438, 0x4ef1, 0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68)
+
+typedef struct EFI_SECURITY_ARCH_PROTOCOL EFI_SECURITY_ARCH_PROTOCOL;
+typedef struct EFI_SECURITY2_ARCH_PROTOCOL EFI_SECURITY2_ARCH_PROTOCOL;
+
+typedef EFI_STATUS (EFIAPI *EFI_SECURITY_FILE_AUTHENTICATION_STATE)(
+                const EFI_SECURITY_ARCH_PROTOCOL *This,
+                uint32_t AuthenticationStatus,
+                const EFI_DEVICE_PATH *File);
+
+typedef EFI_STATUS (EFIAPI *EFI_SECURITY2_FILE_AUTHENTICATION)(
+                const EFI_SECURITY2_ARCH_PROTOCOL *This,
+                const EFI_DEVICE_PATH *DevicePath,
+                void *FileBuffer,
+                size_t FileSize,
+                bool BootPolicy);
+
+struct EFI_SECURITY_ARCH_PROTOCOL {
+        EFI_SECURITY_FILE_AUTHENTICATION_STATE FileAuthenticationState;
+};
+
+struct EFI_SECURITY2_ARCH_PROTOCOL {
+        EFI_SECURITY2_FILE_AUTHENTICATION FileAuthentication;
+};
diff --git a/src/boot/efi/proto/shell-parameters.h b/src/boot/efi/proto/shell-parameters.h
new file mode 100644 (file)
index 0000000..8080922
--- /dev/null
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "efi.h"
+
+#define EFI_SHELL_PARAMETERS_PROTOCOL_GUID \
+        GUID_DEF(0x752f3136, 0x4e16, 0x4fdc, 0xa2, 0x2a, 0xe5, 0xf4, 0x68, 0x12, 0xf4, 0xca)
+
+typedef struct {
+        char16_t **Argv;
+        size_t Argc;
+        void *StdIn;
+        void *StdOut;
+        void *StdErr;
+} EFI_SHELL_PARAMETERS_PROTOCOL;
diff --git a/src/boot/efi/proto/simple-text-io.h b/src/boot/efi/proto/simple-text-io.h
new file mode 100644 (file)
index 0000000..95016d3
--- /dev/null
@@ -0,0 +1,182 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "efi.h"
+
+#define EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \
+        GUID_DEF(0x387477c1, 0x69c7, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
+#define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \
+        GUID_DEF(0xdd9e7534, 0x7762, 0x4698, 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa)
+#define EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID \
+        GUID_DEF(0x387477c2, 0x69c7, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
+
+#define EFI_SHIFT_STATE_VALID     0x80000000U
+#define EFI_RIGHT_SHIFT_PRESSED   0x00000001U
+#define EFI_LEFT_SHIFT_PRESSED    0x00000002U
+#define EFI_RIGHT_CONTROL_PRESSED 0x00000004U
+#define EFI_LEFT_CONTROL_PRESSED  0x00000008U
+#define EFI_RIGHT_ALT_PRESSED     0x00000010U
+#define EFI_LEFT_ALT_PRESSED      0x00000020U
+#define EFI_RIGHT_LOGO_PRESSED    0x00000040U
+#define EFI_LEFT_LOGO_PRESSED     0x00000080U
+#define EFI_MENU_KEY_PRESSED      0x00000100U
+#define EFI_SYS_REQ_PRESSED       0x00000200U
+
+#define EFI_TOGGLE_STATE_VALID 0x80U
+#define EFI_KEY_STATE_EXPOSED  0x40U
+#define EFI_SCROLL_LOCK_ACTIVE 0x01U
+#define EFI_NUM_LOCK_ACTIVE    0x02U
+#define EFI_CAPS_LOCK_ACTIVE   0x04U
+
+enum {
+        EFI_BLACK        = 0x00,
+        EFI_BLUE         = 0x01,
+        EFI_GREEN        = 0x02,
+        EFI_CYAN         = EFI_BLUE | EFI_GREEN,
+        EFI_RED          = 0x04,
+        EFI_MAGENTA      = EFI_BLUE | EFI_RED,
+        EFI_BROWN        = EFI_GREEN | EFI_RED,
+        EFI_LIGHTGRAY    = EFI_BLUE | EFI_GREEN | EFI_RED,
+        EFI_BRIGHT       = 0x08,
+        EFI_DARKGRAY     = EFI_BLACK | EFI_BRIGHT,
+        EFI_LIGHTBLUE    = EFI_BLUE | EFI_BRIGHT,
+        EFI_LIGHTGREEN   = EFI_GREEN | EFI_BRIGHT,
+        EFI_LIGHTCYAN    = EFI_CYAN | EFI_BRIGHT,
+        EFI_LIGHTRED     = EFI_RED | EFI_BRIGHT,
+        EFI_LIGHTMAGENTA = EFI_MAGENTA | EFI_BRIGHT,
+        EFI_YELLOW       = EFI_BROWN | EFI_BRIGHT,
+        EFI_WHITE        = EFI_BLUE | EFI_GREEN | EFI_RED | EFI_BRIGHT,
+};
+
+#define EFI_TEXT_ATTR(fg, bg) ((fg) | ((bg) << 4))
+#define EFI_TEXT_ATTR_SWAP(c) EFI_TEXT_ATTR(((c) & 0xF0U) >> 4, (c) & 0xFU)
+
+enum {
+        SCAN_NULL            = 0x000,
+        SCAN_UP              = 0x001,
+        SCAN_DOWN            = 0x002,
+        SCAN_RIGHT           = 0x003,
+        SCAN_LEFT            = 0x004,
+        SCAN_HOME            = 0x005,
+        SCAN_END             = 0x006,
+        SCAN_INSERT          = 0x007,
+        SCAN_DELETE          = 0x008,
+        SCAN_PAGE_UP         = 0x009,
+        SCAN_PAGE_DOWN       = 0x00A,
+        SCAN_F1              = 0x00B,
+        SCAN_F2              = 0x00C,
+        SCAN_F3              = 0x00D,
+        SCAN_F4              = 0x00E,
+        SCAN_F5              = 0x00F,
+        SCAN_F6              = 0x010,
+        SCAN_F7              = 0x011,
+        SCAN_F8              = 0x012,
+        SCAN_F9              = 0x013,
+        SCAN_F10             = 0x014,
+        SCAN_F11             = 0x015,
+        SCAN_F12             = 0x016,
+        SCAN_ESC             = 0x017,
+        SCAN_PAUSE           = 0x048,
+        SCAN_F13             = 0x068,
+        SCAN_F14             = 0x069,
+        SCAN_F15             = 0x06A,
+        SCAN_F16             = 0x06B,
+        SCAN_F17             = 0x06C,
+        SCAN_F18             = 0x06D,
+        SCAN_F19             = 0x06E,
+        SCAN_F20             = 0x06F,
+        SCAN_F21             = 0x070,
+        SCAN_F22             = 0x071,
+        SCAN_F23             = 0x072,
+        SCAN_F24             = 0x073,
+        SCAN_MUTE            = 0x07F,
+        SCAN_VOLUME_UP       = 0x080,
+        SCAN_VOLUME_DOWN     = 0x081,
+        SCAN_BRIGHTNESS_UP   = 0x100,
+        SCAN_BRIGHTNESS_DOWN = 0x101,
+        SCAN_SUSPEND         = 0x102,
+        SCAN_HIBERNATE       = 0x103,
+        SCAN_TOGGLE_DISPLAY  = 0x104,
+        SCAN_RECOVERY        = 0x105,
+        SCAN_EJECT           = 0x106,
+};
+
+typedef struct {
+        uint16_t ScanCode;
+        char16_t UnicodeChar;
+} EFI_INPUT_KEY;
+
+typedef struct {
+        uint32_t KeyShiftState;
+        uint8_t KeyToggleState;
+} EFI_KEY_STATE;
+
+typedef struct {
+        EFI_INPUT_KEY Key;
+        EFI_KEY_STATE KeyState;
+} EFI_KEY_DATA;
+
+struct EFI_SIMPLE_TEXT_INPUT_PROTOCOL {
+        EFI_STATUS (EFIAPI *Reset)(
+                        EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+                        bool ExtendedVerification);
+        EFI_STATUS (EFIAPI *ReadKeyStroke)(
+                        EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+                        EFI_INPUT_KEY *Key);
+        EFI_EVENT WaitForKey;
+};
+
+typedef struct EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL;
+struct EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL {
+        EFI_STATUS (EFIAPI *Reset)(
+                        EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+                        bool ExtendedVerification);
+        EFI_STATUS (EFIAPI *ReadKeyStrokeEx)(
+                        EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+                        EFI_KEY_DATA *KeyData);
+        EFI_EVENT WaitForKeyEx;
+        void *SetState;
+        void *RegisterKeyNotify;
+        void *UnregisterKeyNotify;
+};
+
+typedef struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
+struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL {
+        EFI_STATUS (EFIAPI *Reset)(
+                        EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+                        bool ExtendedVerification);
+        EFI_STATUS (EFIAPI *OutputString)(
+                        EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+                        char16_t *String);
+        EFI_STATUS (EFIAPI *TestString)(
+                        EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+                        char16_t *String);
+        EFI_STATUS (EFIAPI *QueryMode)(
+                        EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+                        size_t ModeNumber,
+                        size_t *Columns,
+                        size_t *Rows);
+        EFI_STATUS (EFIAPI *SetMode)(
+                        EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+                        size_t ModeNumber);
+        EFI_STATUS (EFIAPI *SetAttribute)(
+                        EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+                        size_t Attribute);
+        EFI_STATUS (EFIAPI *ClearScreen)(
+                        EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This);
+        EFI_STATUS (EFIAPI *SetCursorPosition)(
+                        EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+                        size_t Column,
+                        size_t Row);
+        EFI_STATUS (EFIAPI *EnableCursor)(
+                        EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+                        bool Visible);
+        struct {
+                int32_t MaxMode;
+                int32_t Mode;
+                int32_t Attribute;
+                int32_t CursorColumn;
+                int32_t CursorRow;
+                bool CursorVisible;
+        } *Mode;
+};
diff --git a/src/boot/efi/proto/tcg.h b/src/boot/efi/proto/tcg.h
new file mode 100644 (file)
index 0000000..af6989c
--- /dev/null
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "efi.h"
+
+#define EFI_TCG_PROTOCOL_GUID \
+        GUID_DEF(0xf541796d, 0xa62e, 0x4954, 0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd)
+#define EFI_TCG2_PROTOCOL_GUID \
+        GUID_DEF(0x607f766c, 0x7455, 0x42be, 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f)
+
+#define TCG_ALG_SHA 0x4
+#define EFI_TCG2_EVENT_HEADER_VERSION 1
+#define EV_IPL 13
+
+typedef struct {
+        uint8_t Major;
+        uint8_t Minor;
+        uint8_t RevMajor;
+        uint8_t RevMinor;
+} TCG_VERSION;
+
+typedef struct {
+        uint8_t Major;
+        uint8_t Minor;
+} EFI_TCG2_VERSION;
+
+typedef struct {
+        uint8_t Size;
+        TCG_VERSION StructureVersion;
+        TCG_VERSION ProtocolSpecVersion;
+        uint8_t HashAlgorithmBitmap;
+        bool TPMPresentFlag;
+        bool TPMDeactivatedFlag;
+} EFI_TCG_BOOT_SERVICE_CAPABILITY;
+
+typedef struct {
+        uint8_t Size;
+        EFI_TCG2_VERSION StructureVersion;
+        EFI_TCG2_VERSION ProtocolVersion;
+        uint32_t HashAlgorithmBitmap;
+        uint32_t SupportedEventLogs;
+        bool TPMPresentFlag;
+        uint16_t MaxCommandSize;
+        uint16_t MaxResponseSize;
+        uint32_t ManufacturerID;
+        uint32_t NumberOfPCRBanks;
+        uint32_t ActivePcrBanks;
+} EFI_TCG2_BOOT_SERVICE_CAPABILITY;
+
+typedef struct {
+        uint32_t PCRIndex;
+        uint32_t EventType;
+        struct {
+                uint8_t Digest[20];
+        } Digest;
+        uint32_t EventSize;
+        uint8_t Event[0];
+} _packed_ TCG_PCR_EVENT;
+
+typedef struct {
+        uint32_t HeaderSize;
+        uint16_t HeaderVersion;
+        uint32_t PCRIndex;
+        uint32_t EventType;
+} _packed_ EFI_TCG2_EVENT_HEADER;
+
+typedef struct {
+        uint32_t Size;
+        EFI_TCG2_EVENT_HEADER Header;
+        uint8_t Event[];
+} _packed_ EFI_TCG2_EVENT;
+
+typedef struct EFI_TCG_PROTOCOL EFI_TCG_PROTOCOL;
+struct EFI_TCG_PROTOCOL {
+        EFI_STATUS (EFIAPI *StatusCheck)(
+                        EFI_TCG_PROTOCOL *This,
+                        EFI_TCG_BOOT_SERVICE_CAPABILITY *ProtocolCapability,
+                        uint32_t *TCGFeatureFlags,
+                        EFI_PHYSICAL_ADDRESS *EventLogLocation,
+                        EFI_PHYSICAL_ADDRESS *EventLogLastEntry);
+        void *HashAll;
+        void *LogEvent;
+        void *PassThroughToTpm;
+        EFI_STATUS (EFIAPI *HashLogExtendEvent)(
+                        EFI_TCG_PROTOCOL *This,
+                        EFI_PHYSICAL_ADDRESS HashData,
+                        uint64_t HashDataLen,
+                        uint32_t AlgorithmId,
+                        TCG_PCR_EVENT *TCGLogData,
+                        uint32_t *EventNumber,
+                        EFI_PHYSICAL_ADDRESS *EventLogLastEntry);
+};
+
+typedef struct EFI_TCG2_PROTOCOL EFI_TCG2_PROTOCOL;
+struct EFI_TCG2_PROTOCOL {
+        EFI_STATUS (EFIAPI *GetCapability)(
+                        EFI_TCG2_PROTOCOL *This,
+                        EFI_TCG2_BOOT_SERVICE_CAPABILITY *ProtocolCapability);
+        void *GetEventLog;
+        EFI_STATUS (EFIAPI *HashLogExtendEvent)(
+                        EFI_TCG2_PROTOCOL *This,
+                        uint64_t Flags,
+                        EFI_PHYSICAL_ADDRESS DataToHash,
+                        uint64_t DataToHashLen,
+                        EFI_TCG2_EVENT *EfiTcgEvent);
+        void *SubmitCommand;
+        void *GetActivePcrBanks;
+        void *SetActivePcrBanks;
+        void *GetResultOfSetActivePcrBanks;
+};
index 0370de11479c44acb03cf8f7c5f4006d234a2953..8147e545e4b53822bc9ebf261b4f93b840346afb 100644 (file)
@@ -1,10 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <efi.h>
-#include <efilib.h>
-
 #include "memory-util-fundamental.h"
-#include "missing_efi.h"
+#include "proto/rng.h"
 #include "random-seed.h"
 #include "secure-boot.h"
 #include "sha256.h"
@@ -203,7 +200,7 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir) {
                 return err;
         }
 
-        err = get_file_info_harder(handle, &info, NULL);
+        err = get_file_info(handle, &info, NULL);
         if (err != EFI_SUCCESS)
                 return log_error_status(err, "Failed to get file info for random seed: %m");
 
index 40aaf85860f508492d3a4b9bd5740236813bf33e..67f005dff54f06a3bcd42c85b211e7ae397f70a3 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <efi.h>
+#include "efi.h"
 
 EFI_STATUS process_random_seed(EFI_FILE *root_dir);
index 8b796db65f95cc6e35b22b753b958e8cd1f367cd..3a80712fe0631af15792b3f883972021c591e4a8 100644 (file)
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
 #include "console.h"
+#include "proto/security-arch.h"
 #include "sbat.h"
 #include "secure-boot.h"
 #include "util.h"
@@ -93,7 +94,7 @@ EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path, bool
                 char *buffer;
                 size_t size;
         } sb_vars[] = {
-                { u"db",  u"db.auth",  EFI_IMAGE_SECURITY_DATABASE_VARIABLE, NULL, 0 },
+                { u"db",  u"db.auth",  EFI_IMAGE_SECURITY_DATABASE_GUID, NULL, 0 },
                 { u"KEK", u"KEK.auth", EFI_GLOBAL_VARIABLE, NULL, 0 },
                 { u"PK",  u"PK.auth",  EFI_GLOBAL_VARIABLE, NULL, 0 },
         };
@@ -164,7 +165,7 @@ static EFIAPI EFI_STATUS security2_hook(
                 const EFI_DEVICE_PATH *device_path,
                 void *file_buffer,
                 size_t file_size,
-                BOOLEAN boot_policy) {
+                bool boot_policy) {
 
         assert(security_override.validator);
         assert(security_override.security2);
index bdc34150da677e3ac8c5f4724870fa2149fed679..347113135ffb4ca67a17e890ebd9533ad5ecd496 100644 (file)
@@ -1,10 +1,8 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <efi.h>
-
+#include "efi.h"
 #include "efivars-fundamental.h"
-#include "missing_efi.h"
 
 typedef enum {
         ENROLL_OFF,         /* no Secure Boot key enrollment whatsoever, even manual entries are not generated */
index 5da298c10a686a6dafc18fda1480e70ba7e64cbf..e0bb470cf2b62a747ca2f73c62ae4d7a3b700258 100644 (file)
@@ -8,13 +8,9 @@
  * https://github.com/mjg59/efitools
  */
 
-#include <efi.h>
-#include <efilib.h>
-
-#include "missing_efi.h"
-#include "util.h"
 #include "secure-boot.h"
 #include "shim.h"
+#include "util.h"
 
 #if defined(__x86_64__) || defined(__i386__)
 #define __sysv_abi__ __attribute__((sysv_abi))
index 6d213f5efa718f47ec21c51a592d2a5def019b24..44155d21fc48ed1c46cd6abbb31bb648658c0834 100644 (file)
@@ -9,8 +9,7 @@
  */
 #pragma once
 
-#include <efi.h>
-#include <stdbool.h>
+#include "efi.h"
 
 bool shim_loaded(void);
 EFI_STATUS shim_load_image(EFI_HANDLE parent, const EFI_DEVICE_PATH *device_path, EFI_HANDLE *ret_image);
index 15518b692ab2a2face4f6930ee5d5fb6b88b31f5..f2d9f20e96854450e447d9190ffa93da771e1dcc 100644 (file)
@@ -1,10 +1,9 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <efi.h>
-#include <efilib.h>
-
 #include "graphics.h"
+#include "proto/graphics-output.h"
 #include "splash.h"
+#include "unaligned-fundamental.h"
 #include "util.h"
 
 struct bmp_file {
@@ -28,8 +27,16 @@ struct bmp_dib {
         int32_t y_pixel_meter;
         uint32_t colors_used;
         uint32_t colors_important;
+        uint32_t channel_mask_r;
+        uint32_t channel_mask_g;
+        uint32_t channel_mask_b;
+        uint32_t channel_mask_a;
 } _packed_;
 
+#define SIZEOF_BMP_DIB offsetof(struct bmp_dib, channel_mask_r)
+#define SIZEOF_BMP_DIB_RGB offsetof(struct bmp_dib, channel_mask_a)
+#define SIZEOF_BMP_DIB_RGBA sizeof(struct bmp_dib)
+
 struct bmp_map {
         uint8_t blue;
         uint8_t green;
@@ -49,7 +56,7 @@ static EFI_STATUS bmp_parse_header(
         assert(ret_map);
         assert(pixmap);
 
-        if (size < sizeof(struct bmp_file) + sizeof(struct bmp_dib))
+        if (size < sizeof(struct bmp_file) + SIZEOF_BMP_DIB)
                 return EFI_INVALID_PARAMETER;
 
         /* check file header */
@@ -63,7 +70,7 @@ static EFI_STATUS bmp_parse_header(
 
         /*  check device-independent bitmap */
         struct bmp_dib *dib = (struct bmp_dib *) (bmp + sizeof(struct bmp_file));
-        if (dib->size < sizeof(struct bmp_dib))
+        if (dib->size < SIZEOF_BMP_DIB)
                 return EFI_UNSUPPORTED;
 
         switch (dib->depth) {
@@ -127,22 +134,21 @@ static void read_channel_maks(
 
         assert(dib);
 
-        if (IN_SET(dib->depth, 16, 32) && dib->size >= sizeof(*dib) + 3 * sizeof(uint32_t)) {
-                uint32_t *mask = (uint32_t *) ((uint8_t *) dib + sizeof(*dib));
-                channel_mask[R] = mask[R];
-                channel_mask[G] = mask[G];
-                channel_mask[B] = mask[B];
-                channel_shift[R] = __builtin_ctz(mask[R]);
-                channel_shift[G] = __builtin_ctz(mask[G]);
-                channel_shift[B] = __builtin_ctz(mask[B]);
-                channel_scale[R] = 0xff / ((1 << __builtin_popcount(mask[R])) - 1);
-                channel_scale[G] = 0xff / ((1 << __builtin_popcount(mask[G])) - 1);
-                channel_scale[B] = 0xff / ((1 << __builtin_popcount(mask[B])) - 1);
-
-                if (dib->size >= sizeof(*dib) + 4 * sizeof(uint32_t) && mask[A] != 0) {
-                        channel_mask[A] = mask[A];
-                        channel_shift[A] = __builtin_ctz(mask[A]);
-                        channel_scale[A] = 0xff / ((1 << __builtin_popcount(mask[A])) - 1);
+        if (IN_SET(dib->depth, 16, 32) && dib->size >= SIZEOF_BMP_DIB_RGB) {
+                channel_mask[R] = dib->channel_mask_r;
+                channel_mask[G] = dib->channel_mask_g;
+                channel_mask[B] = dib->channel_mask_b;
+                channel_shift[R] = __builtin_ctz(dib->channel_mask_r);
+                channel_shift[G] = __builtin_ctz(dib->channel_mask_g);
+                channel_shift[B] = __builtin_ctz(dib->channel_mask_b);
+                channel_scale[R] = 0xff / ((1 << __builtin_popcount(dib->channel_mask_r)) - 1);
+                channel_scale[G] = 0xff / ((1 << __builtin_popcount(dib->channel_mask_g)) - 1);
+                channel_scale[B] = 0xff / ((1 << __builtin_popcount(dib->channel_mask_b)) - 1);
+
+                if (dib->size >= SIZEOF_BMP_DIB_RGBA && dib->channel_mask_a != 0) {
+                        channel_mask[A] = dib->channel_mask_a;
+                        channel_shift[A] = __builtin_ctz(dib->channel_mask_a);
+                        channel_scale[A] = 0xff / ((1 << __builtin_popcount(dib->channel_mask_a)) - 1);
                 } else {
                         channel_mask[A] = 0;
                         channel_shift[A] = 0;
@@ -233,7 +239,8 @@ static EFI_STATUS bmp_to_blt(
 
                         case 16:
                         case 32: {
-                                uint32_t i = dib->depth == 16 ? *(uint16_t *) in : *(uint32_t *) in;
+                                uint32_t i = dib->depth == 16 ? unaligned_read_ne16(in) :
+                                                                unaligned_read_ne32(in);
 
                                 uint8_t r = ((i & channel_mask[R]) >> channel_shift[R]) * channel_scale[R],
                                         g = ((i & channel_mask[G]) >> channel_shift[G]) * channel_scale[G],
index bb49740ab2fecab9af2f6dcfe1175ef9cb1204c2..a66eb24d060811f3c7b6f8b382d4d1484e71bcf5 100644 (file)
@@ -1,7 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <efi.h>
-#include <stddef.h>
+#include "efi.h"
 
 EFI_STATUS graphics_splash(const uint8_t *content, size_t len);
index 92229d8dee01e9d8982ac0f9b372d9d99efc8e5c..d85424ceaeb244620f2d69721b6b8bb0aa25a337 100644 (file)
@@ -1,8 +1,5 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <efi.h>
-#include <efilib.h>
-
 #include "cpio.h"
 #include "devicetree.h"
 #include "disk.h"
@@ -11,6 +8,7 @@
 #include "measure.h"
 #include "part-discovery.h"
 #include "pe.h"
+#include "proto/shell-parameters.h"
 #include "random-seed.h"
 #include "secure-boot.h"
 #include "splash.h"
index 654929699890bcbd583d9d5ea6a65f310a926da4..13972528cd59136d114304e58b856d8ed11c3309 100644 (file)
@@ -1,8 +1,5 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <efi.h>
-#include <efilib.h>
-
 #include "ticks.h"
 #include "util.h"
 #include "vmm.h"
index 683724b66cec83b82a05e8ff96ebca4c8870041b..96c62e6bfa210f09b624596e7cc473e018d0bf0c 100644 (file)
@@ -1,9 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <efi.h>
-#include <efilib.h>
-#include <inttypes.h>
-
+#include "proto/device-path.h"
+#include "proto/simple-text-io.h"
 #include "ticks.h"
 #include "util.h"
 
@@ -186,24 +184,25 @@ EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const char16_t *name, ui
 }
 
 EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const char16_t *name, char **ret, size_t *ret_size) {
-        _cleanup_free_ char *buf = NULL;
-        size_t l;
         EFI_STATUS err;
 
         assert(vendor);
         assert(name);
 
-        l = sizeof(char16_t *) * EFI_MAXIMUM_VARIABLE_SIZE;
-        buf = xmalloc(l);
+        size_t size = 0;
+        err = RT->GetVariable((char16_t *) name, (EFI_GUID *) vendor, NULL, &size, NULL);
+        if (err != EFI_BUFFER_TOO_SMALL)
+                return err;
 
-        err = RT->GetVariable((char16_t *) name, (EFI_GUID *) vendor, NULL, &l, buf);
+        _cleanup_free_ void *buf = xmalloc(size);
+        err = RT->GetVariable((char16_t *) name, (EFI_GUID *) vendor, NULL, &size, buf);
         if (err != EFI_SUCCESS)
                 return err;
 
         if (ret)
                 *ret = TAKE_PTR(buf);
         if (ret_size)
-                *ret_size = l;
+                *ret_size = size;
 
         return EFI_SUCCESS;
 }
@@ -299,7 +298,7 @@ EFI_STATUS file_read(EFI_FILE *dir, const char16_t *name, size_t off, size_t siz
         if (size == 0) {
                 _cleanup_free_ EFI_FILE_INFO *info = NULL;
 
-                err = get_file_info_harder(handle, &info, NULL);
+                err = get_file_info(handle, &info, NULL);
                 if (err != EFI_SUCCESS)
                         return err;
 
@@ -371,11 +370,7 @@ void sort_pointer_array(
         }
 }
 
-EFI_STATUS get_file_info_harder(
-                EFI_FILE *handle,
-                EFI_FILE_INFO **ret,
-                size_t *ret_size) {
-
+EFI_STATUS get_file_info(EFI_FILE *handle, EFI_FILE_INFO **ret, size_t *ret_size) {
         size_t size = offsetof(EFI_FILE_INFO, FileName) + 256;
         _cleanup_free_ EFI_FILE_INFO *fi = NULL;
         EFI_STATUS err;
@@ -383,8 +378,6 @@ EFI_STATUS get_file_info_harder(
         assert(handle);
         assert(ret);
 
-        /* A lot like LibFileInfo() but with useful error propagation */
-
         fi = xmalloc(size);
         err = handle->GetInfo(handle, MAKE_GUID_PTR(EFI_FILE_INFO), &size, fi);
         if (err == EFI_BUFFER_TOO_SMALL) {
@@ -404,7 +397,7 @@ EFI_STATUS get_file_info_harder(
         return EFI_SUCCESS;
 }
 
-EFI_STATUS readdir_harder(
+EFI_STATUS readdir(
                 EFI_FILE *handle,
                 EFI_FILE_INFO **buffer,
                 size_t *buffer_size) {
@@ -424,7 +417,7 @@ EFI_STATUS readdir_harder(
                  * position when returning EFI_BUFFER_TOO_SMALL, effectively skipping over any files when
                  * the buffer was too small. Therefore, start with a buffer that should handle FAT32 max
                  * file name length.
-                 * As a side effect, most readdir_harder() calls will now be slightly faster. */
+                 * As a side effect, most readdir() calls will now be slightly faster. */
                 sz = sizeof(EFI_FILE_INFO) + 256 * sizeof(char16_t);
                 *buffer = xmalloc(sz);
                 *buffer_size = sz;
@@ -490,7 +483,7 @@ EFI_STATUS open_directory(
         if (err != EFI_SUCCESS)
                 return err;
 
-        err = get_file_info_harder(dir, &file_info, NULL);
+        err = get_file_info(dir, &file_info, NULL);
         if (err != EFI_SUCCESS)
                 return err;
         if (!FLAGS_SET(file_info->Attribute, EFI_FILE_DIRECTORY))
@@ -648,15 +641,15 @@ EFI_STATUS make_file_device_path(EFI_HANDLE device, const char16_t *file, EFI_DE
         size_t dp_size = (uint8_t *) end_node - (uint8_t *) dp;
 
         /* Make a copy that can also hold a file media device path. */
-        *ret_dp = xmalloc(dp_size + file_size + SIZE_OF_FILEPATH_DEVICE_PATH + END_DEVICE_PATH_LENGTH);
+        *ret_dp = xmalloc(dp_size + file_size + sizeof(FILEPATH_DEVICE_PATH) + sizeof(EFI_DEVICE_PATH));
         dp = mempcpy(*ret_dp, dp, dp_size);
 
         /* Replace end node with file media device path. Use memcpy() in case dp is unaligned (if accessed as
          * FILEPATH_DEVICE_PATH). */
         dp->Type = MEDIA_DEVICE_PATH;
         dp->SubType = MEDIA_FILEPATH_DP;
-        memcpy((uint8_t *) dp + offsetof(FILEPATH_DEVICE_PATH, PathName), file, file_size);
-        SetDevicePathNodeLength(dp, offsetof(FILEPATH_DEVICE_PATH, PathName) + file_size);
+        dp->Length = sizeof(FILEPATH_DEVICE_PATH) + file_size;
+        memcpy((uint8_t *) dp + sizeof(FILEPATH_DEVICE_PATH), file, file_size);
 
         dp = NextDevicePathNode(dp);
         SetDevicePathEndNode(dp);
index d42c23730d3d1958b63060dc3782df27f066afe4..614d83fb71b07dcfcedd58eceec25f6bfdefe20f 100644 (file)
@@ -1,11 +1,9 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <efi.h>
-#include <efilib.h>
-#include <stddef.h>
-
+#include "efi.h"
 #include "log.h"
+#include "proto/file-io.h"
 #include "string-util-fundamental.h"
 
 static inline void free(void *p) {
@@ -113,16 +111,6 @@ static inline void unload_imagep(EFI_HANDLE *image) {
                 (void) BS->UnloadImage(*image);
 }
 
-/* Creates a EFI_GUID pointer suitable for EFI APIs. Use of const allows the compiler to merge multiple
- * uses (although, currently compilers do that regardless). Most EFI APIs declare their EFI_GUID input
- * as non-const, but almost all of them are in fact const. */
-#define MAKE_GUID_PTR(name) ((EFI_GUID *) &(const EFI_GUID) name##_GUID)
-
-/* These allow MAKE_GUID_PTR() to work without requiring an extra _GUID in the passed name. We want to
- * keep the GUID definitions in line with the UEFI spec. */
-#define EFI_GLOBAL_VARIABLE_GUID EFI_GLOBAL_VARIABLE
-#define EFI_FILE_INFO_GUID EFI_FILE_INFO_ID
-
 /*
  * Allocated random UUID, intended to be shared across tools that implement
  * the (ESP)\loader\entries\<vendor>-<revision>.conf convention and the
@@ -137,9 +125,8 @@ void clear_screen(size_t attr);
 typedef int (*compare_pointer_func_t)(const void *a, const void *b);
 void sort_pointer_array(void **array, size_t n_members, compare_pointer_func_t compare);
 
-EFI_STATUS get_file_info_harder(EFI_FILE *handle, EFI_FILE_INFO **ret, size_t *ret_size);
-
-EFI_STATUS readdir_harder(EFI_FILE *handle, EFI_FILE_INFO **buffer, size_t *buffer_size);
+EFI_STATUS get_file_info(EFI_FILE *handle, EFI_FILE_INFO **ret, size_t *ret_size);
+EFI_STATUS readdir(EFI_FILE *handle, EFI_FILE_INFO **buffer, size_t *buffer_size);
 
 bool is_ascii(const char16_t *f);
 
index 6bd440f03203c12e83813d6758c2b2ee512291d8..c3816e1b2dfc00b93df1b7da12964649096c3bde 100644 (file)
@@ -1,14 +1,12 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <efi.h>
-#include <efilib.h>
-#include <stdbool.h>
 #if defined(__i386__) || defined(__x86_64__)
 #  include <cpuid.h>
 #endif
 
 #include "drivers.h"
 #include "efi-string.h"
+#include "proto/device-path.h"
 #include "string-util-fundamental.h"
 #include "util.h"
 
@@ -154,6 +152,11 @@ static bool cpuid_in_hypervisor(void) {
         return false;
 }
 
+#define SMBIOS_TABLE_GUID \
+        GUID_DEF(0xeb9d2d31, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
+#define SMBIOS3_TABLE_GUID \
+        GUID_DEF(0xf2fd1544, 0x9794, 0x4a2c, 0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94)
+
 typedef struct {
         uint8_t anchor_string[4];
         uint8_t entry_point_structure_checksum;
index e98ec74af1cc6e4ac169f26bd6f161db950162e2..32f4fa3345e3ca0e9d3b44b597639436a553abdd 100644 (file)
@@ -1,8 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <efi.h>
-#include <efilib.h>
+#include "efi.h"
 
 bool is_direct_boot(EFI_HANDLE device);
 EFI_STATUS vmm_open(EFI_HANDLE *ret_qemu_dev, EFI_FILE **ret_qemu_dir);
index be7b19877f4678827f59aa0d0e7043b884406de1..8cd1e0370ddb407134467fd5ce9f68813744d4a1 100644 (file)
@@ -4213,14 +4213,21 @@ int unit_patch_contexts(Unit *u) {
                         }
 
                         /* If there are encrypted credentials we might need to access the TPM. */
-                        ExecLoadCredential *cred;
-                        HASHMAP_FOREACH(cred, ec->load_credentials)
-                                if (cred->encrypted) {
-                                        r = cgroup_add_device_allow(cc, "/dev/tpmrm0", "rw");
-                                        if (r < 0)
-                                                return r;
+                        bool allow_tpm = false;
+                        ExecLoadCredential *load_cred;
+                        ExecSetCredential *set_cred;
+                        HASHMAP_FOREACH(load_cred, ec->load_credentials)
+                                if ((allow_tpm |= load_cred->encrypted))
                                         break;
-                                }
+                        HASHMAP_FOREACH(set_cred, ec->set_credentials)
+                                if ((allow_tpm |= set_cred->encrypted))
+                                        break;
+
+                        if (allow_tpm) {
+                                r = cgroup_add_device_allow(cc, "/dev/tpmrm0", "rw");
+                                if (r < 0)
+                                        return r;
+                        }
                 }
         }
 
index cf785f8b7de20102f984265337e6c9989f0566bc..3bad79b0363ff3ec3c80e626cd46401da4415f72 100644 (file)
@@ -1,7 +1,11 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <errno.h>
+#ifdef SD_BOOT
+#  define EINVAL 22
+#else
+#  include <errno.h>
+#endif
 #include "string-util-fundamental.h"
 
 /* Features of the loader, i.e. systemd-boot */
index c4ad957588881489e88a72bf11309e37731371db..fa5b5d221a4d5575b966a09920d88a2ddd7cbfdf 100644 (file)
@@ -339,11 +339,8 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) {
 #define ALIGN2_PTR(p) ((void*) ALIGN2((uintptr_t) p))
 #define ALIGN4_PTR(p) ((void*) ALIGN4((uintptr_t) p))
 #define ALIGN8_PTR(p) ((void*) ALIGN8((uintptr_t) p))
-#if !SD_BOOT
-/* libefi also provides ALIGN, and we do not use them in sd-boot explicitly. */
 #define ALIGN(l)  ALIGN_TO(l, sizeof(void*))
 #define ALIGN_PTR(p) ((void*) ALIGN((uintptr_t) (p)))
-#endif
 
 /* Checks if the specified pointer is aligned as appropriate for the specific type */
 #define IS_ALIGNED16(p) (((uintptr_t) p) % __alignof__(uint16_t) == 0)
index 484131d72a809b007d9a36c18d916b66afc73d01..a5bafc63f4769e3202532e352f9bd3e3e8746b48 100644 (file)
@@ -20,7 +20,6 @@ sd_char *startswith(const sd_char *s, const sd_char *prefix) {
         return (sd_char*) s + l;
 }
 
-#if !SD_BOOT
 sd_char *startswith_no_case(const sd_char *s, const sd_char *prefix) {
         size_t l;
 
@@ -33,7 +32,6 @@ sd_char *startswith_no_case(const sd_char *s, const sd_char *prefix) {
 
         return (sd_char*) s + l;
 }
-#endif
 
 sd_char* endswith(const sd_char *s, const sd_char *postfix) {
         size_t sl, pl;
index c35ce5b88f4ef39ca010dc8f50ff249252b5290c..9019542b169c3058e200afb78fb87329cdd527b7 100644 (file)
@@ -2,8 +2,7 @@
 #pragma once
 
 #if SD_BOOT
-#  include <efi.h>
-#  include <efilib.h>
+#  include "efi.h"
 #  include "efi-string.h"
 #else
 #  include <string.h>
@@ -59,9 +58,7 @@ static inline size_t strlen_ptr(const sd_char *s) {
 }
 
 sd_char *startswith(const sd_char *s, const sd_char *prefix) _pure_;
-#if !SD_BOOT
 sd_char *startswith_no_case(const sd_char *s, const sd_char *prefix) _pure_;
-#endif
 sd_char *endswith(const sd_char *s, const sd_char *postfix) _pure_;
 sd_char *endswith_no_case(const sd_char *s, const sd_char *postfix) _pure_;
 
index 21b9284f8a729d18386091784435681f711ac022..34f67b7fcbbb293932262c8d5e58285f99527c0d 100644 (file)
@@ -773,40 +773,15 @@ static int enumerate_partitions(dev_t devnum) {
 }
 
 static int add_mounts(void) {
-        _cleanup_free_ char *p = NULL;
-        int r;
         dev_t devno;
+        int r;
 
-        /* If the root mount has been replaced by some form of volatile file system (overlayfs), the
-         * original root block device node is symlinked in /run/systemd/volatile-root. Let's read that
-         * here. */
-        r = readlink_malloc("/run/systemd/volatile-root", &p);
-        if (r == -ENOENT) { /* volatile-root not found */
-                r = get_block_device_harder("/", &devno);
-                if (r == -EUCLEAN)
-                        return btrfs_log_dev_root(LOG_ERR, r, "root file system");
-                if (r < 0)
-                        return log_error_errno(r, "Failed to determine block device of root file system: %m");
-                if (r == 0) { /* Not backed by a single block device. (Could be NFS or so, or could be multi-device RAID or so) */
-                        r = get_block_device_harder("/usr", &devno);
-                        if (r == -EUCLEAN)
-                                return btrfs_log_dev_root(LOG_ERR, r, "/usr");
-                        if (r < 0)
-                                return log_error_errno(r, "Failed to determine block device of /usr/ file system: %m");
-                        if (r == 0) { /* /usr/ not backed by single block device, either. */
-                                log_debug("Neither root nor /usr/ file system are on a (single) block device.");
-                                return 0;
-                        }
-                }
-        } else if (r < 0)
-                return log_error_errno(r, "Failed to read symlink /run/systemd/volatile-root: %m");
-        else {
-                mode_t m;
-                r = device_path_parse_major_minor(p, &m, &devno);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to parse major/minor device node: %m");
-                if (!S_ISBLK(m))
-                        return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK), "Volatile root device is of wrong type.");
+        r = blockdev_get_root(LOG_ERR, &devno);
+        if (r < 0)
+                return r;
+        if (r == 0) {
+                log_debug("Skipping automatic GPT dissection logic, root file system not backed by a (single) whole block device.");
+                return 0;
         }
 
         return enumerate_partitions(devno);
index e6b77406000d53bc715ad8829c8f23c72f92992b..413fcf177305c6f0225040ab087f60b946c218b2 100644 (file)
@@ -1180,8 +1180,9 @@ static int home_start_work(Home *h, const char *verb, UserRecord *hr, UserRecord
                 return -errno;
 
         r = safe_fork_full("(sd-homework)",
-                           (int[]) { stdin_fd, stdout_fd }, 2,
-                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG|FORK_REOPEN_LOG, &pid);
+                           (int[]) { stdin_fd, stdout_fd, STDERR_FILENO },
+                           NULL, 0,
+                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_REOPEN_LOG, &pid);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -1226,13 +1227,6 @@ static int home_start_work(Home *h, const char *verb, UserRecord *hr, UserRecord
                 if (r < 0)
                         log_warning_errno(r, "Failed to update $SYSTEMD_EXEC_PID, ignoring: %m");
 
-                r = rearrange_stdio(TAKE_FD(stdin_fd), TAKE_FD(stdout_fd), STDERR_FILENO); /* fds are invalidated by rearrange_stdio() even on failure */
-                if (r < 0) {
-                        log_error_errno(r, "Failed to rearrange stdin/stdout/stderr: %m");
-                        _exit(EXIT_FAILURE);
-                }
-
-
                 /* Allow overriding the homework path via an environment variable, to make debugging
                  * easier. */
                 homework = getenv("SYSTEMD_HOMEWORK_PATH") ?: SYSTEMD_HOMEWORK_PATH;
index 874d27d2920be4c742460f9c3aae5d621c129627..7227f885a8c5589db91feca47913e63936e356e4 100644 (file)
@@ -36,7 +36,10 @@ int import_fork_tar_x(const char *path, pid_t *ret) {
 
         use_selinux = mac_selinux_use();
 
-        r = safe_fork("(tar)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
+        r = safe_fork_full("(tar)",
+                           (int[]) { pipefd[0], -EBADF, STDERR_FILENO },
+                           NULL, 0,
+                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG, &pid);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -63,14 +66,6 @@ int import_fork_tar_x(const char *path, pid_t *ret) {
 
                 /* Child */
 
-                pipefd[1] = safe_close(pipefd[1]);
-
-                r = rearrange_stdio(TAKE_FD(pipefd[0]), -EBADF, STDERR_FILENO);
-                if (r < 0) {
-                        log_error_errno(r, "Failed to rearrange stdin/stdout: %m");
-                        _exit(EXIT_FAILURE);
-                }
-
                 if (unshare(CLONE_NEWNET) < 0)
                         log_warning_errno(errno, "Failed to lock tar into network namespace, ignoring: %m");
 
@@ -110,7 +105,10 @@ int import_fork_tar_c(const char *path, pid_t *ret) {
 
         use_selinux = mac_selinux_use();
 
-        r = safe_fork("(tar)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
+        r = safe_fork_full("(tar)",
+                           (int[]) { -EBADF, pipefd[1], STDERR_FILENO },
+                           NULL, 0,
+                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG, &pid);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -129,14 +127,6 @@ int import_fork_tar_c(const char *path, pid_t *ret) {
 
                 /* Child */
 
-                pipefd[0] = safe_close(pipefd[0]);
-
-                r = rearrange_stdio(-EBADF, TAKE_FD(pipefd[1]), STDERR_FILENO);
-                if (r < 0) {
-                        log_error_errno(r, "Failed to rearrange stdin/stdout: %m");
-                        _exit(EXIT_FAILURE);
-                }
-
                 if (unshare(CLONE_NEWNET) < 0)
                         log_error_errno(errno, "Failed to lock tar into network namespace, ignoring: %m");
 
index 65647a66a6342e0ea1ab599fcf09cc78b403058e..5f7b9c3163d3a053deeabf8c929596d2c84a7cb6 100644 (file)
@@ -365,7 +365,10 @@ static int transfer_start(Transfer *t) {
         if (pipe2(pipefd, O_CLOEXEC) < 0)
                 return -errno;
 
-        r = safe_fork("(sd-transfer)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &t->pid);
+        r = safe_fork_full("(sd-transfer)",
+                           (int[]) { t->stdin_fd, t->stdout_fd < 0 ? pipefd[1] : t->stdout_fd, pipefd[1] },
+                           NULL, 0,
+                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO, &t->pid);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -387,17 +390,6 @@ static int transfer_start(Transfer *t) {
 
                 /* Child */
 
-                pipefd[0] = safe_close(pipefd[0]);
-
-                r = rearrange_stdio(TAKE_FD(t->stdin_fd),
-                                    t->stdout_fd < 0 ? pipefd[1] : TAKE_FD(t->stdout_fd),
-                                    pipefd[1]);
-                TAKE_FD(pipefd[1]);
-                if (r < 0) {
-                        log_error_errno(r, "Failed to set stdin/stdout/stderr: %m");
-                        _exit(EXIT_FAILURE);
-                }
-
                 if (setenv("SYSTEMD_LOG_TARGET", "console-prefixed", 1) < 0 ||
                     setenv("NOTIFY_SOCKET", "/run/systemd/import/notify", 1) < 0) {
                         log_error_errno(errno, "setenv() failed: %m");
index c8a3bf370e113bdd6c223ccd84b88e949d6db6bc..3b80e64b3283d7ea609a54336a2ec396b01aa1d6 100644 (file)
@@ -414,7 +414,11 @@ static int verify_gpg(
 
         gpg_home_created = true;
 
-        r = safe_fork("(gpg)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &pid);
+        r = safe_fork_full("(gpg)",
+                           (int[]) { gpg_pipe[0], -EBADF, STDERR_FILENO },
+                           NULL, 0,
+                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
+                           &pid);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -437,14 +441,6 @@ static int verify_gpg(
 
                 /* Child */
 
-                gpg_pipe[1] = safe_close(gpg_pipe[1]);
-
-                r = rearrange_stdio(TAKE_FD(gpg_pipe[0]), -EBADF, STDERR_FILENO);
-                if (r < 0) {
-                        log_error_errno(r, "Failed to rearrange stdin/stdout: %m");
-                        _exit(EXIT_FAILURE);
-                }
-
                 cmd[k++] = strjoina("--homedir=", gpg_home);
 
                 /* We add the user keyring only to the command line arguments, if it's around since gpg fails
index 7df264fb53141858d15d5f6ed2e77d13690cf152..e620b60a31a66faedba4ef40e66530e29d62067b 100644 (file)
@@ -85,7 +85,10 @@ static int spawn_child(const char* child, char** argv) {
         if (pipe(fd) < 0)
                 return log_error_errno(errno, "Failed to create pager pipe: %m");
 
-        r = safe_fork("(remote)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &child_pid);
+        r = safe_fork_full("(remote)",
+                           (int[]) {STDIN_FILENO, fd[1], STDERR_FILENO },
+                           NULL, 0,
+                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &child_pid);
         if (r < 0) {
                 safe_close_pair(fd);
                 return r;
@@ -93,14 +96,6 @@ static int spawn_child(const char* child, char** argv) {
 
         /* In the child */
         if (r == 0) {
-                fd[0] = safe_close(fd[0]);
-
-                r = rearrange_stdio(STDIN_FILENO, TAKE_FD(fd[1]), STDERR_FILENO);
-                if (r < 0) {
-                        log_error_errno(r, "Failed to dup pipe to stdout: %m");
-                        _exit(EXIT_FAILURE);
-                }
-
                 execvp(child, argv);
                 log_error_errno(errno, "Failed to exec child %s: %m", child);
                 _exit(EXIT_FAILURE);
index dd31007a4dea52bccb64af8353c7fdeb14dcb8c5..de08c4e9651e63a47527dae0662078d61d54ef16 100644 (file)
@@ -873,10 +873,6 @@ static bool shall_try_append_again(JournalFile *f, int r) {
                 log_ratelimit_warning(JOURNAL_LOG_RATELIMIT, "%s: Journal file has been deleted, rotating.", f->path);
                 return true;
 
-        case -ETXTBSY:         /* Journal file is from the future */
-                log_ratelimit_warning(JOURNAL_LOG_RATELIMIT, "%s: Journal file is from the future, rotating.", f->path);
-                return true;
-
         case -EREMCHG:         /* Wallclock time (CLOCK_REALTIME) jumped backwards relative to last journal entry */
                 log_ratelimit_warning(JOURNAL_LOG_RATELIMIT, "%s: Realtime clock jumped backwards relative to last journal entry, rotating.", f->path);
                 return true;
index 81aecfe7cb9be33bfa48e652e6457ff6033562d1..538d999de0a611c232173d34c48151ed8a5d74ae 100644 (file)
@@ -542,8 +542,7 @@ int managed_journal_file_open_reliably(
                     -EBUSY,             /* Unclean shutdown */
                     -ESHUTDOWN,         /* Already archived */
                     -EIO,               /* IO error, including SIGBUS on mmap */
-                    -EIDRM,             /* File has been deleted */
-                    -ETXTBSY))          /* File is from the future */
+                    -EIDRM))            /* File has been deleted */
                 return r;
 
         if ((open_flags & O_ACCMODE) == O_RDONLY)
index 55d717da3163ec45f428bd26b9a74de965d7e434..7fec6d9eea25ae7842c53dbcfa491a894ae3d31c 100644 (file)
@@ -230,7 +230,7 @@ static void test_sequence_numbers_one(void) {
 
         assert_se(one->file->header->state == STATE_ONLINE);
         assert_se(!sd_id128_equal(one->file->header->file_id, one->file->header->machine_id));
-        assert_se(!sd_id128_equal(one->file->header->file_id, one->file->header->boot_id));
+        assert_se(!sd_id128_equal(one->file->header->file_id, one->file->header->tail_entry_boot_id));
         assert_se(sd_id128_equal(one->file->header->file_id, one->file->header->seqnum_id));
 
         memcpy(&seqnum_id, &one->file->header->seqnum_id, sizeof(sd_id128_t));
@@ -241,7 +241,7 @@ static void test_sequence_numbers_one(void) {
         assert_se(two->file->header->state == STATE_ONLINE);
         assert_se(!sd_id128_equal(two->file->header->file_id, one->file->header->file_id));
         assert_se(sd_id128_equal(one->file->header->machine_id, one->file->header->machine_id));
-        assert_se(sd_id128_equal(one->file->header->boot_id, one->file->header->boot_id));
+        assert_se(sd_id128_equal(one->file->header->tail_entry_boot_id, one->file->header->tail_entry_boot_id));
         assert_se(sd_id128_equal(one->file->header->seqnum_id, one->file->header->seqnum_id));
 
         append_number(two, 3, &seqnum);
index 64037e4fe0595875933899155c20c700e80d1b1b..33cfeebda7be3456c2355a1f3828cc5aaea3f189 100644 (file)
@@ -994,7 +994,10 @@ int bus_socket_exec(sd_bus *b) {
         if (r < 0)
                 return -errno;
 
-        r = safe_fork_full("(sd-busexec)", s+1, 1, FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE, &b->busexec_pid);
+        r = safe_fork_full("(sd-busexec)",
+                           (int[]) { s[1], s[1], STDERR_FILENO },
+                           NULL, 0,
+                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REARRANGE_STDIO|FORK_RLIMIT_NOFILE_SAFE, &b->busexec_pid);
         if (r < 0) {
                 safe_close_pair(s);
                 return r;
@@ -1002,11 +1005,6 @@ int bus_socket_exec(sd_bus *b) {
         if (r == 0) {
                 /* Child */
 
-                r = rearrange_stdio(s[1], s[1], STDERR_FILENO);
-                TAKE_FD(s[1]);
-                if (r < 0)
-                        _exit(EXIT_FAILURE);
-
                 if (b->exec_argv)
                         execvp(b->exec_path, b->exec_argv);
                 else
index 3c5d9d7e4975bb61d224f18e7f03f9d1efee8c00..159e21536791ece195ee1a3bba35e34418df0bf7 100644 (file)
@@ -300,7 +300,7 @@ int journal_file_hmac_put_header(JournalFile *f) {
          * n_entry_arrays. */
 
         gcry_md_write(f->hmac, f->header->signature, offsetof(Header, state) - offsetof(Header, signature));
-        gcry_md_write(f->hmac, &f->header->file_id, offsetof(Header, boot_id) - offsetof(Header, file_id));
+        gcry_md_write(f->hmac, &f->header->file_id, offsetof(Header, tail_entry_boot_id) - offsetof(Header, file_id));
         gcry_md_write(f->hmac, &f->header->seqnum_id, offsetof(Header, arena_size) - offsetof(Header, seqnum_id));
         gcry_md_write(f->hmac, &f->header->data_hash_table_offset, offsetof(Header, tail_object_offset) - offsetof(Header, data_hash_table_offset));
 
index d35290d3c70ba30f507885a6343a742d96e6dc73..fb22fc45f304e111eeaada8c5c782dd595ee27a8 100644 (file)
@@ -173,32 +173,31 @@ enum {
         HEADER_INCOMPATIBLE_KEYED_HASH      = 1 << 2,
         HEADER_INCOMPATIBLE_COMPRESSED_ZSTD = 1 << 3,
         HEADER_INCOMPATIBLE_COMPACT         = 1 << 4,
-};
 
-#define HEADER_INCOMPATIBLE_ANY               \
-        (HEADER_INCOMPATIBLE_COMPRESSED_XZ |  \
-         HEADER_INCOMPATIBLE_COMPRESSED_LZ4 | \
-         HEADER_INCOMPATIBLE_KEYED_HASH |     \
-         HEADER_INCOMPATIBLE_COMPRESSED_ZSTD | \
-         HEADER_INCOMPATIBLE_COMPACT)
+        HEADER_INCOMPATIBLE_ANY             = HEADER_INCOMPATIBLE_COMPRESSED_XZ |
+                                              HEADER_INCOMPATIBLE_COMPRESSED_LZ4 |
+                                              HEADER_INCOMPATIBLE_KEYED_HASH |
+                                              HEADER_INCOMPATIBLE_COMPRESSED_ZSTD |
+                                              HEADER_INCOMPATIBLE_COMPACT,
+
+        HEADER_INCOMPATIBLE_SUPPORTED       = (HAVE_XZ ? HEADER_INCOMPATIBLE_COMPRESSED_XZ : 0) |
+                                              (HAVE_LZ4 ? HEADER_INCOMPATIBLE_COMPRESSED_LZ4 : 0) |
+                                              (HAVE_ZSTD ? HEADER_INCOMPATIBLE_COMPRESSED_ZSTD : 0) |
+                                              HEADER_INCOMPATIBLE_KEYED_HASH |
+                                              HEADER_INCOMPATIBLE_COMPACT,
+};
 
-#define HEADER_INCOMPATIBLE_SUPPORTED                            \
-        ((HAVE_XZ ? HEADER_INCOMPATIBLE_COMPRESSED_XZ : 0) |     \
-         (HAVE_LZ4 ? HEADER_INCOMPATIBLE_COMPRESSED_LZ4 : 0) |   \
-         (HAVE_ZSTD ? HEADER_INCOMPATIBLE_COMPRESSED_ZSTD : 0) | \
-         HEADER_INCOMPATIBLE_KEYED_HASH |                        \
-         HEADER_INCOMPATIBLE_COMPACT)
 
 enum {
-        HEADER_COMPATIBLE_SEALED = 1 << 0,
+        HEADER_COMPATIBLE_SEALED             = 1 << 0,
+        HEADER_COMPATIBLE_TAIL_ENTRY_BOOT_ID = 1 << 1, /* if set, the last_entry_boot_id field in the header is exclusively refreshed when an entry is appended */
+        HEADER_COMPATIBLE_ANY                = HEADER_COMPATIBLE_SEALED|
+                                               HEADER_COMPATIBLE_TAIL_ENTRY_BOOT_ID,
+
+        HEADER_COMPATIBLE_SUPPORTED          = (HAVE_GCRYPT ? HEADER_COMPATIBLE_SEALED : 0) |
+                                               HEADER_COMPATIBLE_TAIL_ENTRY_BOOT_ID,
 };
 
-#define HEADER_COMPATIBLE_ANY HEADER_COMPATIBLE_SEALED
-#if HAVE_GCRYPT
-#  define HEADER_COMPATIBLE_SUPPORTED HEADER_COMPATIBLE_SEALED
-#else
-#  define HEADER_COMPATIBLE_SUPPORTED 0
-#endif
 
 #define HEADER_SIGNATURE                                                \
         ((const uint8_t[]) { 'L', 'P', 'K', 'S', 'H', 'H', 'R', 'H' })
@@ -211,7 +210,7 @@ enum {
         uint8_t reserved[7];                            \
         sd_id128_t file_id;                             \
         sd_id128_t machine_id;                          \
-        sd_id128_t boot_id;    /* last writer */        \
+        sd_id128_t tail_entry_boot_id;                  \
         sd_id128_t seqnum_id;                           \
         le64_t header_size;                             \
         le64_t arena_size;                              \
index aab33dbfccab138f58d923ced36bea8b16c96a0e..c4971a807c79db4d664b42b092db340ff1cdd886 100644 (file)
@@ -357,7 +357,9 @@ static int journal_file_init_header(
                                 FLAGS_SET(file_flags, JOURNAL_COMPRESS) * COMPRESSION_TO_HEADER_INCOMPATIBLE_FLAG(DEFAULT_COMPRESSION) |
                                 keyed_hash_requested() * HEADER_INCOMPATIBLE_KEYED_HASH |
                                 compact_mode_requested() * HEADER_INCOMPATIBLE_COMPACT),
-                .compatible_flags = htole32(seal * HEADER_COMPATIBLE_SEALED),
+                .compatible_flags = htole32(
+                                (seal * HEADER_COMPATIBLE_SEALED) |
+                                HEADER_COMPATIBLE_TAIL_ENTRY_BOOT_ID),
         };
 
         assert_cc(sizeof(h.signature) == sizeof(HEADER_SIGNATURE));
@@ -367,6 +369,11 @@ static int journal_file_init_header(
         if (r < 0)
                 return r;
 
+        r = sd_id128_get_machine(&h.machine_id);
+        if (r < 0 && !ERRNO_IS_MACHINE_ID_UNSET(r))
+                return r; /* If we have no valid machine ID (test environment?), let's simply leave the
+                           * machine ID field all zeroes. */
+
         if (template) {
                 h.seqnum_id = template->header->seqnum_id;
                 h.tail_entry_seqnum = template->header->tail_entry_seqnum;
@@ -388,18 +395,8 @@ static int journal_file_refresh_header(JournalFile *f) {
         assert(f);
         assert(f->header);
 
-        r = sd_id128_get_machine(&f->header->machine_id);
-        if (r < 0) {
-                if (!ERRNO_IS_MACHINE_ID_UNSET(r))
-                        return r;
-
-                /* don't have a machine-id, let's continue without */
-                f->header->machine_id = SD_ID128_NULL;
-        }
-
-        r = sd_id128_get_boot(&f->header->boot_id);
-        if (r < 0)
-                return r;
+        /* We used to update the header's boot ID field here, but we don't do that anymore, as per
+         * HEADER_COMPATIBLE_TAIL_ENTRY_BOOT_ID */
 
         r = journal_file_set_online(f);
 
@@ -514,8 +511,12 @@ static int journal_file_verify_header(JournalFile *f) {
                 int r;
 
                 r = sd_id128_get_machine(&machine_id);
-                if (r < 0)
-                        return r;
+                if (r < 0) {
+                        if (!ERRNO_IS_MACHINE_ID_UNSET(r)) /* handle graceful if machine ID is not initialized yet */
+                                return r;
+
+                        machine_id = SD_ID128_NULL;
+                }
 
                 if (!sd_id128_equal(machine_id, f->header->machine_id))
                         return log_debug_errno(SYNTHETIC_ERRNO(EHOSTDOWN),
@@ -536,14 +537,6 @@ static int journal_file_verify_header(JournalFile *f) {
 
                 if (f->header->field_hash_table_size == 0 || f->header->data_hash_table_size == 0)
                         return -EBADMSG;
-
-                /* Don't permit appending to files from the future. Because otherwise the realtime timestamps wouldn't
-                 * be strictly ordered in the entries in the file anymore, and we can't have that since it breaks
-                 * bisection. */
-                if (le64toh(f->header->tail_entry_realtime) > now(CLOCK_REALTIME))
-                        return log_debug_errno(SYNTHETIC_ERRNO(ETXTBSY),
-                                               "Journal file %s is from the future, refusing to append new data to it that'd be older.",
-                                               f->path);
         }
 
         return 0;
@@ -2090,6 +2083,7 @@ static int journal_file_append_entry_internal(
                 JournalFile *f,
                 const dual_timestamp *ts,
                 const sd_id128_t *boot_id,
+                const sd_id128_t *machine_id,
                 uint64_t xor_hash,
                 const EntryItem items[],
                 size_t n_items,
@@ -2126,9 +2120,9 @@ static int journal_file_append_entry_internal(
                                                "timestamp %" PRIu64 ", refusing entry.",
                                                ts->realtime, le64toh(f->header->tail_entry_realtime));
 
-                if (!sd_id128_is_null(f->header->boot_id) && boot_id) {
+                if (!sd_id128_is_null(f->header->tail_entry_boot_id) && boot_id) {
 
-                        if (!sd_id128_equal(f->header->boot_id, *boot_id))
+                        if (!sd_id128_equal(f->header->tail_entry_boot_id, *boot_id))
                                 return log_debug_errno(SYNTHETIC_ERRNO(EREMOTE),
                                                        "Boot ID to write is different from previous boot id, refusing entry.");
 
@@ -2155,6 +2149,10 @@ static int journal_file_append_entry_internal(
                 }
         }
 
+        if (machine_id && sd_id128_is_null(f->header->machine_id))
+                /* Initialize machine ID when not set yet */
+                f->header->machine_id = *machine_id;
+
         osize = offsetof(Object, entry.items) + (n_items * journal_file_entry_item_size(f));
 
         r = journal_file_append_object(f, OBJECT_ENTRY, osize, &o, &np);
@@ -2166,8 +2164,8 @@ static int journal_file_append_entry_internal(
         o->entry.monotonic = htole64(ts->monotonic);
         o->entry.xor_hash = htole64(xor_hash);
         if (boot_id)
-                f->header->boot_id = *boot_id;
-        o->entry.boot_id = f->header->boot_id;
+                f->header->tail_entry_boot_id = *boot_id;
+        o->entry.boot_id = f->header->tail_entry_boot_id;
 
         for (size_t i = 0; i < n_items; i++)
                 write_entry_item(f, o, i, &items[i]);
@@ -2314,7 +2312,7 @@ int journal_file_append_entry(
         EntryItem *items;
         uint64_t xor_hash = 0;
         struct dual_timestamp _ts;
-        sd_id128_t _boot_id;
+        sd_id128_t _boot_id, _machine_id, *machine_id;
         int r;
 
         assert(f);
@@ -2344,6 +2342,16 @@ int journal_file_append_entry(
                 boot_id = &_boot_id;
         }
 
+        r = sd_id128_get_machine(&_machine_id);
+        if (r < 0) {
+                if (!ERRNO_IS_MACHINE_ID_UNSET(r))
+                        return r;
+
+                /* If the machine ID is not initialized yet, handle gracefully */
+                machine_id = NULL;
+        } else
+                machine_id = &_machine_id;
+
 #if HAVE_GCRYPT
         r = journal_file_maybe_append_tag(f, ts->realtime);
         if (r < 0)
@@ -2393,7 +2401,18 @@ int journal_file_append_entry(
         typesafe_qsort(items, n_iovec, entry_item_cmp);
         n_iovec = remove_duplicate_entry_items(items, n_iovec);
 
-        r = journal_file_append_entry_internal(f, ts, boot_id, xor_hash, items, n_iovec, seqnum, seqnum_id, ret_object, ret_offset);
+        r = journal_file_append_entry_internal(
+                        f,
+                        ts,
+                        boot_id,
+                        machine_id,
+                        xor_hash,
+                        items,
+                        n_iovec,
+                        seqnum,
+                        seqnum_id,
+                        ret_object,
+                        ret_offset);
 
         /* If the memory mapping triggered a SIGBUS then we return an
          * IO error and ignore the error code passed down to us, since
@@ -3174,56 +3193,6 @@ void journal_file_save_location(JournalFile *f, Object *o, uint64_t offset) {
         f->current_xor_hash = le64toh(o->entry.xor_hash);
 }
 
-int journal_file_compare_locations(JournalFile *af, JournalFile *bf) {
-        int r;
-
-        assert(af);
-        assert(af->header);
-        assert(bf);
-        assert(bf->header);
-        assert(af->location_type == LOCATION_SEEK);
-        assert(bf->location_type == LOCATION_SEEK);
-
-        /* If contents, timestamps and seqnum match, these entries are
-         * identical. */
-        if (sd_id128_equal(af->current_boot_id, bf->current_boot_id) &&
-            af->current_monotonic == bf->current_monotonic &&
-            af->current_realtime == bf->current_realtime &&
-            af->current_xor_hash == bf->current_xor_hash &&
-            sd_id128_equal(af->header->seqnum_id, bf->header->seqnum_id) &&
-            af->current_seqnum == bf->current_seqnum)
-                return 0;
-
-        if (sd_id128_equal(af->header->seqnum_id, bf->header->seqnum_id)) {
-
-                /* If this is from the same seqnum source, compare
-                 * seqnums */
-                r = CMP(af->current_seqnum, bf->current_seqnum);
-                if (r != 0)
-                        return r;
-
-                /* Wow! This is weird, different data but the same
-                 * seqnums? Something is borked, but let's make the
-                 * best of it and compare by time. */
-        }
-
-        if (sd_id128_equal(af->current_boot_id, bf->current_boot_id)) {
-
-                /* If the boot id matches, compare monotonic time */
-                r = CMP(af->current_monotonic, bf->current_monotonic);
-                if (r != 0)
-                        return r;
-        }
-
-        /* Otherwise, compare UTC time */
-        r = CMP(af->current_realtime, bf->current_realtime);
-        if (r != 0)
-                return r;
-
-        /* Finally, compare by contents */
-        return CMP(af->current_xor_hash, bf->current_xor_hash);
-}
-
 static bool check_properly_ordered(uint64_t new_offset, uint64_t old_offset, direction_t direction) {
 
         /* Consider it an error if any of the two offsets is uninitialized */
@@ -3567,7 +3536,7 @@ void journal_file_print_header(JournalFile *f) {
                "Boot ID: %s\n"
                "Sequential number ID: %s\n"
                "State: %s\n"
-               "Compatible flags:%s%s\n"
+               "Compatible flags:%s%s%s\n"
                "Incompatible flags:%s%s%s%s%s%s\n"
                "Header size: %"PRIu64"\n"
                "Arena size: %"PRIu64"\n"
@@ -3584,12 +3553,13 @@ void journal_file_print_header(JournalFile *f) {
                f->path,
                SD_ID128_TO_STRING(f->header->file_id),
                SD_ID128_TO_STRING(f->header->machine_id),
-               SD_ID128_TO_STRING(f->header->boot_id),
+               SD_ID128_TO_STRING(f->header->tail_entry_boot_id),
                SD_ID128_TO_STRING(f->header->seqnum_id),
                f->header->state == STATE_OFFLINE ? "OFFLINE" :
                f->header->state == STATE_ONLINE ? "ONLINE" :
                f->header->state == STATE_ARCHIVED ? "ARCHIVED" : "UNKNOWN",
                JOURNAL_HEADER_SEALED(f->header) ? " SEALED" : "",
+               JOURNAL_HEADER_TAIL_ENTRY_BOOT_ID(f->header) ? " TAIL_ENTRY_BOOT_ID" : "",
                (le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_ANY) ? " ???" : "",
                JOURNAL_HEADER_COMPRESSED_XZ(f->header) ? " COMPRESSED-XZ" : "",
                JOURNAL_HEADER_COMPRESSED_LZ4(f->header) ? " COMPRESSED-LZ4" : "",
@@ -4192,7 +4162,18 @@ int journal_file_copy_entry(
                         return r;
         }
 
-        r = journal_file_append_entry_internal(to, &ts, boot_id, xor_hash, items, n, seqnum, seqnum_id, NULL, NULL);
+        r = journal_file_append_entry_internal(
+                        to,
+                        &ts,
+                        boot_id,
+                        &from->header->machine_id,
+                        xor_hash,
+                        items,
+                        n,
+                        seqnum,
+                        seqnum_id,
+                        /* ret_object= */ NULL,
+                        /* ret_offset= */ NULL);
 
         if (mmap_cache_fd_got_sigbus(to->cache_fd))
                 return -EIO;
index 07f1f5d180651ab250132f0baf30c474da8ca62d..2a0691ae1945c906d3add8ac2006ecf41e882be6 100644 (file)
@@ -180,6 +180,9 @@ static inline bool VALID_EPOCH(uint64_t u) {
 #define JOURNAL_HEADER_SEALED(h) \
         FLAGS_SET(le32toh((h)->compatible_flags), HEADER_COMPATIBLE_SEALED)
 
+#define JOURNAL_HEADER_TAIL_ENTRY_BOOT_ID(h) \
+        FLAGS_SET(le32toh((h)->compatible_flags), HEADER_COMPATIBLE_TAIL_ENTRY_BOOT_ID)
+
 #define JOURNAL_HEADER_COMPRESSED_XZ(h) \
         FLAGS_SET(le32toh((h)->incompatible_flags), HEADER_INCOMPATIBLE_COMPRESSED_XZ)
 
@@ -272,7 +275,6 @@ int journal_file_find_field_object_with_hash(JournalFile *f, const void *field,
 
 void journal_file_reset_location(JournalFile *f);
 void journal_file_save_location(JournalFile *f, Object *o, uint64_t offset);
-int journal_file_compare_locations(JournalFile *af, JournalFile *bf);
 int journal_file_next_entry(JournalFile *f, uint64_t p, direction_t direction, Object **ret_object, uint64_t *ret_offset);
 
 int journal_file_next_entry_for_data(JournalFile *f, Object *d, direction_t direction, Object **ret_object, uint64_t *ret_offset);
index b4ce3881a44a35c94585a511856d22565e613f98..8232f53eb66995113b01a691d3faa19c9e233184 100644 (file)
@@ -1297,7 +1297,8 @@ int journal_file_verify(
         }
 
         if (entry_monotonic_set &&
-            (sd_id128_equal(entry_boot_id, f->header->boot_id) &&
+            (sd_id128_equal(entry_boot_id, f->header->tail_entry_boot_id) &&
+             JOURNAL_HEADER_TAIL_ENTRY_BOOT_ID(f->header) &&
              entry_monotonic != le64toh(f->header->tail_entry_monotonic))) {
                 error(0,
                       "Invalid tail monotonic timestamp (%"PRIu64" != %"PRIu64")",
index afbf25526635ebf9ecdeed98bf3ddac1ae52963c..053149d675062c9d113e0db47591796931dfb0d5 100644 (file)
@@ -801,6 +801,51 @@ static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direc
         }
 }
 
+static int compare_locations(JournalFile *af, JournalFile *bf) {
+        int r;
+
+        assert(af);
+        assert(af->header);
+        assert(bf);
+        assert(bf->header);
+        assert(af->location_type == LOCATION_SEEK);
+        assert(bf->location_type == LOCATION_SEEK);
+
+        /* If contents, timestamps and seqnum match, these entries are identical. */
+        if (sd_id128_equal(af->current_boot_id, bf->current_boot_id) &&
+            af->current_monotonic == bf->current_monotonic &&
+            af->current_realtime == bf->current_realtime &&
+            af->current_xor_hash == bf->current_xor_hash &&
+            sd_id128_equal(af->header->seqnum_id, bf->header->seqnum_id) &&
+            af->current_seqnum == bf->current_seqnum)
+                return 0;
+
+        if (sd_id128_equal(af->header->seqnum_id, bf->header->seqnum_id)) {
+                /* If this is from the same seqnum source, compare seqnums */
+                r = CMP(af->current_seqnum, bf->current_seqnum);
+                if (r != 0)
+                        return r;
+
+                /* Wow! This is weird, different data but the same seqnums? Something is borked, but let's
+                 * make the best of it and compare by time. */
+        }
+
+        if (sd_id128_equal(af->current_boot_id, bf->current_boot_id)) {
+                /* If the boot id matches, compare monotonic time */
+                r = CMP(af->current_monotonic, bf->current_monotonic);
+                if (r != 0)
+                        return r;
+        }
+
+        /* Otherwise, compare UTC time */
+        r = CMP(af->current_realtime, bf->current_realtime);
+        if (r != 0)
+                return r;
+
+        /* Finally, compare by contents */
+        return CMP(af->current_xor_hash, bf->current_xor_hash);
+}
+
 static int real_journal_next(sd_journal *j, direction_t direction) {
         JournalFile *new_file = NULL;
         unsigned n_files;
@@ -834,7 +879,7 @@ static int real_journal_next(sd_journal *j, direction_t direction) {
                 else {
                         int k;
 
-                        k = journal_file_compare_locations(f, new_file);
+                        k = compare_locations(f, new_file);
 
                         found = direction == DIRECTION_DOWN ? k < 0 : k > 0;
                 }
index 21feaae0c328ebb3cfd6c0a60da1c0a82337ee27..d238cb74c9156440a282b97340d38bbc86dbd579 100644 (file)
@@ -136,7 +136,7 @@ static int brightness_writer_fork(BrightnessWriter *w) {
         assert(w->child == 0);
         assert(!w->child_event_source);
 
-        r = safe_fork("(sd-bright)", FORK_DEATHSIG|FORK_NULL_STDIO|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &w->child);
+        r = safe_fork("(sd-bright)", FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &w->child);
         if (r < 0)
                 return r;
         if (r == 0) {
index 2a121faea59527a8506c7e118e7bb35c2fdf7364..63b6d012ee590443da2811de8aec94d9f470bcd0 100644 (file)
@@ -710,7 +710,7 @@ static int session_dispatch_stop_on_idle(sd_event_source *source, uint64_t t, vo
 
         idle = session_get_idle_hint(s, &ts);
         if (idle) {
-                log_debug("Session \"%s\" of user \"%s\" is idle, stopping.", s->id, s->user->user_record->user_name);
+                log_info("Session \"%s\" of user \"%s\" is idle, stopping.", s->id, s->user->user_record->user_name);
 
                 return session_stop(s, /* force */ true);
         }
index ba2fca32c6b4669ebca8f26f8be640f5e05c190f..2cfe52288ea10a9d53235a2533cdd76b15176d49 100644 (file)
@@ -390,24 +390,40 @@ static int append_session_tasks_max(pam_handle_t *handle, sd_bus_message *m, con
         return PAM_SUCCESS;
 }
 
-static int append_session_cg_weight(pam_handle_t *handle, sd_bus_message *m, const char *limit, const char *field) {
+static int append_session_cpu_weight(pam_handle_t *handle, sd_bus_message *m, const char *limit) {
         uint64_t val;
         int r;
-        bool is_cpu_weight;
 
-        is_cpu_weight = streq(field, "CPUWeight");
         if (isempty(limit))
                 return PAM_SUCCESS;
 
-        r = is_cpu_weight ? cg_cpu_weight_parse(limit, &val) : cg_weight_parse(limit, &val);
-        if (r >= 0) {
-                r = sd_bus_message_append(m, "(sv)", field, "t", val);
+        r = cg_cpu_weight_parse(limit, &val);
+        if (r < 0)
+                pam_syslog(handle, LOG_WARNING, "Failed to parse systemd.cpu_weight, ignoring: %s", limit);
+        else {
+                r = sd_bus_message_append(m, "(sv)", "CPUWeight", "t", val);
                 if (r < 0)
                         return pam_bus_log_create_error(handle, r);
-        } else if (is_cpu_weight)
-                pam_syslog(handle, LOG_WARNING, "Failed to parse systemd.cpu_weight, ignoring: %s", limit);
-        else
+        }
+
+        return PAM_SUCCESS;
+}
+
+static int append_session_io_weight(pam_handle_t *handle, sd_bus_message *m, const char *limit) {
+        uint64_t val;
+        int r;
+
+        if (isempty(limit))
+                return PAM_SUCCESS;
+
+        r = cg_weight_parse(limit, &val);
+        if (r < 0)
                 pam_syslog(handle, LOG_WARNING, "Failed to parse systemd.io_weight, ignoring: %s", limit);
+        else {
+                r = sd_bus_message_append(m, "(sv)", "IOWeight", "t", val);
+                if (r < 0)
+                        return pam_bus_log_create_error(handle, r);
+        }
 
         return PAM_SUCCESS;
 }
@@ -869,11 +885,11 @@ _public_ PAM_EXTERN int pam_sm_open_session(
         if (r != PAM_SUCCESS)
                 return r;
 
-        r = append_session_cg_weight(handle, m, cpu_weight, "CPUWeight");
+        r = append_session_cpu_weight(handle, m, cpu_weight);
         if (r != PAM_SUCCESS)
                 return r;
 
-        r = append_session_cg_weight(handle, m, io_weight, "IOWeight");
+        r = append_session_io_weight(handle, m, io_weight);
         if (r != PAM_SUCCESS)
                 return r;
 
index 5772d96b2fa50031e3e38a235dffdf1f0e226219..3c12648b9d76ef199e18159158b8020941c9685a 100644 (file)
@@ -28,23 +28,17 @@ static int spawn_getent(const char *database, const char *key, pid_t *rpid) {
         if (pipe2(pipe_fds, O_CLOEXEC) < 0)
                 return log_error_errno(errno, "Failed to allocate pipe: %m");
 
-        r = safe_fork("(getent)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &pid);
+        r = safe_fork_full("(getent)",
+                           (int[]) { -EBADF, pipe_fds[1], -EBADF }, NULL, 0,
+                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
+                           &pid);
         if (r < 0) {
                 safe_close_pair(pipe_fds);
                 return r;
         }
         if (r == 0) {
-                char *empty_env = NULL;
-
-                pipe_fds[0] = safe_close(pipe_fds[0]);
-
-                if (rearrange_stdio(-EBADF, TAKE_FD(pipe_fds[1]), -EBADF) < 0)
-                        _exit(EXIT_FAILURE);
-
-                (void) close_all_fds(NULL, 0);
-
-                execle("/usr/bin/getent", "getent", database, key, NULL, &empty_env);
-                execle("/bin/getent", "getent", database, key, NULL, &empty_env);
+                execle("/usr/bin/getent", "getent", database, key, NULL, &(char*[1]){});
+                execle("/bin/getent", "getent", database, key, NULL, &(char*[1]){});
                 _exit(EXIT_FAILURE);
         }
 
index c708eb4da8de7b943a6567a02960e67da4e8ccfb..ae851f67f0ca2bc33902ba9ff268d373e09772a1 100644 (file)
@@ -147,16 +147,14 @@ static void *tls_dns_server(void *p) {
                 fd_tls = fd[1];
         }
 
-        r = safe_fork_full("(test-resolved-stream-tls-openssl)", (int[]) { fd_server, fd_tls }, 2,
-                FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG|FORK_REOPEN_LOG, &openssl_pid);
+        r = safe_fork_full("(test-resolved-stream-tls-openssl)",
+                           (int[]) { fd_tls, fd_tls, STDOUT_FILENO },
+                           NULL, 0,
+                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_REOPEN_LOG,
+                           &openssl_pid);
         assert_se(r >= 0);
         if (r == 0) {
                 /* Child */
-                assert_se(dup2(fd_tls, STDIN_FILENO) >= 0);
-                assert_se(dup2(fd_tls, STDOUT_FILENO) >= 0);
-                close(TAKE_FD(fd_server));
-                close(TAKE_FD(fd_tls));
-
                 execlp("openssl", "openssl", "s_server", "-accept", bind_str,
                        "-key", key_path, "-cert", cert_path,
                        "-quiet", "-naccept", "1", NULL);
index ee134146a152695e21407b0556dbac09c71d61d7..3d03eedcf0316865a6267ce1cec7c7a6b4525b39 100644 (file)
@@ -17,6 +17,7 @@
 #include "errno-util.h"
 #include "fd-util.h"
 #include "fileio.h"
+#include "fs-util.h"
 #include "missing_magic.h"
 #include "parse-util.h"
 
@@ -777,3 +778,53 @@ int blockdev_get_sector_size(int fd, uint32_t *ret) {
         *ret = ssz;
         return 0;
 }
+
+int blockdev_get_root(int level, dev_t *ret) {
+        _cleanup_free_ char *p = NULL;
+        dev_t devno;
+        int r;
+
+        /* Returns the device node backing the root file system. Traces through
+         * dm-crypt/dm-verity/... Returns > 0 and the devno of the device on success. If there's no block
+         * device (or multiple) returns 0 and a devno of 0. Failure otherwise.
+         *
+         * If the root mount has been replaced by some form of volatile file system (overlayfs), the original
+         * root block device node is symlinked in /run/systemd/volatile-root. Let's read that here. */
+        r = readlink_malloc("/run/systemd/volatile-root", &p);
+        if (r == -ENOENT) { /* volatile-root not found */
+                r = get_block_device_harder("/", &devno);
+                if (r == -EUCLEAN)
+                        return btrfs_log_dev_root(level, r, "root file system");
+                if (r < 0)
+                        return log_full_errno(level, r, "Failed to determine block device of root file system: %m");
+                if (r == 0) { /* Not backed by a single block device. (Could be NFS or so, or could be multi-device RAID or so) */
+                        r = get_block_device_harder("/usr", &devno);
+                        if (r == -EUCLEAN)
+                                return btrfs_log_dev_root(level, r, "/usr");
+                        if (r < 0)
+                                return log_full_errno(level, r, "Failed to determine block device of /usr/ file system: %m");
+                        if (r == 0) { /* /usr/ not backed by single block device, either. */
+                                log_debug("Neither root nor /usr/ file system are on a (single) block device.");
+
+                                if (ret)
+                                        *ret = 0;
+
+                                return 0;
+                        }
+                }
+        } else if (r < 0)
+                return log_full_errno(level, r, "Failed to read symlink /run/systemd/volatile-root: %m");
+        else {
+                mode_t m;
+                r = device_path_parse_major_minor(p, &m, &devno);
+                if (r < 0)
+                        return log_full_errno(level, r, "Failed to parse major/minor device node: %m");
+                if (!S_ISBLK(m))
+                        return log_full_errno(level, SYNTHETIC_ERRNO(ENOTBLK), "Volatile root device is of wrong type.");
+        }
+
+        if (ret)
+                *ret = devno;
+
+        return 1;
+}
index 5b27d23e8ae77230c2ac7cb8ca5153fa1e8c8c78..ea093c49a6b2d92e7489c1439f83384e68b9adb6 100644 (file)
@@ -56,3 +56,5 @@ int block_device_has_partitions(sd_device *dev);
 int blockdev_reread_partition_table(sd_device *dev);
 
 int blockdev_get_sector_size(int fd, uint32_t *ret);
+
+int blockdev_get_root(int level, dev_t *ret);
index 9a4bac99a173308a85956a6c5b3468590300138b..ce37dd31ceb80da27abd5e3862fda6550d47d24a 100644 (file)
@@ -1436,8 +1436,9 @@ static int run_fsck(int node_fd, const char *fstype) {
 
         r = safe_fork_full(
                         "(fsck)",
+                        NULL,
                         &node_fd, 1, /* Leave the node fd open */
-                        FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_NULL_STDIO|FORK_CLOEXEC_OFF,
+                        FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_CLOEXEC_OFF,
                         &pid);
         if (r < 0)
                 return log_debug_errno(r, "Failed to fork off fsck: %m");
index 8da16f528fe373fc93ff64dd133dff94d6f28be6..98c47d912500c9783cfdd35a6327fe778a0ff630 100644 (file)
@@ -784,6 +784,7 @@ int parse_elf_object(int fd, const char *executable, bool fork_disable_dump, cha
          * system call or interacting with the system in any way, besides reading from
          * the file descriptor and writing into these four pipes. */
         r = safe_fork_full("(sd-parse-elf)",
+                           NULL,
                            (int[]){ fd, error_pipe[1], return_pipe[1], json_pipe[1] },
                            4,
                            FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE|FORK_NEW_USERNS|FORK_WAIT|FORK_REOPEN_LOG,
index 2e8f5b85627a6282bc2a948c7d4ec9b80f74b0d5..40e9342cd5211c24a9e065defc97bf06b4e44ac7 100644 (file)
@@ -487,6 +487,7 @@ int fork_agent(const char *name, const int except[], size_t n_except, pid_t *ret
         /* Spawns a temporary TTY agent, making sure it goes away when we go away */
 
         r = safe_fork_full(name,
+                           NULL,
                            except,
                            n_except,
                            FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_RLIMIT_NOFILE_SAFE,
index 6870654426bfc7dffe821319a67c45d956dd67fa..bd12259da016e787ad76f154e61f824cdf59c4a0 100644 (file)
@@ -1995,6 +1995,8 @@ static int install_info_symlink_wants(
                         install_changes_add(changes, n_changes, q, *s, NULL);
                         if (r >= 0)
                                 r = q;
+
+                        continue;
                 }
 
                 if (!unit_name_is_valid(dst, valid_dst_type)) {
index 6ed35a3ca9983733206f40a2d037952b453ce56c..7bede85752f26a086c911ba47e49d49daff60281 100644 (file)
@@ -316,7 +316,7 @@ int show_man_page(const char *desc, bool null_stdio) {
         } else
                 args[1] = desc;
 
-        r = safe_fork("(man)", FORK_RESET_SIGNALS|FORK_DEATHSIG|(null_stdio ? FORK_NULL_STDIO : 0)|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
+        r = safe_fork("(man)", FORK_RESET_SIGNALS|FORK_DEATHSIG|(null_stdio ? FORK_REARRANGE_STDIO : 0)|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
         if (r < 0)
                 return r;
         if (r == 0) {
index 232d1db7f58b1c96fbec5da1ccad9e2609811959..1eb00717ca7549c1e4b71f8504852832fe916525 100644 (file)
@@ -42,6 +42,7 @@
 #include "string-util.h"
 #include "strv.h"
 #include "time-util.h"
+#include "udev-util.h"
 
 #define BATTERY_LOW_CAPACITY_LEVEL 5
 #define DISCHARGE_RATE_FILEPATH "/var/lib/systemd/sleep/battery_discharge_percentage_rate_per_hour"
@@ -196,8 +197,8 @@ static int read_battery_capacity_percentage(sd_device *dev) {
         return battery_capacity;
 }
 
-/* If battery percentage capacity is <= 5%, return success */
-int battery_is_low(void) {
+/* If a battery whose percentage capacity is <= 5% exists, and we're not on AC power, return success */
+int battery_is_discharging_and_low(void) {
         _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
         sd_device *dev;
         int r;
@@ -206,6 +207,12 @@ int battery_is_low(void) {
          * or Normal in case ACPI is not working properly. In case of no battery
          * 0 will be returned and system will be suspended for 1st cycle then hibernated */
 
+        r = on_ac_power();
+        if (r < 0)
+                log_debug_errno(r, "Failed to check if the system is running on AC, assuming it is not: %m");
+        if (r > 0)
+                return false;
+
         r = battery_enumerator_new(&e);
         if (r < 0)
                 return log_debug_errno(r, "Failed to initialize battery enumerator: %m");
index 99423fe3d37b91c81500720bc6189c72469b7eb1..5c528b890b944ea01ff30ffe4738bd5f2d961239 100644 (file)
@@ -60,7 +60,7 @@ int find_hibernate_location(HibernateLocation **ret_hibernate_location);
 int can_sleep(SleepOperation operation);
 int can_sleep_disk(char **types);
 int can_sleep_state(char **types);
-int battery_is_low(void);
+int battery_is_discharging_and_low(void);
 int get_total_suspend_interval(Hashmap *last_capacity, usec_t *ret);
 int fetch_batteries_capacity_by_name(Hashmap **ret_current_capacity);
 int get_capacity_by_name(Hashmap *capacities_by_name, const char *name);
index 61bd9d26012ae2d0a895fb3e3a6f40c4683295b9..bae4d9d023b0d5c058f4ddf24fa95d2cb55a743c 100644 (file)
@@ -618,7 +618,10 @@ static int remount_with_timeout(MountPoint *m, bool last_try) {
 
         /* Due to the possibility of a remount operation hanging, we fork a child process and set a
          * timeout. If the timeout lapses, the assumption is that the particular remount failed. */
-        r = safe_fork_full("(sd-remount)", pfd, ELEMENTSOF(pfd), FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &pid);
+        r = safe_fork_full("(sd-remount)",
+                           NULL,
+                           pfd, ELEMENTSOF(pfd),
+                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &pid);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -671,7 +674,10 @@ static int umount_with_timeout(MountPoint *m, bool last_try) {
 
         /* Due to the possibility of a umount operation hanging, we fork a child process and set a
          * timeout. If the timeout lapses, the assumption is that the particular umount failed. */
-        r = safe_fork_full("(sd-umount)", pfd, ELEMENTSOF(pfd), FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &pid);
+        r = safe_fork_full("(sd-umount)",
+                           NULL,
+                           pfd, ELEMENTSOF(pfd),
+                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &pid);
         if (r < 0)
                 return r;
         if (r == 0) {
index 9018188cba05052834139562cae96b0e5015c359..f7fee4a14cc8e072eebe74bfd694d0f5e1952416 100644 (file)
@@ -274,7 +274,7 @@ static int custom_timer_suspend(const SleepConfig *sleep_config) {
 
         hibernate_timestamp = usec_add(now(CLOCK_BOOTTIME), sleep_config->hibernate_delay_usec);
 
-        while (battery_is_low() == 0) {
+        while (battery_is_discharging_and_low() == 0) {
                 _cleanup_hashmap_free_ Hashmap *last_capacity = NULL, *current_capacity = NULL;
                 _cleanup_close_ int tfd = -EBADF;
                 struct itimerspec ts = {};
index 821049e667573d6602a03445417e41293671b28d..f336fbd55ed44234f0884ba53631872b494ceb0c 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "alloc-util.h"
 #include "build.h"
+#include "daemon-util.h"
 #include "errno-util.h"
 #include "fd-util.h"
 #include "log.h"
@@ -672,6 +673,7 @@ static int parse_argv(int argc, char *argv[]) {
 
 static int run(int argc, char *argv[]) {
         _cleanup_(context_clear) Context context = {};
+        _unused_ _cleanup_(notify_on_cleanup) const char *notify_stop = NULL;
         int r, n, fd;
 
         log_parse_environment();
@@ -709,6 +711,7 @@ static int run(int argc, char *argv[]) {
                         return r;
         }
 
+        notify_stop = notify_start(NOTIFY_READY, NOTIFY_STOPPING);
         r = sd_event_loop(context.event);
         if (r < 0)
                 return log_error_errno(r, "Failed to run event loop: %m");
index 6bfaf97236db76d1ef0eb2f40bda240d2c92e8ac..86e7311d3c41dff050c86ae288149ae7a1c92595 100644 (file)
@@ -6,6 +6,7 @@
 #include "bus-locator.h"
 #include "format-table.h"
 #include "locale-util.h"
+#include "path-util.h"
 #include "set.h"
 #include "sort-util.h"
 #include "systemctl-list-units.h"
@@ -101,6 +102,26 @@ static void output_legend(const char *type, size_t n_items) {
                 printf("Pass --all to see loaded but inactive %ss, too.\n", type);
 }
 
+static int table_add_triggered(Table *table, char **triggered) {
+        assert(table);
+
+        if (strv_isempty(triggered))
+                return table_add_cell(table, NULL, TABLE_EMPTY, NULL);
+        else if (strv_length(triggered) == 1)
+                return table_add_cell(table, NULL, TABLE_STRING, triggered[0]);
+        else
+                /* This should never happen, currently our socket units can only trigger a
+                 * single unit. But let's handle this anyway, who knows what the future
+                 * brings? */
+                return table_add_cell(table, NULL, TABLE_STRV, triggered);
+}
+
+static char *format_unit_id(const char *unit, const char *machine) {
+        assert(unit);
+
+        return machine ? strjoin(machine, ":", unit) : strdup(unit);
+}
+
 static int output_units_list(const UnitInfo *unit_infos, size_t c) {
         _cleanup_(table_unrefp) Table *table = NULL;
         size_t job_count = 0;
@@ -123,9 +144,8 @@ static int output_units_list(const UnitInfo *unit_infos, size_t c) {
         table_set_ersatz_string(table, TABLE_ERSATZ_DASH);
 
         for (const UnitInfo *u = unit_infos; unit_infos && (size_t) (u - unit_infos) < c; u++) {
-                _cleanup_free_ char *j = NULL;
-                const char *on_underline = "", *on_loaded = "", *on_active = "";
-                const char *on_circle = "", *id;
+                _cleanup_free_ char *id = NULL;
+                const char *on_underline = "", *on_loaded = "", *on_active = "", *on_circle = "";
                 bool circle = false, underline = false;
 
                 if (u + 1 < unit_infos + c &&
@@ -148,14 +168,9 @@ static int output_units_list(const UnitInfo *unit_infos, size_t c) {
                         on_loaded = on_underline;
                 }
 
-                if (u->machine) {
-                        j = strjoin(u->machine, ":", u->id);
-                        if (!j)
-                                return log_oom();
-
-                        id = j;
-                } else
-                        id = u->id;
+                id = format_unit_id(u->id, u->machine);
+                if (!id)
+                        return log_oom();
 
                 r = table_add_many(table,
                                    TABLE_STRING, circle ? special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE) : " ",
@@ -384,33 +399,20 @@ static int output_sockets_list(struct socket_info *socket_infos, size_t cs) {
         table_set_ersatz_string(table, TABLE_ERSATZ_DASH);
 
         for (struct socket_info *s = socket_infos; s < socket_infos + cs; s++) {
-                _cleanup_free_ char *j = NULL;
-                const char *path;
+                _cleanup_free_ char *unit = NULL;
 
-                if (s->machine) {
-                        j = strjoin(s->machine, ":", s->path);
-                        if (!j)
-                                return log_oom();
-                        path = j;
-                } else
-                        path = s->path;
+                unit = format_unit_id(s->id, s->machine);
+                if (!unit)
+                        return log_oom();
 
                 r = table_add_many(table,
-                                        TABLE_STRING, path,
+                                        TABLE_STRING, s->path,
                                         TABLE_STRING, s->type,
-                                        TABLE_STRING, s->id);
+                                        TABLE_STRING, unit);
                 if (r < 0)
                         return table_log_add_error(r);
 
-                if (strv_isempty(s->triggered))
-                        r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
-                else if (strv_length(s->triggered) == 1)
-                        r = table_add_cell(table, NULL, TABLE_STRING, s->triggered[0]);
-                else
-                        /* This should never happen, currently our socket units can only trigger a
-                                * single unit. But let's handle this anyway, who knows what the future
-                                * brings? */
-                        r = table_add_cell(table, NULL, TABLE_STRV, s->triggered);
+                r = table_add_triggered(table, s->triggered);
                 if (r < 0)
                         return table_log_add_error(r);
         }
@@ -615,19 +617,10 @@ static int output_timers_list(struct timer_info *timer_infos, size_t n) {
         table_set_ersatz_string(table, TABLE_ERSATZ_DASH);
 
         for (struct timer_info *t = timer_infos; t < timer_infos + n; t++) {
-                _cleanup_free_ char *j = NULL, *activates = NULL;
-                const char *unit;
-
-                if (t->machine) {
-                        j = strjoin(t->machine, ":", t->id);
-                        if (!j)
-                                return log_oom();
-                        unit = j;
-                } else
-                        unit = t->id;
+                _cleanup_free_ char *unit = NULL;
 
-                activates = strv_join(t->triggered, ", ");
-                if (!activates)
+                unit = format_unit_id(t->id, t->machine);
+                if (!unit)
                         return log_oom();
 
                 r = table_add_many(table,
@@ -635,8 +628,11 @@ static int output_timers_list(struct timer_info *timer_infos, size_t n) {
                                    TABLE_TIMESTAMP_RELATIVE, t->next_elapse,
                                    TABLE_TIMESTAMP, t->last_trigger,
                                    TABLE_TIMESTAMP_RELATIVE, t->last_trigger,
-                                   TABLE_STRING, unit,
-                                   TABLE_STRING, activates);
+                                   TABLE_STRING, unit);
+                if (r < 0)
+                        return table_log_add_error(r);
+
+                r = table_add_triggered(table, t->triggered);
                 if (r < 0)
                         return table_log_add_error(r);
         }
@@ -847,16 +843,11 @@ static int output_automounts_list(struct automount_info *infos, size_t n_infos)
         table_set_ersatz_string(table, TABLE_ERSATZ_DASH);
 
         for (struct automount_info *info = infos; info < infos + n_infos; info++) {
-                _cleanup_free_ char *j = NULL;
-                const char *unit;
+                _cleanup_free_ char *unit = NULL;
 
-                if (info->machine) {
-                        j = strjoin(info->machine, ":", info->id);
-                        if (!j)
-                                return log_oom();
-                        unit = j;
-                } else
-                        unit = info->id;
+                unit = format_unit_id(info->id, info->machine);
+                if (!unit)
+                        return log_oom();
 
                 r = table_add_many(table,
                                    TABLE_STRING, info->what,
@@ -932,3 +923,215 @@ int verb_list_automounts(int argc, char *argv[], void *userdata) {
 
         return r;
 }
+
+struct path_info {
+        const char *machine;
+        const char *id;
+
+        char *path;
+        char *condition;
+
+        /* Note: triggered is a list here, although it almost certainly will always be one
+         * unit. Nevertheless, dbus API allows for multiple values, so let's follow that. */
+        char** triggered;
+};
+
+struct path_infos {
+        size_t count;
+        struct path_info *items;
+};
+
+static int path_info_compare(const struct path_info *a, const struct path_info *b) {
+        int r;
+
+        assert(a);
+        assert(b);
+
+        r = strcasecmp_ptr(a->machine, b->machine);
+        if (r != 0)
+                return r;
+
+        r = path_compare(a->path, b->path);
+        if (r != 0)
+                return r;
+
+        r = strcmp(a->condition, b->condition);
+        if (r != 0)
+                return r;
+
+        return strcasecmp_ptr(a->id, b->id);
+}
+
+static void path_infos_done(struct path_infos *ps) {
+        assert(ps);
+        assert(ps->items || ps->count == 0);
+
+        for (struct path_info *p = ps->items; p < ps->items + ps->count; p++) {
+                free(p->condition);
+                free(p->path);
+                strv_free(p->triggered);
+        }
+
+        free(ps->items);
+}
+
+static int get_paths(sd_bus *bus, const char *unit_path, char ***ret_conditions, char ***ret_paths) {
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_strv_free_ char **conditions = NULL, **paths = NULL;
+        const char *condition, *path;
+        int r, n = 0;
+
+        assert(bus);
+        assert(unit_path);
+        assert(ret_conditions);
+        assert(ret_paths);
+
+        r = sd_bus_get_property(bus,
+                                "org.freedesktop.systemd1",
+                                unit_path,
+                                "org.freedesktop.systemd1.Path",
+                                "Paths",
+                                &error,
+                                &reply,
+                                "a(ss)");
+        if (r < 0)
+                return log_error_errno(r, "Failed to get paths: %s", bus_error_message(&error, r));
+
+        r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        while ((r = sd_bus_message_read(reply, "(ss)", &condition, &path)) > 0) {
+                if (strv_extend(&conditions, condition) < 0)
+                        return log_oom();
+
+                if (strv_extend(&paths, path) < 0)
+                        return log_oom();
+
+                n++;
+        }
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        r = sd_bus_message_exit_container(reply);
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        *ret_conditions = TAKE_PTR(conditions);
+        *ret_paths = TAKE_PTR(paths);
+
+        return n;
+}
+
+static int output_paths_list(struct path_infos *ps) {
+        _cleanup_(table_unrefp) Table *table = NULL;
+        int r;
+
+        assert(ps);
+        assert(ps->items || ps->count == 0);
+
+        table = table_new("path", "condition", "unit", "activates");
+        if (!table)
+                return log_oom();
+
+        table_set_header(table, arg_legend != 0);
+        if (arg_full)
+                table_set_width(table, 0);
+
+        table_set_ersatz_string(table, TABLE_ERSATZ_DASH);
+
+        for (struct path_info *p = ps->items; p < ps->items + ps->count; p++) {
+                _cleanup_free_ char *unit = NULL;
+
+                unit = format_unit_id(p->id, p->machine);
+                if (!unit)
+                        return log_oom();
+
+                r = table_add_many(table,
+                                   TABLE_STRING, p->path,
+                                   TABLE_STRING, p->condition,
+                                   TABLE_STRING, unit);
+                if (r < 0)
+                        return table_log_add_error(r);
+
+                r = table_add_triggered(table, p->triggered);
+                if (r < 0)
+                        return table_log_add_error(r);
+        }
+
+        r = output_table(table);
+        if (r < 0)
+                return r;
+
+        if (arg_legend != 0)
+                output_legend("path", ps->count);
+
+        return 0;
+}
+
+int verb_list_paths(int argc, char *argv[], void *userdata) {
+        _cleanup_(message_set_freep) Set *replies = NULL;
+        _cleanup_strv_free_ char **machines = NULL, **units = NULL;
+        _cleanup_free_ UnitInfo *unit_infos = NULL;
+        _cleanup_(path_infos_done) struct path_infos path_infos = {};
+        int r, n;
+        sd_bus *bus;
+
+        r = acquire_bus(BUS_MANAGER, &bus);
+        if (r < 0)
+                return r;
+
+        pager_open(arg_pager_flags);
+
+        r = expand_unit_names(bus, strv_skip(argv, 1), ".path", &units, NULL);
+        if (r < 0)
+                return r;
+
+        if (argc == 1 || units) {
+                n = get_unit_list_recursive(bus, units, &unit_infos, &replies, &machines);
+                if (n < 0)
+                        return n;
+
+                for (const UnitInfo *u = unit_infos; u < unit_infos + n; u++) {
+                        _cleanup_strv_free_ char **conditions = NULL, **paths = NULL, **triggered = NULL;
+                        int c;
+
+                        if (!endswith(u->id, ".path"))
+                                continue;
+
+                        r = get_triggered_units(bus, u->unit_path, &triggered);
+                        if (r < 0)
+                                return r;
+
+                        c = get_paths(bus, u->unit_path, &conditions, &paths);
+                        if (c < 0)
+                                return c;
+
+                        if (!GREEDY_REALLOC(path_infos.items, path_infos.count + c))
+                                return log_oom();
+
+                        for (int i = c - 1; i >= 0; i--) {
+                                char **t;
+
+                                t = strv_copy(triggered);
+                                if (!t)
+                                        return log_oom();
+
+                                path_infos.items[path_infos.count++] = (struct path_info) {
+                                        .machine = u->machine,
+                                        .id = u->id,
+                                        .condition = TAKE_PTR(conditions[i]),
+                                        .path = TAKE_PTR(paths[i]),
+                                        .triggered = t,
+                                };
+                        }
+                }
+
+                typesafe_qsort(path_infos.items, path_infos.count, path_info_compare);
+        }
+
+        output_paths_list(&path_infos);
+
+        return 0;
+}
index 117b7e378afbfd0af8c662d014a5c7bd9792d2f1..f7353d037e8b5ac499ab635eef8bcd2738080559 100644 (file)
@@ -5,5 +5,6 @@ int verb_list_units(int argc, char *argv[], void *userdata);
 int verb_list_sockets(int argc, char *argv[], void *userdata);
 int verb_list_timers(int argc, char *argv[], void *userdata);
 int verb_list_automounts(int argc, char *argv[], void *userdata);
+int verb_list_paths(int argc, char *argv[], void *userdata);
 
 usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next);
index a752c6dce49a2b8e18fb9ae26e9fa2f7c6b5cc6c..015503657243cb5b3229888459f11732eacfb8bc 100644 (file)
@@ -152,6 +152,8 @@ static int systemctl_help(void) {
                "  list-units [PATTERN...]             List units currently in memory\n"
                "  list-automounts [PATTERN...]        List automount units currently in memory,\n"
                "                                      ordered by path\n"
+               "  list-paths [PATTERN...]             List path units currently in memory,\n"
+               "                                      ordered by path\n"
                "  list-sockets [PATTERN...]           List socket units currently in memory,\n"
                "                                      ordered by address\n"
                "  list-timers [PATTERN...]            List timer units currently in memory,\n"
@@ -1091,6 +1093,7 @@ static int systemctl_main(int argc, char *argv[]) {
                 { "list-units",            VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_ONLINE_ONLY, verb_list_units },
                 { "list-unit-files",       VERB_ANY, VERB_ANY, 0,                verb_list_unit_files         },
                 { "list-automounts",       VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_list_automounts         },
+                { "list-paths",            VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_list_paths              },
                 { "list-sockets",          VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_list_sockets            },
                 { "list-timers",           VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_list_timers             },
                 { "list-jobs",             VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_list_jobs               },
index e1e260addcca52f85a67505c86ace72c43cc4076..6c05d245f8c473d52114e08b3126ac15a9924ac9 100644 (file)
@@ -264,7 +264,11 @@ static int download_manifest(
         log_info("%s Acquiring manifest file %s%s", special_glyph(SPECIAL_GLYPH_DOWNLOAD),
                  suffixed_url, special_glyph(SPECIAL_GLYPH_ELLIPSIS));
 
-        r = safe_fork("(sd-pull)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
+        r = safe_fork_full("(sd-pull)",
+                           (int[]) { -EBADF, pfd[1], STDERR_FILENO },
+                           NULL, 0,
+                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG,
+                           &pid);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -280,14 +284,6 @@ static int download_manifest(
                         NULL
                 };
 
-                pfd[0] = safe_close(pfd[0]);
-
-                r = rearrange_stdio(-EBADF, pfd[1], STDERR_FILENO);
-                if (r < 0) {
-                        log_error_errno(r, "Failed to rearrange stdin/stdout: %m");
-                        _exit(EXIT_FAILURE);
-                }
-
                 (void) unsetenv("NOTIFY_SOCKET");
                 execv(pull_binary_path(), (char *const*) cmdline);
                 log_error_errno(errno, "Failed to execute %s tool: %m", pull_binary_path());
index f6d05afc1bd7dae7cb4f53ffc64520a2599049b6..7363ea95db11557d3c3dea904bdc6c8e48c557b7 100644 (file)
@@ -583,14 +583,12 @@ static int find_libraries(const char *exec, char ***ret) {
         assert_se(pipe2(outpipe, O_NONBLOCK|O_CLOEXEC) == 0);
         assert_se(pipe2(errpipe, O_NONBLOCK|O_CLOEXEC) == 0);
 
-        r = safe_fork("(spawn-ldd)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
+        r = safe_fork_full("(spawn-ldd)",
+                           (int[]) { -EBADF, outpipe[1], errpipe[1] },
+                           NULL, 0,
+                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG, &pid);
         assert_se(r >= 0);
         if (r == 0) {
-                if (rearrange_stdio(-EBADF, TAKE_FD(outpipe[1]), TAKE_FD(errpipe[1])) < 0)
-                        _exit(EXIT_FAILURE);
-
-                (void) close_all_fds(NULL, 0);
-
                 execlp("ldd", "ldd", exec, NULL);
                 _exit(EXIT_FAILURE);
         }
index 9c24ca8204ff255ef78acdc2e05b040269656938..9a0c15dffe4475307b799f43acb522537102e032 100644 (file)
@@ -589,7 +589,7 @@ TEST(safe_fork) {
 
         BLOCK_SIGNALS(SIGCHLD);
 
-        r = safe_fork("(test-child)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_NULL_STDIO|FORK_REOPEN_LOG, &pid);
+        r = safe_fork("(test-child)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_REOPEN_LOG, &pid);
         assert_se(r >= 0);
 
         if (r == 0) {
index ec4ad30824def8c5755d1b92b4912789649d741a..a8d7db40b457214cc94bea7310944d6a95a0f92f 100644 (file)
@@ -810,18 +810,16 @@ int udev_event_spawn(
 
         log_device_debug(event->dev, "Starting '%s'", cmd);
 
-        r = safe_fork("(spawn)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &pid);
+        r = safe_fork_full("(spawn)",
+                           (int[]) { -EBADF, outpipe[WRITE_END], errpipe[WRITE_END] },
+                           NULL, 0,
+                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
+                           &pid);
         if (r < 0)
                 return log_device_error_errno(event->dev, r,
                                               "Failed to fork() to execute command '%s': %m", cmd);
         if (r == 0) {
-                if (rearrange_stdio(-EBADF, TAKE_FD(outpipe[WRITE_END]), TAKE_FD(errpipe[WRITE_END])) < 0)
-                        _exit(EXIT_FAILURE);
-
-                (void) close_all_fds(NULL, 0);
-
                 DEVICE_TRACE_POINT(spawn_exec, event->dev, cmd);
-
                 execve(argv[0], argv, envp);
                 _exit(EXIT_FAILURE);
         }
index 7a660a8ea76060e0c8069eccc8161a35bc1c262b..fde5fbd1de175d6017cf91e33b8448ad340bd7d8 100755 (executable)
@@ -22,3 +22,20 @@ command -v jq >/dev/null || {
 
 "$bootctl" list --json=pretty | jq . >/dev/null
 "$bootctl" list --json=short | jq . >/dev/null
+
+# bootctl --print-root-device should either succeed or fail with exit status 80
+# (because not backed by a single block device), but not fail otherwise.
+"$bootctl" -R || test "$?" -eq 80
+"$bootctl" -RR || test "$?" -eq 80
+
+if "$bootctl" -R > /dev/null ; then
+    P=$("$bootctl" -R)
+    PP=$("$bootctl" -RR)
+
+    echo "$P vs $PP"
+    test -b "$P"
+    test -b "$PP"
+
+    # $P must be a prefix of $PP
+    [[ $P = $PP* ]]
+fi
index 2d438e2748414225e3fc80474125bdefcde084ce..8ff96a1d9710a2a9e6282b6c9c54dcee7a94a528 100755 (executable)
@@ -61,6 +61,9 @@ printf '%b'   '[Service]\n' 'ExecStart=\n' 'ExecStart=sleep 10d' >"+4"
 EDITOR='mv' script -ec 'systemctl edit "$UNIT_NAME"' /dev/null
 printf '%s\n' '[Service]'   'ExecStart='   'ExecStart=sleep 10d' | cmp - "/etc/systemd/system/$UNIT_NAME.d/override.conf"
 
+# Double free when editing a template unit (#26483)
+EDITOR='true' script -ec 'systemctl edit user@0' /dev/null
+
 # Argument help
 systemctl --state help
 systemctl --signal help
@@ -102,6 +105,8 @@ systemctl list-jobs "*"
 systemctl list-dependencies sysinit.target --type=socket,mount
 systemctl list-dependencies multi-user.target --state=active
 systemctl list-dependencies sysinit.target --state=mounted --all
+systemctl list-paths
+systemctl list-paths --legend=no -a "systemd*"
 
 # is-* verbs
 # Should return 4 for a missing unit file
@@ -427,5 +432,17 @@ EOF
     systemctl stop issue-24990
 fi
 
+# %J in WantedBy= causes ABRT (#26467)
+cat >/run/systemd/system/test-WantedBy.service <<EOF
+[Service]
+ExecStart=true
+
+[Install]
+WantedBy=user-%i@%J.service
+EOF
+systemctl daemon-reload
+systemctl enable --now test-WantedBy.service || :
+systemctl daemon-reload
+
 touch /testok
 rm /failed
index 3499d6160f2c73713a508971ca04e2ae940be2c1..a8d3d2422b9aef522ca36ee974654f1e7cd2736d 100755 (executable)
@@ -211,7 +211,10 @@ fi
 # Ensure that sandboxing doesn't stop creds from being accessible
 echo "test" > /tmp/testdata
 systemd-creds encrypt /tmp/testdata /tmp/testdata.encrypted --with-key=tpm2
+# LoadCredentialEncrypted
 systemd-run -p PrivateDevices=yes -p LoadCredentialEncrypted=testdata.encrypted:/tmp/testdata.encrypted --pipe --wait systemd-creds cat testdata.encrypted | cmp - /tmp/testdata
+# SetCredentialEncrypted
+systemd-run -p PrivateDevices=yes -p SetCredentialEncrypted=testdata.encrypted:"$(cat /tmp/testdata.encrypted)" --pipe --wait systemd-creds cat testdata.encrypted | cmp - /tmp/testdata
 rm /tmp/testdata
 
 echo OK >/testok