bug-bash
[Top][All Lists]
Advanced

[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



reply via email to

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