bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bash crashes while handling very long string in parameter expansion


From: Siteshwar Vashisht
Subject: Re: Bash crashes while handling very long string in parameter expansion
Date: Wed, 10 Aug 2016 07:20:39 -0400 (EDT)

----- Original Message -----
> From: "Chet Ramey" <address@hidden>
> To: "Siteshwar Vashisht" <address@hidden>, address@hidden
> Cc: "chet ramey" <address@hidden>
> Sent: Tuesday, August 9, 2016 7:43:54 PM
> Subject: Re: Bash crashes while handling very long string in parameter        
> expansion
> 
> You exceed the hard resource limit for your data segment size, and either
> the kernel kills the process or malloc fails and xmalloc() aborts the
> process.  If malloc fails and returns 0, the shell will attempt to print
> an explanatory message.  If that's not happening, the kernel is killing it.

Bash is not crashing due to exhausting system limits or by kernel OOM killer. 
This bug reproduces on systems that have more than 4 GB RAM. 

Bash uses signed int variable to store return value of strlen() function.  
While doing parameter expansion when string length goes beyond signed int 
limits, it causes a crash with below backtrace :

(gdb) bt
#0  __memmove_sse2_unaligned_erms () at 
../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:364
#1  0x0000000000455a4a in sub_append_string (
    source=0x7ffef75de010 
"\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001."...,
 target=0x74aad0 "\001C\001o\001m\001m\001a\001n\001d\001 
\001O\001u\001t\001p\001u\001t\001 :\001 \001c\001a\001t\001 
\001d\001a\001t\001a\001\061\001g\001 ", 
    indx=0x7fffffffdd30, size=0x7fffffffdd34) at subst.c:722
#2  0x0000000000467bd0 in expand_word_internal (word=0x74cdc0, quoted=1, 
isexp=0, contains_dollar_at=0x7fffffffded0, expanded_something=0x0) at 
subst.c:9068
#3  0x0000000000468db6 in expand_word_internal (word=0x74d0a0, quoted=0, 
isexp=0, contains_dollar_at=0x7fffffffe078, expanded_something=0x7fffffffe07c) 
at subst.c:9387
#4  0x000000000046ac21 in shell_expand_word_list (tlist=0x74d080, eflags=31) at 
subst.c:10490
#5  0x000000000046af10 in expand_word_list_internal (list=0x74a7c0, eflags=31) 
at subst.c:10613
#6  0x000000000046a137 in expand_words (list=0x74a7c0) at subst.c:10135
#7  0x000000000043d7ff in execute_simple_command (simple_command=0x74a7a0, 
pipe_in=-1, pipe_out=-1, async=0, fds_to_close=0x74cc60) at execute_cmd.c:4153
#8  0x0000000000437a4e in execute_command_internal (command=0x74cd70, 
asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x74cc60) at 
execute_cmd.c:802
#9  0x0000000000437030 in execute_command (command=0x74cd70) at 
execute_cmd.c:405
#10 0x0000000000422045 in reader_loop () at eval.c:180
#11 0x000000000041fd8a in main (argc=3, argv=0x7fffffffe458, 
env=0x7fffffffe478) at shell.c:792

(gdb) frame 1
#1  0x0000000000455a4a in sub_append_string (
    source=0x7ffef75de010 
"\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001."...,
 target=0x74aad0 "\001C\001o\001m\001m\001a\001n\001d\001 
\001O\001u\001t\001p\001u\001t\001 :\001 \001c\001a\001t\001 
\001d\001a\001t\001a\001\061\001g\001 ", 
    indx=0x7fffffffdd30, size=0x7fffffffdd34) at subst.c:722
722           FASTCOPY (source, target + *indx, srclen);


(gdb) l 713,722
713
714           srclen = STRLEN (source);
715           if (srclen >= (int)(*size - *indx))
716             {
717               n = srclen + *indx;
718               n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE);
719               target = (char *)xrealloc (target, (*size = n));
720             }
721
722           FASTCOPY (source, target + *indx, srclen);

(gdb) p srclen
$4 = -2147483648

I can see that bash uses signed int variables through out it's code to store 
return value of strlen() function, so such issues may crop up at other places 
too.

> 
> 
> --
> ``The lyf so short, the craft so long to lerne.'' - Chaucer
>                ``Ars longa, vita brevis'' - Hippocrates
> Chet Ramey, UTech, CWRU    address@hidden    http://cnswww.cns.cwru.edu/~chet/
> 

-- 
--
Siteshwar Vashisht



reply via email to

[Prev in Thread] Current Thread [Next in Thread]