x86 IO-mapped IO ports protection and DOS Extenders

assembly, dos, x86

Solution

I don't see why DOS extenders would require running your app code in Ring 3. I think DPMI spec requires that, but you don't really have to stick to it if your app is the only one running. This forum post mentions a few extenders allegedly running in Ring 0:

All known Ring0 hosts (DOS32/A, WDOSX, CWSDPR0) don't swap - it this just coincidence or is there a fundamendal "problem" preventing Ring0 hosts from swapping?

From the CWSDPMI page:

CWSDPR0.EXE is an alternate version which runs at ring 0 with virtual memory disabled. It may be used if access to ring-0 features are desired.

From the DOS/32 page:

- protected mode applications run at CPL 0

If none of those work, there are other options:

do your own protected mode set up - it's not that difficult

take an existing DOS extender and modify it to run in Ring 0. HX-DOS source is available, as well as a couple of others.

Problem

I'm developing an protected mode application for FreeDOS using DOS Extender. My application does intensive I/O. As all DOS Extenders run their applications in Ring3 (ie CPL=3) and themselves run at Ring 0 (ie CPL=0), some questions about I/O protection arise in my mind. From x86 docs, I get the following info: IOPL-sensitive instructions: IN, INS, OUT, OUTS, CLI, and STI. If CPL <= IOPL, no exception is generated and the IOPL-sensitive instruction is executed. If CPL > IOPL, and the instruction is one of these instructions (IN, OUT, INS, or OUTS), the processor checks the current task's IO permission bit map (in its TSS) to determine if the current application is permitted to access the addressed IO port(s). If the bit map indicates that the task is permitted to access the indicated IO port(s), no exception is generated and the IO instruction is executed. Otherwise, a GP exception is generated. If CPL > IOPL, and the instruction is either CLI or STI, the processor generates a GP Exception. This means if our app. runs at Ring3, then to exceute IN,OUT,INS,OUTS instructions, we must have either CPL <= IOPL(this translates to IOPL=3, in our case), or if CPL > IOPL (this translates to IOPL <= 2, ie IOPL = 0, as usually Ring1 and Ring2 are not used.) the I/O permission bitmap must be set by DOS Extender (while launching our app.), such that our app. is permitted to access any I/O port. But in latter case, we still can't use CLI and STI instructions from our Ring3 application, as CPL > IOPL. So, it turns out that, the following instructions can be executed only if CPL <= IOPL : IN, INS, OUT, OUTS, CLI, and STI . In our case, this translates to 3 <= IOPL, ie IOPL = 3. Now my question is, does all dos extenders set IOPL = 3, in the TSS of the task/application they start ? If they don't, then they must run the task/application in Ring0 (CPL=0), otherwise the application can't execute IOPL sensitive instructions. The docs also state that: A program or task can change its IOPL only with the POPF and IRET instructions; however, such changes are privileged. No procedure may change the current IOPL unless it is running at privilege level 0 ie CPL=0. An attempt by a less privileged procedure to change the IOPL does not result in an exception; the IOPL simply remains unchanged. This means that: if POPF or IRET instructons are encountered in Ring 3 code, then IOPL field will not be modified/restored, and no exception is generated by the CPU. This is ok, as we don't wanna modify IOPL field, and let it be handled by DOS Extender. But does it mean that other flags(bit0 to bit11 of EFLAGS reg. ) will be restored ? My app. may need to execute POPF instruction and IRET too. The doc also states : A procedure may use the POPF instruction to change the setting of the IF flag only if CPL <= IOPL. An attempt by a less privileged procedure to change the IF flag does not result in an exception; the IF flag simply remains unchanged. This mean that: if a POF instruction is encountered in Ring3 code, then IF flag is modified only if CPL <= IOPL, ie 3 <= IOPL or IOPL = 3. Again we need IOPL to be 3. :) I'm seeking for a generic answer- ie not DOS Extender specific. This is becoz, it seems that although they differ in implementations , but the basic principles remain same b/w DOS extenders- for e.g. they run an application in Ring3.

Original source