Page 1 of 1
(SOLVED) Can use port IO even IOPL=0 and CPL=3
Posted: Sun Feb 05, 2017 2:25 pm
by Agola
Hi.
I've finally *fully* moved to userspace. And I've done some tests to verify I'm in user mode.
Using privileged instructions like cli, sti causes a general protection fault.
But using port input output doesn't.
IOPL is 0 and CPL is 3, so CPL > IOPL, then I should get a GPF.
I set iomap base of TSS to sizeof(tss_entry_t), so iomap is simply invalid. How does port IO work even after IOPL = 0? Really strange.
Thanks in advance.
Re: Can use port IO even IOPL=0 and CPL=3
Posted: Sun Feb 05, 2017 2:42 pm
by BrightLight
Can you show us your TSS structure? Also, did you try printing sizeof(tss_entry_t) and checking it's valid? The size of the TSS should be 104 in both the GDT entry and the I/O map base if you want to prevent user applications from accessing I/O ports.
Re: Can use port IO even IOPL=0 and CPL=3
Posted: Sun Feb 05, 2017 2:47 pm
by Agola
The sizeof(tss_entry_t) is 104.
Code: Select all
typedef struct tss_entry_t
{
uint32_t tss_link;
uint32_t esp0;
uint32_t ss0;
uint32_t esp1;
uint32_t ss1;
uint32_t esp2;
uint32_t ss2;
uint32_t cr3;
uint32_t eip;
uint32_t eflags;
uint32_t eax;
uint32_t ecx;
uint32_t edx;
uint32_t ebx;
uint32_t esp;
uint32_t ebp;
uint32_t esi;
uint32_t edi;
uint32_t es;
uint32_t cs;
uint32_t ss;
uint32_t ds;
uint32_t fs;
uint32_t gs;
uint32_t ldt;
uint16_t t_trap;
uint16_t iomap_base;
} tss_entry_t;
That is tss struct.
I set tr with 0x2B.
Re: Can use port IO even IOPL=0 and CPL=3
Posted: Mon Feb 06, 2017 10:51 am
by Agola
Tried everything for about 3 hours, and couldn't fix. I've out of ideas.
I hope there aren't another strange bugs.
Re: Can use port IO even IOPL=0 and CPL=3
Posted: Mon Feb 06, 2017 11:29 am
by dozniak
Are you sure you're not in ring0?
Re: Can use port IO even IOPL=0 and CPL=3
Posted: Mon Feb 06, 2017 11:34 am
by Agola
dozniak wrote:Are you sure you're not in ring0?
Ah, yep.
I'm using Bochs debugger, segment registers are 0x23.
Privileged instructions are triggering #GP also.
Re: Can use port IO even IOPL=0 and CPL=3
Posted: Mon Feb 06, 2017 11:55 am
by Brendan
Hi,
If HLT or CLI causes a general protection fault; then IOPL must be (numerically) less than CPL (and it'd be safe to assume CPL=3 and IOPL=0).
That implies that the problem must be either:
- the IO permission bitmap in the TSS or the GDT entry for the TSS (e.g. the TSS is right but the GDT entry points to something else)
- a buggy emulator
- a buggy test (e.g. thinking you're using an IO port but the instruction is overwritten and/or not executed)
For probabilities, I'd assume that the first possibility is the most likely.
Cheers,
Brendan
Re: Can use port IO even IOPL=0 and CPL=3
Posted: Mon Feb 06, 2017 12:17 pm
by Agola
Brendan wrote:Hi,
If HLT or CLI causes a general protection fault; then IOPL must be (numerically) less than CPL (and it'd be safe to assume CPL=3 and IOPL=0).
That implies that the problem must be either:
- the IO permission bitmap in the TSS or the GDT entry for the TSS (e.g. the TSS is right but the GDT entry points to something else)
- a buggy emulator
- a buggy test (e.g. thinking you're using an IO port but the instruction is overwritten and/or not executed)
For probabilities, I'd assume that the first possibility is the most likely.
Cheers,
Brendan
Thanks. Does the GDT entry for the TSS has a base for IO permission bitmap also?
And, these are some register dumps if helps.
This is info tss output from Bochs debugger:
tr:s=0x2b, base=0x000000000011c060, valid=1
ss:esp(0): 0x0010:0x0019c008
ss:esp(1): 0x0000:0x00000000
ss:esp(2): 0x0000:0x00000000
cr3: 0x00000000
eip: 0x00000000
eflags: 0x00000000
cs: 0x000b ds: 0x0013 ss: 0x0013
es: 0x0013 fs: 0x0013 gs: 0x0013
eax: 0x00000000 ebx: 0x00000000 ecx: 0x00000000 edx: 0x00000000
esi: 0x00000000 edi: 0x00000000 ebp: 0x00000000 esp: 0x00000000
ldt: 0x0000
i/o map: 0x0068
This is CPU0 output:
rax: 00000000_00000034 rcx: 00000000_0019cdc4
rdx: 00000000_00000014 rbx: 00000000_00000000
rsp: 00000000_0019d004 rbp: 00000000_0019d010
rsi: 00000000_00000000 rdi: 00000000_00000000
r8 : 00000000_00000000 r9 : 00000000_00000000
r10: 00000000_00000000 r11: 00000000_00000000
r12: 00000000_00000000 r13: 00000000_00000000
r14: 00000000_00000000 r15: 00000000_00000000
rip: 00000000_00103a64
eflags 0x00200202: ID vip vif ac vm rf nt IOPL=0 of df IF tf sf zf af pf cf
This is sreg output:
es:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
cs:0x001b, dh=0x00cffb00, dl=0x0000ffff, valid=1
Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, Accessed, 32-bit
ss:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ds:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
fs:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
gs:0x0023, dh=0x00cff300, dl=0x0000ffff, valid=1
Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ldtr:0x0000, dh=0x00008200, dl=0x0000ffff, valid=1
tr:0x002b, dh=0x0001eb11, dl=0xc060c0c8, valid=1
gdtr:base=0x000000000011c020, limit=0x2f
idtr:base=0x000000000011c0e0, limit=0x7ff
And this is creg output:
CR0=0xe0000011: PG CD NW ac wp ne ET ts em mp PE
CR2=page fault laddr=0x0000000000000000
CR3=0x000000122000
PCD=page-level cache disable=0
PWT=page-level write-through=0
CR4=0x00000000: smap smep osxsave pcid fsgsbase smx vmx osxmmexcpt osfxsr pce pge mce pae pse de tsd pvi vme
CR8: 0x0
Thanks in advance.
Re: Can use port IO even IOPL=0 and CPL=3
Posted: Mon Feb 06, 2017 12:24 pm
by Schol-R-LEA
Brendan wrote:For probabilities, I'd assume that the first possibility is the most likely.
<aside type="FYI, not directed at anyone in particular">
Agreed, just on the general principle of "extraordinary claims require extraordinary proof". In this case, the extraordinary part would not be claiming that a given tool (the emulator) has bugs, or that you have encountered a bug, but rather that you have encounter a bug in a basic operation which has not already been observed and reported by other users.
If I am writing a program using a set of widely-used tools, and I encounter a problem with the code and cannot explain why the code is failing, I would want - need, really - to exhaust all reasonable avenues by which
my code might be failing before concluding that it
might be a fault in the tool I am using to create or execute the program. I furthermore would want to pin down in as precise a manner as possible the exact behavior of the failure, and find a way to reproduce it in varying circumstances so as to rule out any other factors that could cause it, before issuing a bug report. I would also seek out any existing reports of the behavior, both in and out of the bug tracking system, and see if any of the reports give additional weight or new factors to the possible flaw.
I am not saying anyone is jumping to conclusions, but rather reminding them
not to jump to conclusions. It's always worth reminding people about that, IME, as the temptation to blame others is often a bit hard to resist - I've made the same mistake more often than I can count, and I expect most of the people here have, too.
</aside>
Re: Can use port IO even IOPL=0 and CPL=3
Posted: Mon Feb 06, 2017 2:02 pm
by Gigasoft
Well, there is the problem right there. The limit is 0x1c0c8 instead of 0x67, as it should be.
Re: Can use port IO even IOPL=0 and CPL=3
Posted: Mon Feb 06, 2017 3:16 pm
by Agola
Gigasoft wrote:Well, there is the problem right there. The limit is 0x1c0c8 instead of 0x67, as it should be.
Ah, I thought limit is absolute, not relative.
I'm using the classic flat model, so I didn't think limit is absolute or relative.
Thanks, now everything works great!
Re: Can use port IO even IOPL=0 and CPL=3
Posted: Tue Feb 07, 2017 12:48 am
by dozniak
Agola wrote:Gigasoft wrote:Well, there is the problem right there. The limit is 0x1c0c8 instead of 0x67, as it should be.
Ah, I thought limit is absolute, not relative.
I'm using the classic flat model, so I didn't think limit is absolute or relative.
Thanks, now everything works great!
Limit = size - 1