Page 1 of 2
How to protect the stack
Posted: Fri Jun 03, 2011 1:01 pm
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
Re: How to protect the stack
Posted: Fri Jun 03, 2011 1:26 pm
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.
Re: How to protect the stack
Posted: Fri Jun 03, 2011 1:30 pm
by Karlosoft
Thank you very much ^_^
Re: How to protect the stack
Posted: Fri Jun 03, 2011 1:36 pm
by bluemoon
Oh I see it's not mov esp but sub esp.
Please ignore point 2 & 3.
Re: How to protect the stack
Posted: Fri Jun 03, 2011 1:37 pm
by Karlosoft
However it doesn't work... But now it doesn't reboot.
Re: How to protect the stack
Posted: Fri Jun 03, 2011 8:45 pm
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.
Re: How to protect the stack
Posted: Sat Jun 04, 2011 2:21 am
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?
Re: How to protect the stack
Posted: Sat Jun 04, 2011 8:35 am
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.
Re: How to protect the stack
Posted: Sat Jun 04, 2011 8:53 am
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.
Re: How to protect the stack
Posted: Sat Jun 04, 2011 8:57 am
by Owen
- Nobody uses it
- It is a better use of silicon to update other features
- It becomes relatively slower, so nobody uses it
- 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.
Re: How to protect the stack
Posted: Sat Jun 04, 2011 9:04 am
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?
Re: How to protect the stack
Posted: Sat Jun 04, 2011 10:40 am
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.
Re: How to protect the stack
Posted: Sat Jun 04, 2011 11:18 am
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!
Re: How to protect the stack
Posted: Sat Jun 04, 2011 11:31 am
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?
Re: How to protect the stack
Posted: Sat Jun 04, 2011 11:49 am
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?