[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
su - user Hang!!!! Bug in reading history
From: |
Geng Sheng Liu |
Subject: |
su - user Hang!!!! Bug in reading history |
Date: |
Mon, 08 Jul 2013 13:50:23 +0800 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130216 Thunderbird/17.0.3 |
Hi, All
I met a bug in bash when dealing with one case about bash history.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Setps to reproduce the problem:
create a new user like jack.
setup the 4 factors to reproduce the problem, user with the following
condition would encount this problem.
1.HISTFILESIZE is larger than 0, for example 1000
2.HISTSIZE=0
3..bash_history is not a empty file
4.time stamp is enabled in .bash_history file.
Then we use root user to run su - jack, bash would hang.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I did some investigation and I think it should be a bug of bash.
1. if HISTSIZE=0, then the length of array to store history command in
memory would be zero.
The global variable the_history[history_length] is the array to store
history command, history_length would be set 0 if HISTSIZE=0,
2. if HISTFILESIZE is set to none zero value, for example 1000, bash
would truncate .bash_history size to 1000.
history_truncate_file (".bash_hisotry, 1000);
3. then read_history_range function would be call to put item read from
.bash_history file to array the_history[history_length].
add_history would have this action done,
void
add_history (string)
const char *string;
{
HIST_ENTRY *temp;
if (history_stifled && (history_length == history_max_entries))
{
register int i;
/* If the history is stifled, and history_length is zero,
and it equals history_max_entries, we don't save items. */
if (history_length == 0)
return; <--- we can see that if history_length=0,
add_history would return directly, would not add any item.
4. Then it would add try to add timestamp if they are enable in
.bash_history.
if (HIST_TIMESTAMP_START(line_start) == 0)
{
add_history (line_start);
if (last_ts)
{
add_history_time (last_ts);
last_ts = NULL;
}
}
5. Because add_history did not any thing if history_length = 0. and
add_history_time would meet a wrong array index exception at
hs = the_history[history_length - 1];
it try to read the_history[-1] which does not exist.
void
add_history_time (string)
const char *string;
{
HIST_ENTRY *hs;
hs = the_history[history_length - 1];
FREE (hs->timestamp);
hs->timestamp = savestring (string);
}
6. So the problem happens and shell stops there.
(gdb) where
#0 0x0000000000482027 in add_history_time (string=0x18779b55
"#1357531487") at history.c:322
#1 0x0000000000484d26 in read_history_range (filename=<value optimized
out>, from=0, to=4535) at histfile.c:272
#2 0x000000000044de3e in load_history () at bashhist.c:284
#3 0x000000000041b445 in main (argc=<value optimized out>,
argv=0x7fff6eee2458, env=0x7fff6eee2468) at shell.c:710
(gdb) f
#0 0x0000000000482027 in add_history_time (string=0x18779b55
"#1357531487") at history.c:322
322 hs = the_history[history_length - 1];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Fix:
We should exit add_history_time if history_length=0.
/* Change the time stamp of the most recent history entry to STRING. */
void
add_history_time (string)
const char *string;
{
HIST_ENTRY *hs;
if ( history_length ==0 ) <-----------------------change needs to be
done here to avoid invalid array index if history_length=0.
return;
hs = the_history[history_length - 1];
FREE (hs->timestamp);
hs->timestamp = savestring (string);
}
Gengsheng Liu
RHCE
Redhat GSS Support
- su - user Hang!!!! Bug in reading history,
Geng Sheng Liu <=