DOS / Prevent crashes due to asynchronous signals

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

 



DOS protected mode applications have a nasty habit of crashing every 
now and then when an asynchronous signal is delivered. This patch 
finally cures the bug. The problem was that during interrupt handling,
application calls 16-bit-to-Wine relay using linear code segment. This
makes asynchronous signal handler think that it interrupted application
in 32-bit context and the signal handler did not try to fix FS segment.
Following NtCurrentTeb call would then crash Wine.

Also, for some reason all other asynchronous signals are blocked
in signal handlers, except SIGUSR2 which is used by dosvm to deliver IRQs 
to DOS applications. Since nested signal handling is not needed by DOS 
and it is a likely source of hard to find bugs, this patch blocks
SIGUSR2 in signal handlers.



Changelog:
  When asynchronous signals are blocked, block also SIGUSR2.
  Fix race that made signal handler forget to restore FS register.



Index: dlls/ntdll/signal_i386.c
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/signal_i386.c,v
retrieving revision 1.49
diff -u -r1.49 signal_i386.c
--- dlls/ntdll/signal_i386.c	10 Dec 2002 22:56:45 -0000	1.49
+++ dlls/ntdll/signal_i386.c	11 Dec 2002 18:59:46 -0000
@@ -549,8 +549,16 @@
     context->SegFs = fs;
 
     /* now restore a proper %fs for the fault handler */
-    if (!IS_SELECTOR_SYSTEM(CS_sig(sigcontext)))  /* 16-bit mode */
+    if (!IS_SELECTOR_SYSTEM(CS_sig(sigcontext)) ||
+        !IS_SELECTOR_SYSTEM(SS_sig(sigcontext)))  /* 16-bit mode */
     {
+        /*
+         * Win16 or DOS protected mode. Note that during switch 
+         * from 16-bit mode to linear mode, CS may be set to system 
+         * segment before FS is restored. Fortunately, in this case 
+         * SS is still non-system segment. This is why both CS and SS
+         * are checked.
+         */
         fs = SYSLEVEL_Win16CurrentTeb;
     }
 #ifdef __HAVE_VM86
@@ -1079,6 +1087,7 @@
         sig_act.ksa_handler = func;
         sig_act.ksa_flags   = SA_RESTART;
         sig_act.ksa_mask    = (1 << (SIGINT-1)) |
+                              (1 << (SIGUSR2-1)) |
                               (1 << (SIGALRM-1));
         /* point to the top of the stack */
         sig_act.ksa_restorer = (char *)NtCurrentTeb()->signal_stack + SIGNAL_STACK_SIZE;
@@ -1088,6 +1097,7 @@
     sig_act.sa_handler = func;
     sigemptyset( &sig_act.sa_mask );
     sigaddset( &sig_act.sa_mask, SIGINT );
+    sigaddset( &sig_act.sa_mask, SIGUSR2 );
     sigaddset( &sig_act.sa_mask, SIGALRM );
 
 #ifdef linux




-- 
Jukka Heinonen <http://www.iki.fi/jhei/>


[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux