Ring 3 in long mode

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
iefbr14
Posts: 4
Joined: Tue Aug 12, 2014 10:42 pm

Ring 3 in long mode

Post by iefbr14 »

I know that I simply have done some stupid error (or didn't read the manual careful enough), but I'm standing still without any idea. When attempting to execute the following code:

Code: Select all

  mov rax,rsp
  push qword 24 ;SS
  push qword rax ;RSP
  push qword 0 ;RFLAGS
  push qword 16 ;CS
  push qword TEST ;RIP
  iretq
TEST:
  jmp $
#GP comes at 'ireq' with error code 10 (the selector of my ring-3 code segment). My GDT is:

Code: Select all

    align 8
GDT:
  dq 0 ; Null descriptor.
  db 0,0,0,0,0,10011000b,00100000b,0 ; Ring-0 descriptor.
  db 0,0,0,0,0,11111000b,00100000b,0 ; Ring-3 descriptor.
  db 0,0,0,0,0,10010000b,00000000b,0 ; Ring-3 stack.
GDTP:
  dw $-GDT-1
  dq GDT
I have got no TSS, but the ireq doesn't require one, does it? Ring0-to-ring0 interrupts and ireqs works fine, U/S paging flag is on, but that is not relevant anyway, as the fault occurs before the user code starts execution. Can anybody help me? Thanks in advance.
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: Ring 3 in long mode

Post by Gigasoft »

The return CS is wrong. It should be 19. And you'll need a TSS when going back to ring 0 afterwards.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Ring 3 in long mode

Post by bluemoon »

RFLAG must not be zero, bit #1 should be set.

Also, the GDT looks not quite right, and where's the ring0 data?
iefbr14
Posts: 4
Joined: Tue Aug 12, 2014 10:42 pm

Re: Ring 3 in long mode

Post by iefbr14 »

bluemoon wrote:RFLAG must not be zero, bit #1 should be set.
Thanks. But still doesn't work, even if I use pushfq.
bluemoon wrote:where's the ring0 data?
I use zero selector, that seems to work both on qemu and on real hardware. That should, as it is normally used as interrupt stack segment.
The return CS is wrong. It should be 19.
Still no effect. RE: at least now the stack segment (0x18) is reported as error code, and not the code segment.
you'll need a TSS when going back to ring 0 afterwards.
I know, but I just didn't came so far yet.
iefbr14
Posts: 4
Joined: Tue Aug 12, 2014 10:42 pm

Re: Ring 3 in long mode

Post by iefbr14 »

Thanks everybody. My problem was RPL, just as Gigasoft told. But it seems like QEMU checks for write access on stack. Is it correct behaviour? I didn't figured it out from the AMD manual.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Ring 3 in long mode

Post by bluemoon »

iefbr14 wrote:
bluemoon wrote:where's the ring0 data?
I use zero selector, that seems to work both on qemu and on real hardware. That should, as it is normally used as interrupt stack segment.
This may work, but there are two reason not to do so:
1. According to intel manual:
9.8.1 Protected-Mode System Data Structures
To implement a flat memory model without paging, software initialization code must at a minimum load a GDT with one code and one data-segment descriptor. A null descriptor in the first GDT entry is also required.
Although it says "flat memory model without paging", I read it as a minimal example and also apply to more complex memory models (ie. standard flat paging).

Also note that, while base and limit is not checked in 64-bit mode, other fields are still significant.

2. syscall/sysret requires specific GDT layout which "data selector" is "code selector+8", so you need an entry for data anyway.


As a side note, if TR is insane (e.g. point to bogus memory, or mapped to 16bit TSS), 64-bit consistency check may fail when attempt to switch to long mode, and generate #GP.
Post Reply