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 -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]