[PATCH v3] elf: dl-load: Get rid of alloca usage.

Joe Simmons-Talbott josimmon@redhat.com
Mon Oct 30 11:57:49 GMT 2023


Ping.

On Thu, Oct 19, 2023 at 01:24:48PM -0400, Joe Simmons-Talbott wrote:
> Replace alloca usage with a scratch_buffer.  Change the semantics of
> is_trusted_path_normalize to return 1, 0, or -1 on error.  Change
> _dl_dst_substitute to return NULL on error and update callers to handle
> the NULL return value.
> ---
> Changes to v2:
> * Remove 3 other alloca removals as separate patches.
> * Use "Memory allocation failure" message rather than a new one.
> * Simplify multiple returns into one.
> * Only call is_trusted_path_normalize if check_for_trusted is set.
> * In expand_dynamic_string_token handle a NULL return from
>   _dl_dst_substitute and free malloc'ed memory.
> * Print an error message in fillin_rpath when
>   expand_dynamic_string_token returns NULL.
> 
>  elf/dl-deps.c |  5 +++--
>  elf/dl-load.c | 50 ++++++++++++++++++++++++++++++++++++++------------
>  2 files changed, 41 insertions(+), 14 deletions(-)
> 
> diff --git a/elf/dl-deps.c b/elf/dl-deps.c
> index 0549b4a4ff..16077384b6 100644
> --- a/elf/dl-deps.c
> +++ b/elf/dl-deps.c
> @@ -100,8 +100,9 @@ DST not allowed in SUID/SGID programs"));				      \
>  						   __dst_cnt));		      \
>  									      \
>  	__result = _dl_dst_substitute (l, __str, __newp);		      \
> -									      \
> -	if (*__result == '\0')						      \
> +	if (__result == NULL)						      \
> +	  _dl_signal_error (0, __str, NULL, N_("Memory allocation failure")); \
> +	else if (*__result == '\0')					      \
>  	  {								      \
>  	    /* The replacement for the DST is not known.  We can't	      \
>  	       processed.  */						      \
> diff --git a/elf/dl-load.c b/elf/dl-load.c
> index 2923b1141d..1133421fd8 100644
> --- a/elf/dl-load.c
> +++ b/elf/dl-load.c
> @@ -21,6 +21,7 @@
>  #include <errno.h>
>  #include <fcntl.h>
>  #include <libintl.h>
> +#include <scratch_buffer.h>
>  #include <stdbool.h>
>  #include <stdlib.h>
>  #include <string.h>
> @@ -124,14 +125,21 @@ static const size_t system_dirs_len[] =
>  };
>  #define nsystem_dirs_len array_length (system_dirs_len)
>  
> -static bool
> +static int
>  is_trusted_path_normalize (const char *path, size_t len)
>  {
>    if (len == 0)
> -    return false;
> +    return 0;
> +
> +  struct scratch_buffer sbuf;
> +  scratch_buffer_init (&sbuf);
>  
> -  char *npath = (char *) alloca (len + 2);
> +  if (!scratch_buffer_set_array_size (&sbuf, 1, len + 2))
> +    return -1;
> +
> +  char *npath = sbuf.data;
>    char *wnp = npath;
> +
>    while (*path != '\0')
>      {
>        if (path[0] == '/')
> @@ -167,17 +175,22 @@ is_trusted_path_normalize (const char *path, size_t len)
>  
>    const char *trun = system_dirs;
>  
> +  int r = 0;
>    for (size_t idx = 0; idx < nsystem_dirs_len; ++idx)
>      {
>        if (wnp - npath >= system_dirs_len[idx]
>  	  && memcmp (trun, npath, system_dirs_len[idx]) == 0)
>  	/* Found it.  */
> -	return true;
> +	{
> +          r = 1;
> +	  break;
> +	}
>  
>        trun += system_dirs_len[idx] + 1;
>      }
>  
> -  return false;
> +  scratch_buffer_free (&sbuf);
> +  return r;
>  }
>  
>  /* Given a substring starting at INPUT, just after the DST '$' start
> @@ -270,7 +283,7 @@ _dl_dst_count (const char *input)
>     least equal to the value returned by DL_DST_REQUIRED.  Note that it
>     is possible for a DT_NEEDED, DT_AUXILIARY, and DT_FILTER entries to
>     have colons, but we treat those as literal colons here, not as path
> -   list delimiters.  */
> +   list delimiters.  Returns NULL on failure.  */
>  char *
>  _dl_dst_substitute (struct link_map *l, const char *input, char *result)
>  {
> @@ -362,11 +375,16 @@ _dl_dst_substitute (struct link_map *l, const char *input, char *result)
>       trusted to have designed this correctly.  Only $ORIGIN is tested in
>       this way because it may be manipulated in some ways with hard
>       links.  */
> -  if (__glibc_unlikely (check_for_trusted)
> -      && !is_trusted_path_normalize (result, wp - result))
> +  if (__glibc_unlikely (check_for_trusted))
>      {
> -      *result = '\0';
> -      return result;
> +      int r = is_trusted_path_normalize (result, wp - result);
> +      if (r == -1)
> +	return NULL;
> +      else if (r == 0)
> +	{
> +	  *result = '\0';
> +	  return result;
> +	}
>      }
>  
>    *wp = '\0';
> @@ -406,7 +424,11 @@ expand_dynamic_string_token (struct link_map *l, const char *input)
>    if (result == NULL)
>      return NULL;
>  
> -  return _dl_dst_substitute (l, input, result);
> +  char *r = _dl_dst_substitute (l, input, result);
> +  if (r == NULL)
> +    free (result);
> +
> +  return r;
>  }
>  
>  
> @@ -485,7 +507,11 @@ fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep,
>  	  /* expand_dynamic_string_token can return NULL in case of empty
>  	     path or memory allocation failure.  */
>  	  if (cp == NULL)
> -	    continue;
> +	    {
> +	      _dl_signal_error (errno, NULL, NULL,
> +			        N_("empty path or memory allocation failure"));
> +	      continue;
> +	    }
>  
>  	  /* Compute the length after dynamic string token expansion and
>  	     ignore empty paths.  */
> -- 
> 2.39.2
> 



More information about the Libc-alpha mailing list