efi_loader: check device path in InstallMultipleProtocolInterfaces
authorHeinrich Schuchardt <xypron.glpk@gmx.de>
Thu, 16 May 2019 19:54:04 +0000 (21:54 +0200)
committerHeinrich Schuchardt <xypron.glpk@gmx.de>
Sun, 19 May 2019 06:10:10 +0000 (08:10 +0200)
According to the UEFI spec InstallMultipleProtocolInterfaces() must check
if a device path has already been installed. In this case it must return
EFI_ALREADY_STARTED.

Cf. UEFI SCT II 2.6 A (2017),
3.3.16 InstallMultipleProtocolInterfaces(), 5.1.3.16.1.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
lib/efi_loader/efi_boottime.c

index ec6f5758ded3d7812eb47957ee142be77061affa..d3f21f15b703b51d10b0bcaf1dc803c9609ba4f1 100644 (file)
@@ -2334,6 +2334,7 @@ efi_status_t EFIAPI efi_install_multiple_protocol_interfaces
        efi_va_list argptr;
        const efi_guid_t *protocol;
        void *protocol_interface;
+       efi_handle_t old_handle;
        efi_status_t r = EFI_SUCCESS;
        int i = 0;
 
@@ -2346,6 +2347,17 @@ efi_status_t EFIAPI efi_install_multiple_protocol_interfaces
                if (!protocol)
                        break;
                protocol_interface = efi_va_arg(argptr, void*);
+               /* Check that a device path has not been installed before */
+               if (!guidcmp(protocol, &efi_guid_device_path)) {
+                       struct efi_device_path *dp = protocol_interface;
+
+                       r = EFI_CALL(efi_locate_device_path(protocol, &dp,
+                                                           &old_handle));
+                       if (r == EFI_SUCCESS) {
+                               r = EFI_ALREADY_STARTED;
+                               break;
+                       }
+               }
                r = EFI_CALL(efi_install_protocol_interface(
                                                handle, protocol,
                                                EFI_NATIVE_INTERFACE,