This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Don't allow attackers to inject arbitrary data into stack through LD_DEBUG


On Sun, Aug 09, 2015 at 10:59:05PM +0200, Alex Dowad wrote:
> C programs which use uninitialized stack variables can be exploited if an attacker
> can control the contents of memory where the buggy function's stack frame lands.
> If the buggy function is called very early in the program's execution, that memory
> might still hold values written by ld.so, so manipulation of ld.so is one way to
> carry out such an exploit.
> 
> But how can an unprivileged user, running a set-UID program, cause ld.so to write
> arbitrary data onto the stack? One way is to assign it to LD_DEBUG. When printing the
> resulting warning message, ld.so uses alloca to create a buffer on the stack, and
> copies the entire contents of LD_DEBUG into it (even if it is dozens of kilobytes long).
> 
> Of course, people shouldn't write programs which use uninitialized variables, but it
> is easy enough to plug this hole if they do -- zero out the buffer after printing the
> warning message. Call it the "pants and suspenders" approach.
> ---
> 
> Dear GLibc devs,
> 
> Does this look like something you might be interested in merging? I've never contributed
> before, and haven't filled in any copyright attribution papers, but am happy to do so
> if necessary.
> 
> I discovered this issue while playing through a hacking "wargame" where players must
> develop exploits against programs with deliberately planted security vulnerabilities.
> It helped me "beat" the game by achieving a privilege escalation.
> 
> Regards,
> Alex Dowad
> 
>  elf/rtld.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/elf/rtld.c b/elf/rtld.c
> index 6dcbabc..ee194a6 100644
> --- a/elf/rtld.c
> +++ b/elf/rtld.c
> @@ -2408,6 +2408,8 @@ process_dl_debug (const char *dl_debug)
>  	      char *copy = strndupa (dl_debug, len);
>  	      _dl_error_printf ("\
>  warning: debug option `%s' unknown; try LD_DEBUG=help\n", copy);
> +	      /* Don't let an attacker inject arbitrary data into the stack area */
> +	      __builtin_memset(copy, 0, len);
>  	    }
>  
>  	  dl_debug += len;

This memset will be optimized out by any decent compiler. Some
mechanism to prevent that is needed.

BTW are you sure you haven't uncovered a much more serious bug?
Unbounded alloca allows the clobbering of arbitrary memory. While it's
not entirely unbounded, the environment/argv size limit was removed on
modern Linux, so it's quite possible to have multi-MB or even GB
strings there. It's possible/likely that we got lucky and get an
unconditional crash at a point where there's only one thread and no
signal handlers, but I still think this should be checked and the
bogus alloca removed.

Rich


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]