Description
I traced a crash that I encountered to the call in
Line 457 in 192cccc
Line 1974 in 192cccc
Line 1924 in 192cccc
The problem is that the latter function never checks that sufficient memory is available in the referenced memory block. In my test case this causes the kernel to overwrite memory not belonging to it, corrupting my little test's int 2Fh handler and likely part of the resident debugger (bootable lDebug) as well.
I'm running in "dosemu2 2.0pre9-dev-20240420-1892-g6a2f4f527 Configured: 2024-04-18 10:57:53 +0000" and booting into a recent lDebug revision. The kernel I use is from the bin/ subdirectory of my most recent build, renamed from kernel.sys to fdkernel.sys, and configured using sys config fdkernel.sys checkdebugger=1
. I'm also using testpl.com as a device driver, a build of which I uploaded to our server here. (If you really want I can dig up the exact commands to build it from the lDOS boot repo.)
The full config file used contains:
rem config.sys for DOSEMU + FreeDOS
SWITCHES=/F
DOS=UMB,HIGH
dosdata=umb
lastdrive=Z
files=40
stacks=0
buffers=10
device=c:\testpl.com rc now
device=d:\dosemu\umb.sys
device=d:\dosemu\emufs.sys
device=d:\dosemu\ems.sys
device=d:\dosemu\cdrom.sys
install=d:\dosemu\emufs.com
shell=C:\command.com /e:4096 /p:d:\autoexec.bat
;set ldebugconfig=c:\testdir
;device=c:\bin\ldebug.com /c=d68:0;qcd
;device=c:\bin\ldebug.com /c=qdc
The fred327
alias used in the debugger session is defined as follows:
alias add fred327 boot protocol freedos cmdline=1 ldp/fdkernel.sys . config fdconfig.327
(This adds an override to run a different config file than default.)
The testumb1.sld
Script for lDebug file used contains:
r word [0:413] -= 2
r v0 = word [0:413]
r v1 = v0 + 1
r v0 *= #1024 / #16
r v1 *= #1024 / #16
f v0:0 l #1024 26
f v1:0 l #1024 CC
f v1:0 l 10 0
a v1:10
cmp ax, 4300
je 20
cmp ax, 4310
je 30
jmp 0:0
.
r v2 = aao - 4
a v1:20
mov al, 80
iret
.
a v1:30
push cs
pop es
mov bx, 40
iret
.
a v1:40
jmp short 45
nop
nop
nop
cmp ah, 10
je 50
.
r v3 = aao
a
xor ax, ax ; error
mov bl, 80 ; not implemented
retf
.
a v1:50
cmp byte [cs:10], EB
je 80
cmp dx, (#1024 / #16 - v4)
ja 70
jb (v3) ; if requested smaller -->
mov ax, 1 ; success
mov bx, (v0 + v4) ; => UMB, dx = size
mov word [cs:10], (EB + (v2 - 1 - 12) * 100)
retf
.
a v1:70
xor ax, ax ; error
mov bl, B0 ; only a smaller UMB
mov dx, (#1024 / #16 - v4)
retf
.
a v1:80
xor ax, ax ; error
mov bl, B1 ; no UMB available
xor dx, dx ; largest available
retf
.
rc.replace r vf = ri2Fp; r dword [v1:v2] = vf; r dword [0:2F * 4] = v1*10000 + 10
This script reserves 2 KiB at the top of the Low Memory Area (below the resident debugger and possibly EBDA), using the upper 1 KiB for code space and the lower 1 KiB as an improvised "UMB" space. The v4
variable indicates how much of a gap (in paragraphs) to leave between the top of the LMA and the UMB. I set this to 1 in the test to avoid any possible confounding factors with UMBs that extend the LMA. (This is the original purpose of the test, which showed me that lRxDOS/lMS-DOS incorrectly treat that case.)
The code is an int 2Fh handler which offers an XMS entrypoint. The only supported function is function 10h, allocate UMB, and then only the size query (eg with dx
= 0FFFFh) and exact size allocation are supported. After the UMB is allocated, the int 2Fh handler is changed to chain to its downlink immediately (hiding the XMS entrypoint), and subsequent function 10h calls to the XMS entrypoint say there is no free UMB left.
The use of this script is as follows, once booted into lDebug:
r v4 1
y testumb1.sld
fred327
g
r f CY
g
rc
The Y command runs a Script for lDebug file, which is read using int 13h when booted into the debugger. The fred327
alias was listed above. The first g
command runs up to the debugger check, which had to be enabled using sys config
as above. r f CY
indicates debugger present to the kernel.
The second g
command runs up to the next breakpoint, which in this FreeDOS kernel test case is the int3
instruction in testpl.com. The rc
command hooks int 2Fh to our handler then. That makes it ready for action, to offer its UMB to the config code after the testpl.com device driver returns. Running a third g
command would crash dosemu2, due to the kernel corrupting int 2Fh presumably.
I will dump a longer session output as a subsequent comment.