Kernel segmentation

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
Silverhawk

Kernel segmentation

Post by Silverhawk »

Hi !

I would like to know how to make my kernel segmentation ?

What are the segments to put in my GDT, and how can I choose them, why ?

Thanks.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Kernel segmentation

Post by Pype.Clicker »

well, that will depend alot on your kernel design, but basically, you'll at least need:
- a "kernel code" segment, which will be used to access all your kernel functions
- a "kernel data" segment, to read/write kernel variables, and possibly allocate some more variables dynamically
- a "kernel stack" segment -- which may optionnally be your kernel data segment.

- a TSS for your initialization task.

Now, depending on whether you decide to have modules executed within the same code segment or as separate code segment, depending on whether you decide to provide several stack segments for an improved system security, etc. you may have different requirement.

As a basic startpoint, make your code & data 4GB-wide so that you can access the whole memory space.
Tim

Re:Kernel segmentation

Post by Tim »

If you want to start using segments with different base addresses (e.g. malloc allocates a new segment), you effectively must write your code in assembler. Virtually no compilers understand segmentation, and expect a flat memory model (base=0, limit=4GB).
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Kernel segmentation

Post by Pype.Clicker »

@timl: i wonder whether C++ operators overloading could be used to work with far calls and far data segments.

something like

Code: Select all

class farArray {
private: 
      segment;
public:
     <type> operator [](int index) {
           <type> ret;
           asm ("mov %0, %%fs": segment);
           asm("mov fs:(%1),%0":"=g"(ret):"index);
           return ret
      }
}
or

Code: Select all

class farFunc {
        private:
            call_gate;
        public:
            operator () {
                  asm ("lcall " ...);
             }
}
Tim

Re:Kernel segmentation

Post by Tim »

Possibly. But that throws out any possibility of writing generic code. You'd need separate near and far versions of every function which accepted a pointer, or else marshal data to and from the far array yourself.

Segmented programming is horrendous, yet DOS has been obsolete so long that today's programmers have forgotten it.
Silverhawk

Re:Kernel segmentation

Post by Silverhawk »

Thanks a lot to Pype.Cliker & Tim Robinson !

So, it is more reliable for a kernel to execute each processes in different segments ?

I would like to use paging to manage memory. What kind of architecture do you advise me ? Should I use 4GB segment code & 4GB data code, and then use paging in it ?

If I decide to use severals segments for each processes, I must had en entry in the GDT. And if the segment is no used any more, I must delete the corresponding entry of the GDT ?

It is not really clear in my mind... :P

Thanks for your help !
Silverhawk

Implementing paging

Post by Silverhawk »

I've forgotten to ask you how can I implement paging...
Actually, I've got a boot loader and a "kernel" which is loaded at the 1MB boundary.

So, to realize this, I had to jump in Pmode using a GDT.
How can I use paging at this stage ?

thanks once more...
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Kernel segmentation

Post by Pype.Clicker »

what i suggest you for a C-compatible but secure environment is:

- have one big data segment and one big code segment for each process
- the size of the code segment will be adjusted so that only .text sections are covered by it (you will not have an executable heap or stack, because this leads to several virus opportunities and exploits on your applications)
- the base of both stack and data segment should be the same.
- rather put a specific LDT for each process in the GDT and then put process-specific segments in the LDT.
Silverhawk

Re:Kernel segmentation

Post by Silverhawk »

to Pype.Cliker
OK !

So, a summary of what to do to develop my kernel is :

- Boot (in asm) :
- To set up a GDT with a code segment (big) entry.
- To enter into Pmode.
- To load and jump to the kernel.

- Kernel :
-To re-establish the GDT (to be able to code in C language).
-To add a data segment (big) in the GDT entry.
-To add a stack segment (big) in the GDT entry.
-To activate paging (how ?)

-Then, to code a memory management which adds new segments (code, data and stack) for each process, and then which uses paging to manage memory in these segments ?

Am I right ?

Thanks for your advice !
Silverhawk

Re:Kernel segmentation

Post by Silverhawk »

I wonder to know if :
- If put a segment code in my GDT which begins at 0x000000 and ends at 0xffffff.
- And if I add another one, but a data segment, which begins at the same address and has the same length.

Do they cover the same memory ?

I can't imagine a code segment from 0x000000 to 0xffffff
and a data segment frome 0x000000 to 0xffffff which cover different memory ?????
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Kernel segmentation

Post by Pype.Clicker »

the CPU has no trouble dealing with overlapping segments. So you can (and in fact, for the kernel, you *should*) have OS_CODE and OS_DATA overlapping.

btw, i suggest the OS_DATA segment to be set up before entering pmode aswell: if you enter with a OS_CODE segment only, you'll be in big trouble when you'll try to modify memory, as code segments may only be used to *read* data or execute instructions ...
Perica
Member
Member
Posts: 454
Joined: Sat Nov 25, 2006 12:50 am

Re:Kernel segmentation

Post by Perica »

..
Last edited by Perica on Sun Dec 03, 2006 9:14 pm, edited 1 time in total.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Kernel segmentation

Post by Pype.Clicker »

sounds like you've never heard of "buffer overflow" exploits, which consist of overwriting the return address of a function by making a stack-located buffer overflowed with a very specific dataset (larger than the expected size), which contains (among other things) a bootstrap code that will execute malicious actions that the running program was not supposed to run.

By making your program's code read-only, you can prevent a buggy/malicious harmless program to become a new harmful one, but you cannot protect against new bytes to be executed.

By making your program's code to be the solely bytes that can be executed, you make sure that no "alien" code can come and get executed with your program's priviledge.

This "simple" modification on the execution environment gives you the security that software engineers actually try to get with "secure programming" fashions. Considering the large amount of security flaws that are announced periodically for the wide range of networking programs, having the ability of blocking efficiently the most common attack style without losing the speed of native programs seems a non-neglectible advantage for an OS, imho.
mystran

Re:Kernel segmentation

Post by mystran »

Yeah, protecting code from modifications and data from being executed is great, but I don't know if that's really a "solve it all" for security. There are still other ways to exploit systems, and you still have the buffer overflow, which still can be used to crash, if not exploit the system.

Often the program binaries actually contain all the code you would want. Since the libc is linked in anyway, you could just arrange your overflowed stack to call some library functions, and say.. start a rootshell (in case of UNIX system).

So instead of having a small function that calls exec() or such, you instead arrange your stack to do it without extra code. While it is a bit harder, it's still possible.
Post Reply