1. 12 1月, 2023 1 次提交
    • A
      efi: random: combine bootloader provided RNG seed with RNG protocol output · 15f818d4
      Ard Biesheuvel 提交于
      commit 196dff27 upstream.
      
      Instead of blindly creating the EFI random seed configuration table if
      the RNG protocol is implemented and works, check whether such a EFI
      configuration table was provided by an earlier boot stage and if so,
      concatenate the existing and the new seeds, leaving it up to the core
      code to mix it in and credit it the way it sees fit.
      
      This can be used for, e.g., systemd-boot, to pass an additional seed to
      Linux in a way that can be consumed by the kernel very early. In that
      case, the following definitions should be used to pass the seed to the
      EFI stub:
      
      struct linux_efi_random_seed {
            u32     size; // of the 'seed' array in bytes
            u8      seed[];
      };
      
      The memory for the struct must be allocated as EFI_ACPI_RECLAIM_MEMORY
      pool memory, and the address of the struct in memory should be installed
      as a EFI configuration table using the following GUID:
      
      LINUX_EFI_RANDOM_SEED_TABLE_GUID        1ce1e5bc-7ceb-42f2-81e5-8aadf180f57b
      
      Note that doing so is safe even on kernels that were built without this
      patch applied, but the seed will simply be overwritten with a seed
      derived from the EFI RNG protocol, if available. The recommended seed
      size is 32 bytes, and seeds larger than 512 bytes are considered
      corrupted and ignored entirely.
      
      In order to preserve forward secrecy, seeds from previous bootloaders
      are memzero'd out, and in order to preserve memory, those older seeds
      are also freed from memory. Freeing from memory without first memzeroing
      is not safe to do, as it's possible that nothing else will ever
      overwrite those pages used by EFI.
      Reviewed-by: NJason A. Donenfeld <Jason@zx2c4.com>
      [ardb: incorporate Jason's followup changes to extend the maximum seed
             size on the consumer end, memzero() it and drop a needless printk]
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      Signed-off-by: NJason A. Donenfeld <Jason@zx2c4.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      15f818d4
  2. 11 11月, 2022 1 次提交
    • A
      arm64: efi: Force the use of SetVirtualAddressMap() on Altra machines · 550b33cf
      Ard Biesheuvel 提交于
      Ampere Altra machines are reported to misbehave when the SetTime() EFI
      runtime service is called after ExitBootServices() but before calling
      SetVirtualAddressMap(). Given that the latter is horrid, pointless and
      explicitly documented as optional by the EFI spec, we no longer invoke
      it at boot if the configured size of the VA space guarantees that the
      EFI runtime memory regions can remain mapped 1:1 like they are at boot
      time.
      
      On Ampere Altra machines, this results in SetTime() calls issued by the
      rtc-efi driver triggering synchronous exceptions during boot.  We can
      now recover from those without bringing down the system entirely, due to
      commit 23715a26 ("arm64: efi: Recover from synchronous
      exceptions occurring in firmware"). However, it would be better to avoid
      the issue entirely, given that the firmware appears to remain in a funny
      state after this.
      
      So attempt to identify these machines based on the 'family' field in the
      type #1 SMBIOS record, and call SetVirtualAddressMap() unconditionally
      in that case.
      Tested-by: NAlexandru Elisei <alexandru.elisei@gmail.com>
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      550b33cf
  3. 24 10月, 2022 1 次提交
  4. 21 10月, 2022 1 次提交
    • A
      efi: efivars: Fix variable writes without query_variable_store() · 8a254d90
      Ard Biesheuvel 提交于
      Commit bbc6d2c6 ("efi: vars: Switch to new wrapper layer")
      refactored the efivars layer so that the 'business logic' related to
      which UEFI variables affect the boot flow in which way could be moved
      out of it, and into the efivarfs driver.
      
      This inadvertently broke setting variables on firmware implementations
      that lack the QueryVariableInfo() boot service, because we no longer
      tolerate a EFI_UNSUPPORTED result from check_var_size() when calling
      efivar_entry_set_get_size(), which now ends up calling check_var_size()
      a second time inadvertently.
      
      If QueryVariableInfo() is missing, we support writes of up to 64k -
      let's move that logic into check_var_size(), and drop the redundant
      call.
      
      Cc: <stable@vger.kernel.org> # v6.0
      Fixes: bbc6d2c6 ("efi: vars: Switch to new wrapper layer")
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      8a254d90
  5. 27 9月, 2022 4 次提交
    • A
      efi: zboot: create MemoryMapped() device path for the parent if needed · 3c6edd90
      Ard Biesheuvel 提交于
      LoadImage() is supposed to install an instance of the protocol
      EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL onto the loaded image's handle so
      that the program can figure out where it was loaded from. The reference
      implementation even does this (with a NULL protocol pointer) if the call
      to LoadImage() used the source buffer and size arguments, and passed
      NULL for the image device path. Hand rolled implementations of LoadImage
      may behave differently, though, and so it is better to tolerate
      situations where the protocol is missing. And actually, concatenating an
      Offset() node to a NULL device path (as we do currently) is not great
      either.
      
      So in cases where the protocol is absent, or when it points to NULL,
      construct a MemoryMapped() device node as the base node that describes
      the parent image's footprint in memory.
      
      Cc: Daan De Meyer <daandemeyer@fb.com>
      Cc: Jeremy Linton <jeremy.linton@arm.com>
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      3c6edd90
    • A
      efi: libstub: install boot-time memory map as config table · 171539f5
      Ard Biesheuvel 提交于
      Expose the EFI boot time memory map to the kernel via a configuration
      table. This is arch agnostic and enables future changes that remove the
      dependency on DT on architectures that don't otherwise rely on it.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      171539f5
    • A
      efi: libstub: unify initrd loading between architectures · f4dc7fff
      Ard Biesheuvel 提交于
      Use a EFI configuration table to pass the initrd to the core kernel,
      instead of per-arch methods. This cleans up the code considerably, and
      should make it easier for architectures to get rid of their reliance on
      DT for doing EFI boot in the future.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      f4dc7fff
    • A
      efi: libstub: simplify efi_get_memory_map() and struct efi_boot_memmap · eab31265
      Ard Biesheuvel 提交于
      Currently, struct efi_boot_memmap is a struct that is passed around
      between callers of efi_get_memory_map() and the users of the resulting
      data, and which carries pointers to various variables whose values are
      provided by the EFI GetMemoryMap() boot service.
      
      This is overly complex, and it is much easier to carry these values in
      the struct itself. So turn the struct into one that carries these data
      items directly, including a flex array for the variable number of EFI
      memory descriptors that the boot service may return.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      eab31265
  6. 20 9月, 2022 1 次提交
    • A
      efi/libstub: implement generic EFI zboot · a0509109
      Ard Biesheuvel 提交于
      Implement a minimal EFI app that decompresses the real kernel image and
      launches it using the firmware's LoadImage and StartImage boot services.
      This removes the need for any arch-specific hacks.
      
      Note that on systems that have UEFI secure boot policies enabled,
      LoadImage/StartImage require images to be signed, or their hashes known
      a priori, in order to be permitted to boot.
      
      There are various possible strategies to work around this requirement,
      but they all rely either on overriding internal PI/DXE protocols (which
      are not part of the EFI spec) or omitting the firmware provided
      LoadImage() and StartImage() boot services, which is also undesirable,
      given that they encapsulate platform specific policies related to secure
      boot and measured boot, but also related to memory permissions (whether
      or not and which types of heap allocations have both write and execute
      permissions.)
      
      The only generic and truly portable way around this is to simply sign
      both the inner and the outer image with the same key/cert pair, so this
      is what is implemented here.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      a0509109
  7. 17 9月, 2022 1 次提交
    • A
      efi/libstub: add some missing EFI prototypes · c7007d9f
      Ard Biesheuvel 提交于
      Define the correct prototypes for the load_image, start_image and
      unload_image boot service pointers so we can call them from the EFI
      zboot code.
      
      Also add some prototypes related to installation and deinstallation of
      protocols in to the EFI protocol database, including some definitions
      related to device paths.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      c7007d9f
  8. 29 6月, 2022 1 次提交
  9. 25 6月, 2022 7 次提交
    • A
      efi: vars: Move efivar caching layer into efivarfs · 2d82e622
      Ard Biesheuvel 提交于
      Move the fiddly bits of the efivar layer into its only remaining user,
      efivarfs, and confine its use to that particular module. All other uses
      of the EFI variable store have no need for this additional layer of
      complexity, given that they either only read variables, or read and
      write variables into a separate GUIDed namespace, and cannot be used to
      manipulate EFI variables that are covered by the EFI spec and/or affect
      the boot flow.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      2d82e622
    • A
      efi: vars: Drop __efivar_entry_iter() helper which is no longer used · 5ac94136
      Ard Biesheuvel 提交于
      __efivar_entry_iter() uses a list iterator in a dubious way, i.e., it
      assumes that the iteration variable always points to an object of the
      appropriate type, even if the list traversal exhausts the list
      completely, in which case it will point somewhere in the vicinity of the
      list's anchor instead.
      
      Fortunately, we no longer use this function so we can just get rid of it
      entirely.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      5ac94136
    • A
      efi: vars: Use locking version to iterate over efivars linked lists · 3a75f9f2
      Ard Biesheuvel 提交于
      Both efivars and efivarfs uses __efivar_entry_iter() to go over the
      linked list that shadows the list of EFI variables held by the firmware,
      but fail to call the begin/end helpers that are documented as a
      prerequisite.
      
      So switch to the proper version, which is efivar_entry_iter(). Given
      that in both cases, efivar_entry_remove() is invoked with the lock held
      already, don't take the lock there anymore.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      3a75f9f2
    • A
      efi: vars: Remove deprecated 'efivars' sysfs interface · 0f5b2c69
      Ard Biesheuvel 提交于
      Commit 5d9db883 ("efi: Add support for a UEFI variable filesystem")
      dated Oct 5, 2012, introduced a new efivarfs pseudo-filesystem to
      replace the efivars sysfs interface that was used up to that point to
      expose EFI variables to user space.
      
      The main problem with the sysfs interface was that it only supported up
      to 1024 bytes of payload per file, whereas the underlying variables
      themselves are only bounded by a platform specific per-variable and
      global limit that is typically much higher than 1024 bytes.
      
      The deprecated sysfs interface is only enabled on x86 and Itanium, other
      EFI enabled architectures only support the efivarfs pseudo-filesystem.
      
      So let's finally rip off the band aid, and drop the old interface
      entirely. This will make it easier to refactor and clean up the
      underlying infrastructure that is shared between efivars, efivarfs and
      efi-pstore, and is long overdue for a makeover.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      0f5b2c69
    • A
      efi: pstore: Omit efivars caching EFI varstore access layer · 85974825
      Ard Biesheuvel 提交于
      Avoid the efivars layer and simply call the newly introduced EFI
      varstore helpers instead. This simplifies the code substantially, and
      also allows us to remove some hacks in the shared efivars layer that
      were added for efi-pstore specifically.
      
      In order to be able to delete the EFI variable associated with a record,
      store the UTF-16 name of the variable in the pstore record's priv field.
      That way, we don't have to make guesses regarding which variable the
      record may have been loaded from.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      85974825
    • A
      efi: vars: Add thin wrapper around EFI get/set variable interface · 472831d4
      Ard Biesheuvel 提交于
      The current efivars layer is a jumble of list iterators, shadow data
      structures and safe variable manipulation helpers that really belong in
      the efivarfs pseudo file system once the obsolete sysfs access method to
      EFI variables is removed.
      
      So split off a minimal efivar get/set variable API that reuses the
      existing efivars_lock semaphore to mediate access to the various runtime
      services, primarily to ensure that performing a SetVariable() on one CPU
      while another is calling GetNextVariable() in a loop to enumerate the
      contents of the EFI variable store does not result in surprises.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      472831d4
    • A
      efi: vars: Don't drop lock in the middle of efivar_init() · ec3507b2
      Ard Biesheuvel 提交于
      Even though the efivars_lock lock is documented as protecting the
      efivars->ops pointer (among other things), efivar_init() happily
      releases and reacquires the lock for every EFI variable that it
      enumerates. This used to be needed because the lock was originally a
      spinlock, which prevented the callback that is invoked for every
      variable from being able to sleep. However, releasing the lock could
      potentially invalidate the ops pointer, but more importantly, it might
      allow a SetVariable() runtime service call to take place concurrently,
      and the UEFI spec does not define how this affects an enumeration that
      is running in parallel using the GetNextVariable() runtime service,
      which is what efivar_init() uses.
      
      In the meantime, the lock has been converted into a semaphore, and the
      only reason we need to drop the lock is because the efivarfs pseudo
      filesystem driver will otherwise deadlock when it invokes the efivars
      API from the callback to create the efivar_entry items and insert them
      into the linked list. (EFI pstore is affected in a similar way)
      
      So let's switch to helpers that can be used while the lock is already
      taken. This way, we can hold on to the lock throughout the enumeration.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      ec3507b2
  10. 15 6月, 2022 1 次提交
  11. 19 5月, 2022 1 次提交
  12. 03 5月, 2022 2 次提交
  13. 14 4月, 2022 2 次提交
  14. 07 4月, 2022 1 次提交
    • B
      x86/boot: Add Confidential Computing type to setup_data · 5ea98e01
      Brijesh Singh 提交于
      While launching encrypted guests, the hypervisor may need to provide
      some additional information during the guest boot. When booting under an
      EFI-based BIOS, the EFI configuration table contains an entry for the
      confidential computing blob that contains the required information.
      
      To support booting encrypted guests on non-EFI VMs, the hypervisor
      needs to pass this additional information to the guest kernel using a
      different method.
      
      For this purpose, introduce SETUP_CC_BLOB type in setup_data to hold
      the physical address of the confidential computing blob location. The
      boot loader or hypervisor may choose to use this method instead of an
      EFI configuration table. The CC blob location scanning should give
      preference to a setup_data blob over an EFI configuration table.
      
      In AMD SEV-SNP, the CC blob contains the address of the secrets and
      CPUID pages. The secrets page includes information such as a VM to PSP
      communication key and the CPUID page contains PSP-filtered CPUID values.
      Define the AMD SEV confidential computing blob structure.
      
      While at it, define the EFI GUID for the confidential computing blob.
      
        [ bp: Massage commit message, mark struct __packed. ]
      Signed-off-by: NBrijesh Singh <brijesh.singh@amd.com>
      Signed-off-by: NBorislav Petkov <bp@suse.de>
      Acked-by: NArd Biesheuvel <ardb@kernel.org>
      Link: https://lore.kernel.org/r/20220307213356.2797205-30-brijesh.singh@amd.com
      5ea98e01
  15. 05 3月, 2022 1 次提交
  16. 28 12月, 2021 1 次提交
    • C
      efi: Introduce EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER and corresponding structures · 1882de7f
      Chen Yu 提交于
      Platform Firmware Runtime Update image starts with UEFI headers, and the
      headers are defined in UEFI specification, but some of them have not been
      defined in the kernel yet.
      
      For example, the header layout of a capsule file looks like this:
      
      EFI_CAPSULE_HEADER
      EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER
      EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER
      EFI_FIRMWARE_IMAGE_AUTHENTICATION
      
      These structures would be used by the Platform Firmware Runtime Update
      driver to parse the format of capsule file to verify if the corresponding
      version number is valid. In this way, if the user provides an invalid
      capsule image, the kernel could be used as a guard to reject it, without
      switching to the Management Mode (which might be costly).
      
      EFI_CAPSULE_HEADER has been defined in the kernel, but the other
      structures have not been defined yet, so do that. Besides,
      EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER and
      EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER are required to be packed
      in the uefi specification. For this reason, use the __packed attribute
      to indicate to the compiler that the entire structure can appear
      misaligned in memory (as suggested by Ard) in case one of them follows
      the other directly in a capsule header.
      Acked-by: NArd Biesheuvel <ardb@kernel.org>
      Signed-off-by: NChen Yu <yu.c.chen@intel.com>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      1882de7f
  17. 13 12月, 2021 1 次提交
  18. 22 11月, 2021 1 次提交
  19. 11 11月, 2021 1 次提交
  20. 19 3月, 2021 1 次提交
    • A
      efi: use 32-bit alignment for efi_guid_t literals · fb98cc0b
      Ard Biesheuvel 提交于
      Commit 494c704f ("efi: Use 32-bit alignment for efi_guid_t") updated
      the type definition of efi_guid_t to ensure that it always appears
      sufficiently aligned (the UEFI spec is ambiguous about this, but given
      the fact that its EFI_GUID type is defined in terms of a struct carrying
      a uint32_t, the natural alignment is definitely >= 32 bits).
      
      However, we missed the EFI_GUID() macro which is used to instantiate
      efi_guid_t literals: that macro is still based on the guid_t type,
      which does not have a minimum alignment at all. This results in warnings
      such as
      
        In file included from drivers/firmware/efi/mokvar-table.c:35:
        include/linux/efi.h:1093:34: warning: passing 1-byte aligned argument to
            4-byte aligned parameter 2 of 'get_var' may result in an unaligned pointer
            access [-Walign-mismatch]
                status = get_var(L"SecureBoot", &EFI_GLOBAL_VARIABLE_GUID, NULL, &size,
                                                ^
        include/linux/efi.h:1101:24: warning: passing 1-byte aligned argument to
            4-byte aligned parameter 2 of 'get_var' may result in an unaligned pointer
            access [-Walign-mismatch]
                get_var(L"SetupMode", &EFI_GLOBAL_VARIABLE_GUID, NULL, &size, &setupmode);
      
      The distinction only matters on CPUs that do not support misaligned loads
      fully, but 32-bit ARM's load-multiple instructions fall into that category,
      and these are likely to be emitted by the compiler that built the firmware
      for loading word-aligned 128-bit GUIDs from memory
      
      So re-implement the initializer in terms of our own efi_guid_t type, so that
      the alignment becomes a property of the literal's type.
      
      Fixes: 494c704f ("efi: Use 32-bit alignment for efi_guid_t")
      Reported-by: NNathan Chancellor <nathan@kernel.org>
      Reviewed-by: NNick Desaulniers <ndesaulniers@google.com>
      Reviewed-by: NNathan Chancellor <nathan@kernel.org>
      Tested-by: NNathan Chancellor <nathan@kernel.org>
      Link: https://github.com/ClangBuiltLinux/linux/issues/1327Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      fb98cc0b
  21. 20 1月, 2021 2 次提交
  22. 18 1月, 2021 1 次提交
  23. 14 12月, 2020 1 次提交
    • A
      efi: ia64: disable the capsule loader · e0a6aa30
      Ard Biesheuvel 提交于
      EFI capsule loading is a feature that was introduced into EFI long after
      its initial introduction on Itanium, and it is highly unlikely that IA64
      systems are receiving firmware updates in the first place, let alone
      using EFI capsules.
      
      So let's disable capsule support altogether on IA64. This fixes a build
      error on IA64 due to a recent change that added an unconditional
      include of asm/efi.h, which IA64 does not provide.
      
      While at it, tweak the make rules a bit so that the EFI capsule
      component that is always builtin (even if the EFI capsule loader itself
      is built as a module) is omitted for all architectures if the module is
      not enabled in the build.
      
      Cc: Tony Luck <tony.luck@intel.com>
      Link: https://lore.kernel.org/linux-efi/20201214152200.38353-1-ardb@kernel.orgSigned-off-by: NArd Biesheuvel <ardb@kernel.org>
      e0a6aa30
  24. 05 11月, 2020 1 次提交
  25. 30 9月, 2020 3 次提交
    • A
      efi: efivars: un-export efivars_sysfs_init() · 5d3c8617
      Ard Biesheuvel 提交于
      efivars_sysfs_init() is only used locally in the source file that
      defines it, so make it static and unexport it.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      5d3c8617
    • A
      efi: pstore: move workqueue handling out of efivars · c9b51a2d
      Ard Biesheuvel 提交于
      The worker thread that gets kicked off to sync the state of the
      EFI variable list is only used by the EFI pstore implementation,
      and is defined in its source file. So let's move its scheduling
      there as well. Since our efivar_init() scan will bail on duplicate
      entries, there is no need to disable the workqueue like we did
      before, so we can run it unconditionally.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      c9b51a2d
    • A
      efi: pstore: disentangle from deprecated efivars module · 232f4eb6
      Ard Biesheuvel 提交于
      The EFI pstore implementation relies on the 'efivars' abstraction,
      which encapsulates the EFI variable store in a way that can be
      overridden by other backing stores, like the Google SMI one.
      
      On top of that, the EFI pstore implementation also relies on the
      efivars.ko module, which is a separate layer built on top of the
      'efivars' abstraction that exposes the [deprecated] sysfs entries
      for each variable that exists in the backing store.
      
      Since the efivars.ko module is deprecated, and all users appear to
      have moved to the efivarfs file system instead, let's prepare for
      its removal, by removing EFI pstore's dependency on it.
      Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
      232f4eb6
  26. 26 9月, 2020 1 次提交