Fix 386 register save/restore (FS & GS destroyed across EXEC - SF bug: 3090610)

Involves:
* before calling INT24 restore 386 registers. Protect again when
  re-entering DOS for "(A)bort"
* INT21/AH=4C and variations restore 386 registers from the user stack
* INT23 (ctrl-break) restores 386 registers
* INT2F/AH=14 protects 386 registers.
* EXECRH is marked to potentially modify FS/GS for OW.


git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@1591 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Bart Oldeman 2011-05-06 01:46:55 +00:00
parent ed61be3ca3
commit cd79fe5f31
6 changed files with 53 additions and 31 deletions

View File

@ -492,7 +492,12 @@ COUNT block_error(request * rq, COUNT nDrive, struct dhdr FAR * lpDevice, int mo
WORD ASMCFUNC FAR clk_driver(rqptr rp); WORD ASMCFUNC FAR clk_driver(rqptr rp);
/* execrh.asm */ /* execrh.asm */
#if defined(__WATCOMC__) && _M_IX86 >= 300
WORD execrh(request FAR *, struct dhdr FAR *);
#pragma aux execrh "^" parm reverse routine [] modify [ax bx cx dx es fs gs]
#else
WORD ASMPASCAL execrh(request FAR *, struct dhdr FAR *); WORD ASMPASCAL execrh(request FAR *, struct dhdr FAR *);
#endif
/* /*
* end of device.h * end of device.h

View File

@ -136,17 +136,33 @@ irp_hi equ 26
%macro Protect386Registers 0 %macro Protect386Registers 0
%endmacro %endmacro
%macro RestoreSP 0
mov sp, bp
%endmacro
%macro Restore386Registers 0 %macro Restore386Registers 0
%endmacro %endmacro
%ELSE %ELSE
%macro Protect386Registers 0
%ifdef WATCOM %ifdef WATCOM
%macro Protect386Registers 0
push fs push fs
push gs push gs
%endmacro
%macro RestoreSP 0
lea sp, [bp-4]
%endmacro
%macro Restore386Registers 0
pop gs
pop fs
%endmacro
%else %else
%macro Protect386Registers 0
push eax push eax
pop ax pop ax
%ifdef MSCL8 %ifdef MSCL8
@ -158,16 +174,13 @@ irp_hi equ 26
%endif %endif
push edx push edx
pop dx pop dx
%endif %endmacro
%macro RestoreSP 0
lea sp, [bp-6]
%endmacro %endmacro
%macro Restore386Registers 0 %macro Restore386Registers 0
%ifdef WATCOM
pop gs
pop fs
%else
push dx push dx
pop edx pop edx
%ifdef MSCL8 %ifdef MSCL8
@ -179,8 +192,7 @@ irp_hi equ 26
%endif %endif
push ax push ax
pop eax pop eax
%endif
%endmacro %endmacro
%endif
%ENDIF %ENDIF

View File

@ -251,7 +251,6 @@ reloc_call_int21_handler:
sti sti
PUSH$ALL PUSH$ALL
mov bp,sp mov bp,sp
Protect386Registers
; ;
; Create kernel reference frame. ; Create kernel reference frame.
; ;
@ -259,6 +258,7 @@ reloc_call_int21_handler:
; until later when which stack to run on is determined. ; until later when which stack to run on is determined.
; ;
int21_reentry: int21_reentry:
Protect386Registers
mov dx,[cs:_DGROUP_] mov dx,[cs:_DGROUP_]
mov ds,dx mov ds,dx
@ -378,17 +378,11 @@ int21_exit_nodec:
pop bp ; get back user stack pop bp ; get back user stack
pop si pop si
%if XCPU >= 386 global _int21_iret
%ifdef WATCOM _int21_iret:
sub bp, byte 4 ; for fs and gs only
%else
sub bp, byte 6 ; high parts of eax, ebx or ecx, edx
%endif
%endif
cli cli
mov ss,si mov ss,si
mov sp,bp RestoreSP
int21_ret: int21_ret:
Restore386Registers Restore386Registers
@ -557,7 +551,7 @@ CritErr05:
; make bp:si point to dev header ; make bp:si point to dev header
; ;
mov si,word [bp+10] ; lpDevice Offset mov si,word [bp+10] ; lpDevice Offset
mov bp,word [bp+12] ; lpDevice segment mov cx,word [bp+12] ; lpDevice segment
; ;
; Now save real ss:sp and retry info in internal stack ; Now save real ss:sp and retry info in internal stack
; ;
@ -580,7 +574,10 @@ CritErr05:
; switch to user's stack ; switch to user's stack
; ;
mov ss,[es:PSP_USERSS] mov ss,[es:PSP_USERSS]
mov sp,[es:PSP_USERSP] mov bp,[es:PSP_USERSP]
RestoreSP
Restore386Registers
mov bp,cx
; ;
; and call critical error handler ; and call critical error handler
; ;

View File

@ -63,7 +63,9 @@ extern struct _KernelConfig InitKernelConfig;
#define open init_DosOpen #define open init_DosOpen
/* execrh.asm */ /* execrh.asm */
#ifndef __WATCOMC__
WORD ASMPASCAL execrh(request FAR *, struct dhdr FAR *); WORD ASMPASCAL execrh(request FAR *, struct dhdr FAR *);
#endif
/* asmsupt.asm */ /* asmsupt.asm */
VOID ASMPASCAL memset( void *s, int ch, size_t n); VOID ASMPASCAL memset( void *s, int ch, size_t n);

View File

@ -100,12 +100,14 @@ Check4Share:
Int2f?14: ;; MUX-14 -- NLSFUNC API Int2f?14: ;; MUX-14 -- NLSFUNC API
;; all functions are passed to syscall_MUX14 ;; all functions are passed to syscall_MUX14
push bp ; Preserve BP later on push bp ; Preserve BP later on
Protect386Registers
PUSH$ALL PUSH$ALL
mov ds, [cs:_DGROUP_] mov ds, [cs:_DGROUP_]
call _syscall_MUX14 call _syscall_MUX14
pop bp ; Discard incoming AX pop bp ; Discard incoming AX
push ax ; Correct stack for POP$ALL push ax ; Correct stack for POP$ALL
POP$ALL POP$ALL
Restore386Registers
mov bp, sp mov bp, sp
or ax, ax or ax, ax
jnz Int2f?14?1 ; must return set carry jnz Int2f?14?1 ; must return set carry

View File

@ -58,21 +58,23 @@ _exec_user:
; ;
pop ax ; return address (unused) pop ax ; return address (unused)
pop ax ; irp (user ss:sp) pop bp ; irp (user ss:sp)
pop dx pop si
pop cx ; disable A20? pop cx ; disable A20?
or cx,cx
jz do_iret
cli cli
mov ss,dx mov ss,si
mov sp,ax ; set-up user stack mov sp,bp ; set-up user stack
sti sti
; ;
or cx,cx
POP$ALL POP$ALL
jz do_iret
extern _ExecUserDisableA20 extern _ExecUserDisableA20
jmp far _ExecUserDisableA20 jmp far _ExecUserDisableA20
do_iret: do_iret:
iret extern _int21_iret
jmp _int21_iret
segment _LOWTEXT segment _LOWTEXT
@ -128,6 +130,7 @@ _spawn_int23:
;; 1999/03/27 ska - comments: see cmt1.txt ;; 1999/03/27 ska - comments: see cmt1.txt
mov ds, [cs:_DGROUP_] ;; Make sure DS is OK mov ds, [cs:_DGROUP_] ;; Make sure DS is OK
mov bp, [_user_r]
; restore to user stack ; restore to user stack
cli ;; Pre-8086 don't disable INT autom. cli ;; Pre-8086 don't disable INT autom.
@ -144,11 +147,12 @@ _spawn_int23:
; this patch helps FreeDos to survive CtrlC, ; this patch helps FreeDos to survive CtrlC,
; but should clearly be done somehow else. ; but should clearly be done somehow else.
mov ss, [_user_r+2] mov ss, [_user_r+2]
mov sp, [_user_r] RestoreSP
sti sti
; get all the user registers back ; get all the user registers back
Restore386Registers
POP$ALL POP$ALL
;; Construct the piece of code into the stack ;; Construct the piece of code into the stack