[Pkg-gpm-devel] Bug#326709: libgpm can bomb the stack hooking to its own signal handlers

Ron ron at debian.org
Mon Sep 5 08:14:26 UTC 2005


Package: gpm
Version: 1.19.6-21
Severity: important
Tags: patch

Hi,

libgpm tries to hook to an existing signal handler for
SIGWINCH and SIGSTP, but doesn't check if its own handler
is already installed.

ncurses now loads libgpm dynamically if available and
would seem to call Gpm_Open more than once.  This leads
to libgpm hooking to its own handler and a stack bomb
when the signal is next raised.

The following code demonstrates the problem:

#include <stdlib.h>
#include <signal.h>
#include <ncurses.h>

main()
{
    initscr();
    mousemask( ALL_MOUSE_EVENTS, NULL );
    printw("Hello World !!!");
    refresh();
    getch();
    raise( SIGWINCH );
    endwin();
    return EXIT_SUCCESS;
}

Build with:
$ LDFLAGS="-lncurses" make demo.c

It will segfault if run in a console controlled by gpm.

The following patch addresses it.  I may NMU shortly applying
only this change as debian/patches/060_dont_hook_our_own_hook
unless requested to do otherwise.

cheers,
Ron


--- gpm-1.19.6/src/liblow.c.orig	2005-09-05 16:29:34.000000000 +0930
+++ gpm-1.19.6/src/liblow.c	2005-09-05 17:09:21.000000000 +0930
@@ -353,28 +353,40 @@
     {
       /* itz Wed Dec 16 23:22:16 PST 1998 use sigaction, the old
          code caused a signal loop under XEmacs */
-      struct sigaction sa;
+      struct sigaction sa, snow;
       sigemptyset(&sa.sa_mask);
 
+      /* We must check if the signals have already been hooked by
+       * this routine, else they will hook back to themselves and
+       * bomb the stack the first time one is raised. */
+
 #if (defined(SIGWINCH))
       /* And the winch hook .. */
-      sa.sa_handler = gpm_winch_hook;
-      sa.sa_flags = 0;
-      sigaction(SIGWINCH, &sa, &gpm_saved_winch_hook);
+      if (sigaction(SIGWINCH, NULL, &snow) == 0
+          && snow.sa_handler != gpm_winch_hook )
+      {
+          sa.sa_handler = gpm_winch_hook;
+          sa.sa_flags = 0;
+          sigaction(SIGWINCH, &sa, &gpm_saved_winch_hook);
+      }
 #endif
 
 #if (defined(SIGTSTP))
       if (gpm_flag == 1) {
-        /* Install suspend hook */
-        sa.sa_handler = SIG_IGN;
-        sigaction(SIGTSTP, &sa, &gpm_saved_suspend_hook);
-
-        /* if signal was originally ignored, job control is not supported */
-        if (gpm_saved_suspend_hook.sa_handler != SIG_IGN) {
-          sa.sa_flags = SA_NOMASK;
-          sa.sa_handler = gpm_suspend_hook;
-          sigaction(SIGTSTP, &sa, 0);
-        } /*if*/
+          if (sigaction(SIGTSTP, NULL, &snow) == 0
+              && snow.sa_handler != gpm_suspend_hook )
+          {
+                /* Install suspend hook */
+                sa.sa_handler = SIG_IGN;
+                sigaction(SIGTSTP, &sa, &gpm_saved_suspend_hook);
+
+                /* if signal was originally ignored, job control is not supported */
+                if (gpm_saved_suspend_hook.sa_handler != SIG_IGN) {
+                  sa.sa_flags = SA_NOMASK;
+                  sa.sa_handler = gpm_suspend_hook;
+                  sigaction(SIGTSTP, &sa, 0);
+                } /*if*/
+          }
       } /*if*/
 #endif
 



-- System Information:
Debian Release: testing/unstable
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.12
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)

Versions of packages gpm depends on:
ii  debconf [debconf-2.0]         1.4.58     Debian configuration management sy
ii  debianutils                   2.14.3     Miscellaneous utilities specific t
ii  libc6                         2.3.5-6    GNU C Library: Shared libraries an
ii  ucf                           2.001      Update Configuration File: preserv

gpm recommends no packages.

-- debconf information excluded




More information about the Pkg-gpm-devel mailing list