How to protect the stack

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.
User avatar
Karlosoft
Member
Member
Posts: 277
Joined: Thu Feb 14, 2008 10:46 am
Location: Italy
Contact:

How to protect the stack

Post by Karlosoft »

Hi, I'd like to protect my kernel stack with a GDT segment...

Code: Select all

    void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran){
    gdt[num].base_low = (base & 0xFFFF);
    gdt[num].base_middle = (base >> 16) & 0xFF;
    gdt[num].base_high = (base >> 24) & 0xFF;
    gdt[num].limit_low = (limit & 0xFFFF);
    gdt[num].granularity = ((limit >> 16) & 0x0F);
    gdt[num].granularity |= (gran & 0xF0);
    gdt[num].access = access;
    }
    //....
    gdt_set_gate(0, 0, 0, 0, 0);
    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
    gdt_set_gate(3, 0, 0xFFFFF, 0x9a, 0x00);
    gdt_set_gate(4, 0, 0xFFFFF, 0x92, 0x00);
    gdt_set_gate(5, 0x50000, 0x40000, 0x92, 0x40);      //Stack...
But when I chose the last segment for SS I have a reset of my computer.
The segment has to map the memory from 0x50000 up to 0x90000. Why this code doesn't work?

EDIT: This code updates my segments

Code: Select all

global _gdt_flush
extern _gp
_gdt_flush:
    lgdt [_gp]
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ax, 0x30
    mov ss, ax
    sub esp, 0x50000
    jmp 0x08:flush2
flush2:
    ret
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: How to protect the stack

Post by bluemoon »

Code: Select all

mov ax, 0x30
mov ss, ax
sub esp, 0x50000
...
ret
A quick look reveal at least 3 issues:

1. The 5th selector should be 0x28.
2. ESP = 0x50000 is outside the selector limit, which is 0x40000.
( Address = ss.base(0x50000) + esp (0x50000) )
3. You altered the stacked pointer, so the ret would go wild.
Last edited by bluemoon on Fri Jun 03, 2011 1:33 pm, edited 1 time in total.
User avatar
Karlosoft
Member
Member
Posts: 277
Joined: Thu Feb 14, 2008 10:46 am
Location: Italy
Contact:

Re: How to protect the stack

Post by Karlosoft »

Thank you very much ^_^
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: How to protect the stack

Post by bluemoon »

Oh I see it's not mov esp but sub esp.
Please ignore point 2 & 3.
User avatar
Karlosoft
Member
Member
Posts: 277
Joined: Thu Feb 14, 2008 10:46 am
Location: Italy
Contact:

Re: How to protect the stack

Post by Karlosoft »

However it doesn't work... But now it doesn't reboot.
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: How to protect the stack

Post by Owen »

4. You're using (I presume) GCC or MSVC. Both require CS.base == DS.base == ES.base == SS.base.

OpenWatcom is just about the only C(++) compiler which understands segmentation.
User avatar
Karlosoft
Member
Member
Posts: 277
Joined: Thu Feb 14, 2008 10:46 am
Location: Italy
Contact:

Re: How to protect the stack

Post by Karlosoft »

Oh nice.... ok this is the last thing of gcc I can't stand, I'll change compiler or language. Any idea? OpenWatcom is a good compiler?
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: How to protect the stack

Post by Owen »

OpenWatcom is a pretty lousy compiler (It is far behind in terms of standard support).

Good luck finding anything which supports segmentation. Even AMD and Intel have declared it obsolete; it is completely unsupported except in a minor form (CS/DS/ES/SS base completely ignored. No limit checking. Segment descriptors cannot have >4GB bases; FS and GS bases must be loaded by writing an MSR for higher values) for 64-bit code.
User avatar
Karlosoft
Member
Member
Posts: 277
Joined: Thu Feb 14, 2008 10:46 am
Location: Italy
Contact:

Re: How to protect the stack

Post by Karlosoft »

I'll continue to write my own compiler... XD..
I see but what is the problem of GDT? I mean is there any good reason for the which GDT has not been updated in newer processors? I can't understand.
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: How to protect the stack

