public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Joe Simmons-Talbott <josimmon@redhat.com>
To: libc-alpha@sourceware.org
Subject: Re: [PATCH] elf: dl-load: Get rid of alloca usage.
Date: Tue, 10 Oct 2023 15:07:31 -0400	[thread overview]
Message-ID: <20231010190731.GM4098455@oak> (raw)
In-Reply-To: <20231002132404.249890-1-josimmon@redhat.com>

Ping.

On Mon, Oct 02, 2023 at 09:24:01AM -0400, Joe Simmons-Talbott wrote:
> Replace alloca usage with scratch_buffers.  Change the sematics of
> is_trusted_path_normalize to return 1, 0, or -1 on error.
> ---
>  elf/dl-load.c | 72 ++++++++++++++++++++++++++++++++++++++++++---------
>  1 file changed, 60 insertions(+), 12 deletions(-)
> 
> diff --git a/elf/dl-load.c b/elf/dl-load.c
> index 2923b1141d..c8e135b6e5 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);
> +
> +  if (!scratch_buffer_set_array_size (&sbuf, 1, len + 2))
> +    return -1;
>  
> -  char *npath = (char *) alloca (len + 2);
> +  char *npath = sbuf.data;
>    char *wnp = npath;
> +
>    while (*path != '\0')
>      {
>        if (path[0] == '/')
> @@ -172,12 +180,12 @@ is_trusted_path_normalize (const char *path, size_t len)
>        if (wnp - npath >= system_dirs_len[idx]
>  	  && memcmp (trun, npath, system_dirs_len[idx]) == 0)
>  	/* Found it.  */
> -	return true;
> +	return 1;
>  
>        trun += system_dirs_len[idx] + 1;
>      }
>  
> -  return false;
> +  return 0;
>  }
>  
>  /* Given a substring starting at INPUT, just after the DST '$' start
> @@ -363,7 +371,7 @@ _dl_dst_substitute (struct link_map *l, const char *input, char *result)
>       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))
> +      && is_trusted_path_normalize (result, wp - result) != 1)
>      {
>        *result = '\0';
>        return result;
> @@ -951,6 +959,8 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
>    /* Initialize to keep the compiler happy.  */
>    const char *errstring = NULL;
>    int errval = 0;
> +  struct scratch_buffer sbuf;
> +  scratch_buffer_init (&sbuf);
>  
>    /* Get file information.  To match the kernel behavior, do not fill
>       in this information for the executable in case of an explicit
> @@ -982,6 +992,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
>  	    free ((void *) l->l_phdr);
>  	  free (l);
>  	  free (realname);
> +	  scratch_buffer_free (&sbuf);
>  	  _dl_signal_error (errval, name, NULL, errstring);
>  	}
>  
> @@ -998,6 +1009,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
>  	    free (realname);
>  	    add_name_to_object (l, name);
>  
> +	    scratch_buffer_free (&sbuf);
>  	    return l;
>  	  }
>      }
> @@ -1029,6 +1041,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
>        /* Add the map for the mirrored object to the object list.  */
>        _dl_add_to_namespace_list (l, nsid);
>  
> +      scratch_buffer_free (&sbuf);
>        return l;
>      }
>  #endif
> @@ -1039,6 +1052,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
>  	 loaded.  So return now.  */
>        free (realname);
>        __close_nocancel (fd);
> +      scratch_buffer_free (&sbuf);
>        return NULL;
>      }
>  
> @@ -1071,7 +1085,12 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
>      phdr = (void *) (fbp->buf + header->e_phoff);
>    else
>      {
> -      phdr = alloca (maplength);
> +      if (!scratch_buffer_set_array_size (&sbuf, 1, maplength))
> +	{
> +	  errstring = N_("cannot allocate memory");
> +	  goto lose_errno;
> +	}
> +      phdr = sbuf.data;
>        if ((size_t) __pread64_nocancel (fd, (void *) phdr, maplength,
>  				       header->e_phoff) != maplength)
>  	{
> @@ -1485,7 +1504,10 @@ cannot enable executable stack as shared object requires");
>  
>    /* Skip auditing and debugger notification when called from 'sprof'.  */
>    if (mode & __RTLD_SPROF)
> -    return l;
> +    {
> +      scratch_buffer_free (&sbuf);
> +      return l;
> +    }
>  
>    /* Signal that we are going to add new objects.  */
>    struct r_debug *r = _dl_debug_update (nsid);
> @@ -1515,6 +1537,7 @@ cannot enable executable stack as shared object requires");
>      _dl_audit_objopen (l, nsid);
>  #endif
>  
> +  scratch_buffer_free (&sbuf);
>    return l;
>  }
>  \f
> @@ -1598,6 +1621,8 @@ open_verify (const char *name, int fd,
>    /* Initialize it to make the compiler happy.  */
>    const char *errstring = NULL;
>    int errval = 0;
> +  struct scratch_buffer sbuf;
> +  scratch_buffer_init (&sbuf);
>  
>  #ifdef SHARED
>    /* Give the auditing libraries a chance.  */
> @@ -1660,6 +1685,7 @@ open_verify (const char *name, int fd,
>  	      name = strdupa (realname);
>  	      free (realname);
>  	    }
> +	  scratch_buffer_free (&sbuf);
>  	  __close_nocancel (fd);
>  	  _dl_signal_error (errval, name, NULL, errstring);
>  	}
> @@ -1696,6 +1722,7 @@ open_verify (const char *name, int fd,
>  		 32-bit and 64-bit binaries can be run this might
>  		 happen.  */
>  	      *found_other_class = true;
> +	      scratch_buffer_free (&sbuf);
>  	      __close_nocancel (fd);
>  	      __set_errno (ENOENT);
>  	      return -1;
> @@ -1734,6 +1761,7 @@ open_verify (const char *name, int fd,
>  	}
>        if (! __glibc_likely (elf_machine_matches_host (ehdr)))
>  	{
> +	  scratch_buffer_free (&sbuf);
>  	  __close_nocancel (fd);
>  	  __set_errno (ENOENT);
>  	  return -1;
> @@ -1755,7 +1783,14 @@ open_verify (const char *name, int fd,
>  	phdr = (void *) (fbp->buf + ehdr->e_phoff);
>        else
>  	{
> -	  phdr = alloca (maplength);
> +	  if (!scratch_buffer_set_array_size (&sbuf, 1, maplength))
> +	    {
> +	      errval = errno;
> +	      errstring = N_("cannot allocate memory");
> +	      goto lose;
> +	    }
> +	  phdr = sbuf.data;
> +
>  	  if ((size_t) __pread64_nocancel (fd, (void *) phdr, maplength,
>  					   ehdr->e_phoff) != maplength)
>  	    {
> @@ -1769,6 +1804,7 @@ open_verify (const char *name, int fd,
>  			    (phdr, ehdr->e_phnum, fbp->buf, fbp->len,
>  			     loader, fd)))
>  	{
> +	  scratch_buffer_free (&sbuf);
>  	  __close_nocancel (fd);
>  	  __set_errno (ENOENT);
>  	  return -1;
> @@ -1776,6 +1812,7 @@ open_verify (const char *name, int fd,
>  
>      }
>  
> +  scratch_buffer_free (&sbuf);
>    return fd;
>  }
>  \f
> @@ -1796,13 +1833,18 @@ open_path (const char *name, size_t namelen, int mode,
>    int fd = -1;
>    const char *current_what = NULL;
>    int any = 0;
> +  struct scratch_buffer sbuf;
> +  scratch_buffer_init (&sbuf);
>  
>    if (__glibc_unlikely (dirs == NULL))
>      /* We're called before _dl_init_paths when loading the main executable
>         given on the command line when rtld is run directly.  */
>      return -1;
>  
> -  buf = alloca (max_dirnamelen + max_capstrlen + namelen);
> +  if (!scratch_buffer_set_array_size (&sbuf, 1,
> +	max_dirnamelen + max_capstrlen + namelen))
> +    return -1;
> +  buf = sbuf.data;
>    do
>      {
>        struct r_search_path_elem *this_dir = *dirs;
> @@ -1901,6 +1943,7 @@ open_path (const char *name, size_t namelen, int mode,
>  	  if (*realname != NULL)
>  	    {
>  	      memcpy (*realname, buf, buflen);
> +	      scratch_buffer_free (&sbuf);
>  	      return fd;
>  	    }
>  	  else
> @@ -1908,12 +1951,16 @@ open_path (const char *name, size_t namelen, int mode,
>  	      /* No memory for the name, we certainly won't be able
>  		 to load and link it.  */
>  	      __close_nocancel (fd);
> +	      scratch_buffer_free (&sbuf);
>  	      return -1;
>  	    }
>  	}
>        if (here_any && (err = errno) != ENOENT && err != EACCES)
> -	/* The file exists and is readable, but something went wrong.  */
> -	return -1;
> +	{
> +	  /* The file exists and is readable, but something went wrong.  */
> +          scratch_buffer_free (&sbuf);
> +	  return -1;
> +	}
>  
>        /* Remember whether we found anything.  */
>        any |= here_any;
> @@ -1934,6 +1981,7 @@ open_path (const char *name, size_t namelen, int mode,
>  	sps->dirs = (void *) -1;
>      }
>  
> +  scratch_buffer_free (&sbuf);
>    return -1;
>  }
>  
> -- 
> 2.39.2
> 


  reply	other threads:[~2023-10-10 19:07 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-02 13:24 Joe Simmons-Talbott
2023-10-10 19:07 ` Joe Simmons-Talbott [this message]
2023-10-17 17:50 ` Adhemerval Zanella Netto
2023-10-18 13:31   ` Joe Simmons-Talbott

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=20231010190731.GM4098455@oak \
    --to=josimmon@redhat.com \
    --cc=libc-alpha@sourceware.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).