summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/efi_loader/efi_device_path.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index b4e2f933cb6..24a4f40c004 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -126,6 +126,7 @@ static struct efi_object *find_obj(struct efi_device_path *dp, bool short_path,
struct efi_device_path **rem)
{
struct efi_object *efiobj;
+ unsigned int dp_size = efi_dp_size(dp);
list_for_each_entry(efiobj, &efi_obj_list, link) {
struct efi_handler *handler;
@@ -141,10 +142,18 @@ static struct efi_object *find_obj(struct efi_device_path *dp, bool short_path,
do {
if (efi_dp_match(dp, obj_dp) == 0) {
if (rem) {
+ /*
+ * Allow partial matches, but inform
+ * the caller.
+ */
*rem = ((void *)dp) +
efi_dp_size(obj_dp);
+ return efiobj;
+ } else {
+ /* Only return on exact matches */
+ if (efi_dp_size(obj_dp) == dp_size)
+ return efiobj;
}
- return efiobj;
}
obj_dp = shorten_path(efi_dp_next(obj_dp));
@@ -164,8 +173,14 @@ struct efi_object *efi_dp_find_obj(struct efi_device_path *dp,
{
struct efi_object *efiobj;
- efiobj = find_obj(dp, false, rem);
+ /* Search for an exact match first */
+ efiobj = find_obj(dp, false, NULL);
+ /* Then for a fuzzy match */
+ if (!efiobj)
+ efiobj = find_obj(dp, false, rem);
+
+ /* And now for a fuzzy short match */
if (!efiobj)
efiobj = find_obj(dp, true, rem);