Merge tag 'efi-2019-07-rc3-3' of git://git.denx.de/u-boot-efi
[oweals/u-boot.git] / lib / efi_loader / efi_boottime.c
index 967b39b223ce2e12d8cecc64ef88950bc30c2153..54fff85e64efff2e0dc49160331aa8e689b352bc 100644 (file)
@@ -181,10 +181,12 @@ static void efi_queue_event(struct efi_event *event, bool check_tpl)
                /* Check TPL */
                if (check_tpl && efi_tpl >= event->notify_tpl)
                        return;
+               event->is_queued = false;
                EFI_CALL_VOID(event->notify_function(event,
                                                     event->notify_context));
+       } else {
+               event->is_queued = false;
        }
-       event->is_queued = false;
 }
 
 /**
@@ -267,7 +269,7 @@ static unsigned long EFIAPI efi_raise_tpl(efi_uintn_t new_tpl)
        EFI_ENTRY("0x%zx", new_tpl);
 
        if (new_tpl < efi_tpl)
-               debug("WARNING: new_tpl < current_tpl in %s\n", __func__);
+               EFI_PRINT("WARNING: new_tpl < current_tpl in %s\n", __func__);
        efi_tpl = new_tpl;
        if (efi_tpl > TPL_HIGH_LEVEL)
                efi_tpl = TPL_HIGH_LEVEL;
@@ -290,7 +292,7 @@ static void EFIAPI efi_restore_tpl(efi_uintn_t old_tpl)
        EFI_ENTRY("0x%zx", old_tpl);
 
        if (old_tpl > efi_tpl)
-               debug("WARNING: old_tpl > current_tpl in %s\n", __func__);
+               EFI_PRINT("WARNING: old_tpl > current_tpl in %s\n", __func__);
        efi_tpl = old_tpl;
        if (efi_tpl > TPL_HIGH_LEVEL)
                efi_tpl = TPL_HIGH_LEVEL;
@@ -513,10 +515,8 @@ efi_status_t efi_remove_protocol(const efi_handle_t handle,
        ret = efi_search_protocol(handle, protocol, &handler);
        if (ret != EFI_SUCCESS)
                return ret;
-       if (guidcmp(handler->guid, protocol))
-               return EFI_INVALID_PARAMETER;
        if (handler->protocol_interface != protocol_interface)
-               return EFI_INVALID_PARAMETER;
+               return EFI_NOT_FOUND;
        list_del(&handler->link);
        free(handler);
        return EFI_SUCCESS;
@@ -1093,11 +1093,9 @@ static efi_status_t EFIAPI efi_install_protocol_interface(
                r = efi_create_handle(handle);
                if (r != EFI_SUCCESS)
                        goto out;
-               debug("%sEFI: new handle %p\n", indent_string(nesting_level),
-                     *handle);
+               EFI_PRINT("new handle %p\n", *handle);
        } else {
-               debug("%sEFI: handle %p\n", indent_string(nesting_level),
-                     *handle);
+               EFI_PRINT("handle %p\n", *handle);
        }
        /* Add new protocol */
        r = efi_add_protocol(*handle, protocol, protocol_interface);
