All of lore.kernel.org
 help / color / mirror / Atom feed
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
To: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Cc: u-boot@lists.denx.de, Ilias Apalodimas <ilias.apalodimas@linaro.org>
Subject: Re: [PATCH v2 2/9] efi_loader: fix efi_dp_find_obj()
Date: Wed, 23 Mar 2022 16:18:09 +0900	[thread overview]
Message-ID: <20220323071809.GD49108@laputa> (raw)
In-Reply-To: <20220319091148.142036-3-heinrich.schuchardt@canonical.com>

On Sat, Mar 19, 2022 at 10:11:41AM +0100, Heinrich Schuchardt wrote:
> efi_dp_find_obj() should not return any handle with a partially matching
> device path

If so, please describe so explicitly in the function's description.
See below.

> but the handle with the maximum matching device path.
> 
> Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
> ---
> v2:
> 	new patch
> ---
>  include/efi_loader.h             |   4 +-
>  lib/efi_loader/efi_device_path.c | 110 +++++++++++++++++--------------
>  2 files changed, 63 insertions(+), 51 deletions(-)
> 
> diff --git a/include/efi_loader.h b/include/efi_loader.h
> index 1ffcdfc485..6271d40125 100644
> --- a/include/efi_loader.h
> +++ b/include/efi_loader.h
> @@ -730,8 +730,8 @@ struct efi_device_path *efi_dp_shorten(struct efi_device_path *dp);
>  struct efi_device_path *efi_dp_next(const struct efi_device_path *dp);
>  int efi_dp_match(const struct efi_device_path *a,
>  		 const struct efi_device_path *b);
> -struct efi_object *efi_dp_find_obj(struct efi_device_path *dp,
> -				   struct efi_device_path **rem);
> +efi_handle_t efi_dp_find_obj(struct efi_device_path *dp,
> +			     struct efi_device_path **rem);
>  /* get size of the first device path instance excluding end node */
>  efi_uintn_t efi_dp_instance_size(const struct efi_device_path *dp);
>  /* size of multi-instance device path excluding end node */
> diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
> index ddd5f132ec..aeb5264820 100644
> --- a/lib/efi_loader/efi_device_path.c
> +++ b/lib/efi_loader/efi_device_path.c
> @@ -159,69 +159,81 @@ struct efi_device_path *efi_dp_shorten(struct efi_device_path *dp)
>  	return dp;
>  }
>  
> -static struct efi_object *find_obj(struct efi_device_path *dp, bool short_path,
> -				   struct efi_device_path **rem)
> +/**
> + * find_handle() - find handle by device path
> + *
> + * If @rem is provided, the handle with the longest partial match is returned.
> + *
> + * @dp:		device path to search
> + * @short_path:	use short form device path for matching
> + * @rem:	pointer to receive remaining device path
> + * Return:	matching handle
> + */
> +static efi_handle_t find_handle(struct efi_device_path *dp, bool short_path,
> +			        struct efi_device_path **rem)
>  {
> -	struct efi_object *efiobj;
> -	efi_uintn_t dp_size = efi_dp_instance_size(dp);
> +	efi_handle_t handle, best_handle = NULL;
> +	efi_uintn_t len, best_len = 0;
> +
> +	len = efi_dp_instance_size(dp);
>  
> -	list_for_each_entry(efiobj, &efi_obj_list, link) {
> +	list_for_each_entry(handle, &efi_obj_list, link) {
>  		struct efi_handler *handler;
> -		struct efi_device_path *obj_dp;
> +		struct efi_device_path *dp_current;
> +		efi_uintn_t len_current;
>  		efi_status_t ret;
>  
> -		ret = efi_search_protocol(efiobj,
> -					  &efi_guid_device_path, &handler);
> +		ret = efi_search_protocol(handle, &efi_guid_device_path,
> +					  &handler);
>  		if (ret != EFI_SUCCESS)
>  			continue;
> -		obj_dp = handler->protocol_interface;
> -
> -		do {
> -			if (efi_dp_match(dp, obj_dp) == 0) {
> -				if (rem) {
> -					/*
> -					 * Allow partial matches, but inform
> -					 * the caller.
> -					 */
> -					*rem = ((void *)dp) +
> -						efi_dp_instance_size(obj_dp);
> -					return efiobj;
> -				} else {
> -					/* Only return on exact matches */
> -					if (efi_dp_instance_size(obj_dp) ==
> -					    dp_size)
> -						return efiobj;
> -				}
> -			}
> -
> -			obj_dp = efi_dp_shorten(efi_dp_next(obj_dp));
> -		} while (short_path && obj_dp);
> +		dp_current = handler->protocol_interface;
> +		if (short_path) {
> +			dp_current = efi_dp_shorten(dp_current);
> +			if (!dp_current)
> +				continue;
> +		}
> +		len_current = efi_dp_instance_size(dp_current);
> +		if (rem) {
> +			if (len_current < len)
> +				continue;
> +		} else {
> +			if (len_current != len)
> +				continue;
> +		}
> +		if (memcmp(dp_current, dp, len))
> +			continue;
> +		if (!rem)
> +			return handle;
> +		if (len_current > best_len) {
> +			best_len = len_current;
> +			best_handle = handle;
> +			*rem = (void*)((u8 *)dp + len_current);
> +		}
>  	}
> -
> -	return NULL;
> +	return best_handle;
>  }
>  
> -/*
> - * Find an efiobj from device-path, if 'rem' is not NULL, returns the
> - * remaining part of the device path after the matched object.
> +/**
> + * efi_dp_find_obj() - find handle by device path
> + *
> + * If @rem is provided, the handle with the longest partial match is returned.

What if @rem == NULL.

> + *
> + * @dp:		device path to search
> + * @rem:	pointer to receive remaining device path
> + * Return:	matching handle
>   */
> -struct efi_object *efi_dp_find_obj(struct efi_device_path *dp,
> -				   struct efi_device_path **rem)
> +efi_handle_t efi_dp_find_obj(struct efi_device_path *dp,
> +			     struct efi_device_path **rem)

The return type was also changed.
Why not change the function name to, say, efi_dp_find_handle()
"object" is an internal representation.

-Takahiro Akashi

>  {
> -	struct efi_object *efiobj;
> -
> -	/* 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);
> +	efi_handle_t handle;
>  
> -	/* And now for a fuzzy short match */
> -	if (!efiobj)
> -		efiobj = find_obj(dp, true, rem);
> +	handle = find_handle(dp, false, rem);
> +	if (!handle)
> +		/* Match short form device path */
> +		handle = find_handle(dp, true, rem);
>  
> -	return efiobj;
> +	return handle;
>  }
>  
>  /*
> -- 
> 2.34.1
> 

  reply	other threads:[~2022-03-23  7:18 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-19  9:11 [PATCH v2 0/9] efi_loader: booting via short-form device-path Heinrich Schuchardt
2022-03-19  9:11 ` [PATCH v2 1/9] efi_loader: export efi_dp_shorten() Heinrich Schuchardt
2022-03-21  7:41   ` Ilias Apalodimas
2022-03-23  6:55   ` AKASHI Takahiro
2022-03-19  9:11 ` [PATCH v2 2/9] efi_loader: fix efi_dp_find_obj() Heinrich Schuchardt
2022-03-23  7:18   ` AKASHI Takahiro [this message]
2022-03-19  9:11 ` [PATCH v2 3/9] efi_loader: efi_dp_find_obj() add protocol check Heinrich Schuchardt
2022-03-23  7:26   ` AKASHI Takahiro
2022-03-19  9:11 ` [PATCH v2 4/9] efi_loader: support booting via short-form device-path Heinrich Schuchardt
2022-03-23  7:50   ` AKASHI Takahiro
2022-03-19  9:11 ` [PATCH v2 5/9] efi_loader: use short-form DP for load options Heinrich Schuchardt
2022-03-23  8:18   ` AKASHI Takahiro
2022-03-19  9:11 ` [PATCH v2 6/9] efi_loader: export efi_system_partition_guid Heinrich Schuchardt
2022-03-19  9:11 ` [PATCH v2 7/9] efi_loader: remove efi_disk_is_system_part() Heinrich Schuchardt
2022-03-19  9:11 ` [PATCH v2 8/9] efi_loader: move dtbdump.c, initrddump.c to lib/efi_loader Heinrich Schuchardt
2022-03-23  7:01   ` AKASHI Takahiro
2022-03-19  9:11 ` [PATCH v2 9/9] test: test UEFI boot manager Heinrich Schuchardt
2022-03-25  7:01 ` [PATCH v2 0/9] efi_loader: booting via short-form device-path AKASHI Takahiro
2022-03-25  9:12   ` AKASHI Takahiro

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220323071809.GD49108@laputa \
    --to=takahiro.akashi@linaro.org \
    --cc=heinrich.schuchardt@canonical.com \
    --cc=ilias.apalodimas@linaro.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.