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);
/* 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 *);
#endif
/*
* end of device.h

View File

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

View File

@ -251,7 +251,6 @@ reloc_call_int21_handler:
sti
PUSH$ALL
mov bp,sp
Protect386Registers
;
; Create kernel reference frame.
;
@ -259,6 +258,7 @@ reloc_call_int21_handler:
; until later when which stack to run on is determined.
;
int21_reentry:
Protect386Registers
mov dx,[cs:_DGROUP_]
mov ds,dx
@ -378,17 +378,11 @@ int21_exit_nodec:
pop bp ; get back user stack
pop si
%if XCPU >= 386
%ifdef WATCOM
sub bp, byte 4 ; for fs and gs only
%else
sub bp, byte 6 ; high parts of eax, ebx or ecx, edx
%endif
%endif
global _int21_iret
_int21_iret:
cli
mov ss,si
mov sp,bp
RestoreSP
int21_ret:
Restore386Registers
@ -557,7 +551,7 @@ CritErr05:
; make bp:si point to dev header
;
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
;
@ -580,7 +574,10 @@ CritErr05:
; switch to user's stack
;
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
;

View File

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

View File

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

View File

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