bug-bash
[Top][All Lists]
Advanced

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

bash-3.2: Bad signal work in readline


From: Roman Rakus
Subject: bash-3.2: Bad signal work in readline
Date: Mon, 19 Jan 2009 16:47:38 +0100
User-agent: Thunderbird 2.0.0.19 (X11/20090105)

It's possible to make bash locked up. It's done by bad signal handling in bash and/or readline. It may happened when bash/readline catch signal in any alloc call. I have changed readline to process signals only in safe point. This appears also in bash-4. I will attach a small reproducer (normally it's nearly impossible to reproduce this bug. With this reproducer patch you can hit ctrl-r and then ctrl-c to see bash locked up) and patch which fix this bug.
--- bash-3.2/lib/readline/isearch.c-orig        2009-01-09 08:08:05.000000000 
+0100
+++ bash-3.2/lib/readline/isearch.c     2009-01-09 08:17:00.000000000 +0100
@@ -220,7 +220,9 @@ _rl_isearch_init (direction)
 
   /* Allocate space for this many lines, +1 for the current input line,
      and remember those lines. */
+{int xc; cxt->lines = NULL; for (xc = 0; xc < 30000000; xc++) { xfree 
(cxt->lines);
   cxt->lines = (char **)xmalloc ((1 + (cxt->hlen = i)) * sizeof (char *));
+}}
   for (i = 0; i < cxt->hlen; i++)
     cxt->lines[i] = hlist[i]->line;
 
diff -up bash-3.2/lib/readline/signals.c.rr bash-3.2/lib/readline/signals.c
--- bash-3.2/lib/readline/signals.c.rr  2009-01-19 15:57:29.000000000 +0100
+++ bash-3.2/lib/readline/signals.c     2009-01-19 16:00:04.000000000 +0100
@@ -111,11 +111,19 @@ static sighandler_cxt old_winch;
 #endif
 
 /* Readline signal handler functions. */
+int catched_signal = 0;
 
 static RETSIGTYPE
 rl_signal_handler (sig)
      int sig;
 {
+  catched_signal = sig;
+  SIGHANDLER_RETURN;
+}
+
+void do_rl_signal_handler (sig)
+{
+  catched_signal = 0;
 #if defined (HAVE_POSIX_SIGNALS)
   sigset_t set;
 #else /* !HAVE_POSIX_SIGNALS */
@@ -192,7 +200,6 @@ rl_signal_handler (sig)
     }
 
   RL_UNSETSTATE(RL_STATE_SIGHANDLER);
-  SIGHANDLER_RETURN;
 }
 
 #if defined (SIGWINCH)
diff -up bash-3.2/lib/readline/readline.h.rr bash-3.2/lib/readline/readline.h
--- bash-3.2/lib/readline/readline.h.rr 2009-01-19 15:57:38.000000000 +0100
+++ bash-3.2/lib/readline/readline.h    2009-01-19 15:58:35.000000000 +0100
@@ -428,6 +428,16 @@ extern int rl_clear_signals PARAMS((void
 extern void rl_cleanup_after_signal PARAMS((void));
 extern void rl_reset_after_signal PARAMS((void));
 extern void rl_free_line_state PARAMS((void));
+extern void do_rl_signal_handler (int);
+extern int catched_signal;
+#define CATCH_SIGNALS()                                                 \
+  do                                                                    \
+    {                                                                   \
+      if (catched_signal)                                               \
+        do_rl_signal_handler (catched_signal);                          \
+    } while (0)
+
+
  
 extern int rl_set_paren_blink_timeout PARAMS((int));
 
diff -up bash-3.2/lib/readline/input.c.rr bash-3.2/lib/readline/input.c
--- bash-3.2/lib/readline/input.c.rr    2009-01-19 15:57:44.000000000 +0100
+++ bash-3.2/lib/readline/input.c       2009-01-19 16:00:33.000000000 +0100
@@ -465,6 +465,7 @@ rl_getc (stream)
 
   while (1)
     {
+      CATCH_SIGNALS ();
 #if defined (__MINGW32__)
       if (isatty (fileno (stream)))
        return (getch ());

reply via email to

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