Post by Owen »

  1. Nobody uses it
  2. It is a better use of silicon to update other features
  3. It becomes relatively slower, so nobody uses it
  4. GOTO 2
When AMD64 came about, they went "Nobody's using this, so lets cut all the features we don't need for backwards compatibility when running in long mode". The rest, as they say, is history.

Note that on most recent CPUs Base + Scale * Index + Offset addressing will take an extra cycle when the segment base is not zero.
User avatar
Karlosoft
Member
Member
Posts: 277
Joined: Thu Feb 14, 2008 10:46 am
Location: Italy
Contact:

Re: How to protect the stack

Post by Karlosoft »

So the problem is that nobody used this feature. I mean, if it were used today It should be implemented better on processors. So am I forced to use paging?
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: How to protect the stack

Post by bluemoon »

Karlosoft wrote:So the problem is that nobody used this feature. I mean, if it were used today It should be implemented better on processors. So am I forced to use paging?
The situation is major software company(in terms on market share), especially dealing with OS level, not using segmentation.
So as manufacture it's normal to optimize & benefit the bigger market.

Intel or AMD won't force you to use anything, and I guess they not even care.
User avatar
Chandra
Member
Member
Posts: 487
Joined: Sat Jul 17, 2010 12:45 am

Re: How to protect the stack

Post by Chandra »

Karlosoft wrote:Hi, I'd like to protect my kernel stack with a GDT segment...

Code: Select all

    void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran){
    gdt[num].base_low = (base & 0xFFFF);
    gdt[num].base_middle = (base >> 16) & 0xFF;
    gdt[num].base_high = (base >> 24) & 0xFF;
    gdt[num].limit_low = (limit & 0xFFFF);
    gdt[num].granularity = ((limit >> 16) & 0x0F);
    gdt[num].granularity |= (gran & 0xF0);
    gdt[num].access = access;
    }
    //....
    gdt_set_gate(0, 0, 0, 0, 0);
    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
    gdt_set_gate(3, 0, 0xFFFFF, 0x9a, 0x00);
    gdt_set_gate(4, 0, 0xFFFFF, 0x92, 0x00);
    gdt_set_gate(5, 0x50000, 0x40000, 0x92, 0x40);      //Stack...
But when I chose the last segment for SS I have a reset of my computer.
The segment has to map the memory from 0x50000 up to 0x90000. Why this code doesn't work?

EDIT: This code updates my segments

Code: Select all

global _gdt_flush
extern _gp
_gdt_flush:
    lgdt [_gp]
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ax, 0x30
    mov ss, ax
    sub esp, 0x50000
    jmp 0x08:flush2
flush2:
    ret
Nowhere in the code you've called gdt_flush. You know the rest....

Despite the fact that GCC can't handle segmentation, your code is messed up too. Like bluemoon pointed out the selector you used for the stack segment is wrong which was the cause for the 'Triple Fault' in the first place. One next thing I'd like to acknowledge is that GCC doesn't know where the stack segment is, it's the processor who knows. All the access to the stack segments are made VIA the cpu, so if you could just trick the compiler to access the right segments, may be you'd have some luck.............
Karlosoft wrote:I'll continue to write my own compiler
That's the terrible decision to make.

And Oh! how would defining a separate stack segment protect the kernel stack anyway? They carry read and write attribute so in the end, it doesn't make much sense. A finely maintained code can do this job whatsoever.

Cheers!
Programming is not about using a language to solve a problem, it's about using logic to find a solution !
User avatar
Karlosoft
Member
Member
Posts: 277
Joined: Thu Feb 14, 2008 10:46 am
Location: Italy
Contact:

Re: How to protect the stack

Post by Karlosoft »

It could be safer because it can't access other memory or it launches the GDT exception.
I corrected the segment now it is 0x28 it should be right. The function is called after I init the segments of the GDT...
However, why shouldn't I?
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: How to protect the stack

Post by bluemoon »

It could be safer because it can't access other memory or it launches the GDT exception.
How can it be?
A guard page for stack should be enough to avoid stack overflow.
with DPL=0 avoid access from ring3 application
unset the execution bit provide further security against malicious execution

what else protection do you want and cannot be implemented with plain paging?
Post Reply