@@ -1441,7 +1439,7 @@ static efi_status_t efi_locate_handle(
 
        *buffer_size = size;
 
-       /* The buffer size is sufficient but there is not buffer */
+       /* The buffer size is sufficient but there is no buffer */
        if (!buffer)
                return EFI_INVALID_PARAMETER;
 
@@ -1762,7 +1760,7 @@ efi_status_t EFIAPI efi_load_image(bool boot_policy,
        EFI_ENTRY("%d, %p, %pD, %p, %zd, %p", boot_policy, parent_image,
                  file_path, source_buffer, source_size, image_handle);
 
-       if (!image_handle || !parent_image) {
+       if (!image_handle || !efi_search_obj(parent_image)) {
                ret = EFI_INVALID_PARAMETER;
                goto error;
        }
@@ -1771,6 +1769,11 @@ efi_status_t EFIAPI efi_load_image(bool boot_policy,
                ret = EFI_NOT_FOUND;
                goto error;
        }
+       /* The parent image handle must refer to a loaded image */
+       if (!parent_image->type) {
+               ret = EFI_INVALID_PARAMETER;
+               goto error;
+       }
 
        if (!source_buffer) {
                ret = efi_load_image_from_path(file_path, &dest_buffer,
@@ -1778,6 +1781,10 @@ efi_status_t EFIAPI efi_load_image(bool boot_policy,
                if (ret != EFI_SUCCESS)
                        goto error;
        } else {
+               if (!source_size) {
+                       ret = EFI_LOAD_ERROR;
+                       goto error;
+               }
                dest_buffer = source_buffer;
        }
        /* split file_path which contains both the device and file parts */
@@ -1834,11 +1841,11 @@ static void efi_exit_caches(void)
  * Return: status code
  */
 static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
-                                                 unsigned long map_key)
+                                                 efi_uintn_t map_key)
 {
        struct efi_event *evt;
 
-       EFI_ENTRY("%p, %ld", image_handle, map_key);
+       EFI_ENTRY("%p, %zx", image_handle, map_key);
 
        /* Check that the caller has read the current memory map */
        if (map_key != efi_memory_map_key)
@@ -1909,10 +1916,17 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
 static efi_status_t EFIAPI efi_get_next_monotonic_count(uint64_t *count)
 {
        static uint64_t mono;
+       efi_status_t ret;
 
        EFI_ENTRY("%p", count);
+       if (!count) {
+               ret = EFI_INVALID_PARAMETER;
+               goto out;
+       }
        *count = mono++;
-       return EFI_EXIT(EFI_SUCCESS);
+       ret = EFI_SUCCESS;
+out:
+       return EFI_EXIT(ret);
 }
 
 /**
@@ -2254,7 +2268,7 @@ static efi_status_t EFIAPI efi_locate_device_path(
 
        EFI_ENTRY("%pUl, %p, %p", protocol, device_path, device);
 
-       if (!protocol || !device_path || !*device_path || !device) {
+       if (!protocol || !device_path || !*device_path) {
                ret = EFI_INVALID_PARAMETER;
                goto out;
        }
@@ -2287,6 +2301,10 @@ static efi_status_t EFIAPI efi_locate_device_path(
                /* Check if dp is a subpath of device_path */
                if (memcmp(*device_path, dp, len_dp))
                        continue;
+               if (!device) {
+                       ret = EFI_INVALID_PARAMETER;
+                       goto out;
+               }
                *device = handles[i];
                len_best = len_dp;
        }
@@ -2323,6 +2341,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;
 
@@ -2335,6 +2354,20 @@ 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 &&
+                           dp->type == DEVICE_PATH_TYPE_END) {
+                               EFI_PRINT("Path %pD already installed\n",
+                                         protocol_interface);
+                               r = EFI_ALREADY_STARTED;
+                               break;
+                       }
+               }
                r = EFI_CALL(efi_install_protocol_interface(
                                                handle, protocol,
                                                EFI_NATIVE_INTERFACE,
@@ -2442,9 +2475,16 @@ static efi_status_t EFIAPI efi_calculate_crc32(const void *data,
                                               efi_uintn_t data_size,
                                               u32 *crc32_p)
 {
+       efi_status_t ret = EFI_SUCCESS;
+
        EFI_ENTRY("%p, %zu", data, data_size);
+       if (!data || !data_size || !crc32_p) {
+               ret = EFI_INVALID_PARAMETER;
+               goto out;
+       }
        *crc32_p = crc32(0, data, data_size);
-       return EFI_EXIT(EFI_SUCCESS);
+out:
+       return EFI_EXIT(ret);
 }
 
 /**
@@ -2638,8 +2678,15 @@ static efi_status_t EFIAPI efi_open_protocol
        }
 
        r = efi_search_protocol(handle, protocol, &handler);
-       if (r != EFI_SUCCESS)
+       switch (r) {
+       case EFI_SUCCESS:
+               break;
+       case EFI_NOT_FOUND:
+               r = EFI_UNSUPPORTED;
+               goto out;
+       default:
                goto out;
+       }
 
        r = efi_protocol_open(handler, protocol_interface, agent_handle,
                              controller_handle, attributes);
@@ -2706,10 +2753,9 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
                 * missed out steps of EFI_CALL.
                 */
                assert(__efi_entry_check());
-               debug("%sEFI: %lu returned by started image\n",
-                     __efi_nesting_dec(),
-                     (unsigned long)((uintptr_t)image_obj->exit_status &
-                                     ~EFI_ERROR_MASK));
+               EFI_PRINT("%lu returned by started image\n",
+                         (unsigned long)((uintptr_t)image_obj->exit_status &
+                         ~EFI_ERROR_MASK));
                current_image = parent_image;
                return EFI_EXIT(image_obj->exit_status);
        }