Page 1 of 1

Process identification.

Posted: Wed Oct 04, 2006 2:01 pm
by mrkaktus
Hi, I am thinking about identification processess. I know there must be some identifier that will allow one process to identify another one as that he is searching for. I was thinking about different concepts, for eg. :

- Process ID is an adress of beginning of block with data that describes that process.
(+)
It would be great thing because when one process is saying to kernel to do something with process X kernel already has its adress and don't need to search for it.
(-)
BUT this type of implementation is impossible because on PC's with small ram, it is possible that I will have process A at adress X, later I will kill it and in thesame adress will be created describing block of process B (so it gains ID of old A) and if there will be C that was comunicating with A it won't se difference between A and B and will continue to sen him some messages.

So now in my OS I have something like this:
- PID that is newer replicated after old procesess
- "Process Adress" - that is used to do fast messaging, this is in fact that decription block adress.

But such thing isn't enough because process that is executing have some name, and after that name it can be identified, so I also addedd 32byte
name field that is name of process mirror. And for supporting compatibility bacward, with name comes version of this process and version of the oldes compatible backward.

So at end every process in my kernel is represented by:
-(adress)
-PID
-version
-compatibility version
-32byte mirror name

But I'm wondering is there is some other solution (maybe easier). How it looks in your OSes ?

Posted: Wed Oct 04, 2006 3:48 pm
by jvff
Hello,

I don't know if this is worth it in a small memory PC, but from what I read from the KeyKOS docs, they use keys to describe the capabilities of a process with another process (ie. it's connection to other processes). So I suppose you could keep track of PIDs, and the keys. For instance, you could handle out keys (which could be a simple number; the KeyID) and keep track of what keys refer to what process (perhaps on a more complex system the keys also have with what permissions and features it has access too). See: http://en.wikipedia.org/wiki/Capability ... er_Systems.

Perhaps a more simpler and less memory hungry principle is to hand out a key that is the lower half a PID and the upper half the time it was handled (perhaps encrypted), so you can discover when there is a request with a key that's too old. Or even better could be using the time half as a checksum with the time itself, so you can encrypt the key.

Or maybe it's all just too complex =) Hope this helps,

JVFF

Re: Process identification.

Posted: Wed Oct 04, 2006 8:26 pm
by rexlunae
mrkaktus wrote:- Process ID is an adress of beginning of block with data that describes that process.
You must not be planning to use paging to separate processes then, right? Or perhaps the address you are storing is the physical address...

It's probably a bad idea to trust pointers passed from a process. If a process passes you a bad pointer, the kernel could end up attempting to access memory that it shouldn't. I don't really see a good way to verify that those pointers are valid.
mrkaktus wrote: (+)
It would be great thing because when one process is saying to kernel to do something with process X kernel already has its adress and don't need to search for it.
Yes, but if you kept a process table in the kernel, the PID could be the index into the table and you wouldn't need to search for the process, and, you would avoid the pointer problems.
mrkaktus wrote:
(-)
BUT this type of implementation is impossible because on PC's with small ram, it is possible that I will have process A at adress X, later I will kill it and in thesame adress will be created describing block of process B (so it gains ID of old A) and if there will be C that was comunicating with A it won't se difference between A and B and will continue to sen him some messages.
Worrying about race conditions is valid, but I'm not sure what kind of communication you would be doing based on the PID of the process you are communicating with. You probably should only be using the PID for signals directly related to process control, such as stopping, starting, or killing the process.

You will probably need more than just a PID to identify an IPC. For one thing, it is likely that a particular process will have many IPCs, which the kernel needs to be able to distinguish. Tracking the IPCs separately will solve that problem, and the concern about communication getting crossed by PID recycling. When a process dies, it's IPCs will be closed, so other processes don't accidentally communicate with it.

Posted: Thu Oct 05, 2006 12:57 pm
by mrkaktus
You must not be planning to use paging to separate processes then, right? Or perhaps the address you are storing is the physical address...
I was thinking about physical adress that is beginning of frame that have all data about the process (its mailbox also).
I don't really see a good way to verify that those pointers are valid.
Validating adress given by process is very easy, I made this in such way:
Every block that is describing some process has in some offset from it's beginning a field inside wchich there is negation of beginning adress of that block.So when process gives you "adress", you are adding to it some offset, reading memory (physical all the time) and negating it. If both adressess are thesame, process is correct.

I haven't got process table because I'm designing my OS with decision that everything is a page. So blocks that describes processess are pointing to each other creating several lists at a time (global list of processess, list of different state's). Because of such architecture, Process Description Block must be always in memory and it can't be paged to the hard drive.
It is why having PID as a adress of that block could be possible if assume that never one PDB will be created in place after some old PDB, but I can't assume that so the idea is bad.

About creating PID from process starting time, you can also create it from
system uptime counter state when process is runed, and it leads you to conclusion that you can just have counter that always shows last given PID and you are just increasing it and geting new walue as a PID for now created process.

Posted: Thu Oct 05, 2006 1:48 pm
by rexlunae
mrkaktus wrote: Validating adress given by process is very easy, I made this in such way:
Every block that is describing some process has in some offset from it's beginning a field inside wchich there is negation of beginning adress of that block.So when process gives you "adress", you are adding to it some offset, reading memory (physical all the time) and negating it. If both adressess are thesame, process is correct.
How do you know the process didn't just forge a fake control block and pass the address to it?

Posted: Thu Oct 05, 2006 11:42 pm
by mrkaktus
Because control blocks are in kernel space and are unaccessible form user space :).

Posted: Fri Oct 06, 2006 9:16 am
by rexlunae
mrkaktus wrote:Because control blocks are in kernel space and are unaccessible form user space :).
How do you verify that a block of memory is in kernel space based on it's physical address? Is kernel memory allocated out of a separate pool from user space? Or do you scan the page tables for the page before accessing it?

Posted: Sat Oct 07, 2006 3:54 am
by mrkaktus
When you call INT processor is switching to DPL0, CR3 is reloaded to kernel space, and then every frame is maped : physical = virtual. So Adress that I have I can directly read/access.

In future I will try to make it faster to not reaload CR3, then I will map that frame to kernel space to some TEMP area of paging.

Posted: Sun Oct 08, 2006 6:40 pm
by rexlunae
mrkaktus wrote:When you call INT processor is switching to DPL0, CR3 is reloaded to kernel space, and then every frame is maped : physical = virtual. So Adress that I have I can directly read/access.
If the all the memory is identity mapped for the kernel, then the process could forge a control block by creating one in its own memory space, then passing it's physical address. It wouldn't have to actually know the physical address, it could just run through the entire memory range.

Another thing I've been wondering: Do you have a way to get a complete list of all the processes that are running?

Posted: Sun Oct 08, 2006 9:01 pm
by carbonBased
rexlunae wrote: If the all the memory is identity mapped for the kernel, then the process could forge a control block by creating one in its own memory space, then passing it's physical address. It wouldn't have to actually know the physical address, it could just run through the entire memory range.

Another thing I've been wondering: Do you have a way to get a complete list of all the processes that are running?
I must say I agree with what rexlunae has been saying, and where he's about to take this :) Generally speaking, pointers into system tables/structures, even opaque pointers, aren't a great idea, and are best to avoid, if possible, in my opinion.

Maintaining a PID to Process-Structure mapping table isn't overly difficult, and is probably less overhead then using the pager, or other mechanisms, to ensure a pointer-based system is secure.

--Jeff

Posted: Mon Oct 09, 2006 1:05 pm
by mrkaktus
to rexlunae:

He cannot run across entire memory space because if it will hit wrong place error will ocure and it can be terminated. And even if he could he don't know on how offset the checksum is.

"Do you have a way to get a complete list of all the processes that are running?"

Yes, every process description block is part of two way list called "global process list" and is part of another two direction list "state list". When process is changing state, it is just cuted from one list and pasted in another (using pointers in that state list), and its state number is changed.

So to obtain a list of all processess in some state (or globall list), you only needs to go field by field from the beginning of that list.


to carbonBased:

I don't need to use any pager to get adress :?.

Posted: Mon Oct 09, 2006 7:26 pm
by rexlunae
mrkaktus wrote:to rexlunae:
He cannot run across entire memory space because if it will hit wrong place error will ocure and it can be terminated.
It seems to me that it would be a bad thing to terminate a process just because of an error in a system call without even giving it a chance to catch the error. But, even so, that doesn't solve the problem, it would just slightly obfuscate it. There would still be a non-trivial chance that a process could guess the correct physical address for it's memory, especially if a controlling process were to spawn a bunch of children to try over and over again.
mrkaktus wrote:And even if he could he don't know on how offset the checksum is.
I guarentee that once your OS has been around for a few minutes, someone will figure out what the offset of the checksum is. Trying to hide how the kernel works will not prevent people from discovering vulnerabiliites, just ask Microsoft. See also: Security by Obscurity, which also applies to the idea that a process can't guess the physical address of memory in it's address space.

I completely agree with what carbonbased said, there is no benefit (not one that I can think of) in the kernel accepting a pointer from userland to something in its own address space. That just makes it harder for the kernel to be certain of its validity. Perhaps you could explain a little more about why you think this is useful?

Posted: Tue Oct 10, 2006 10:48 am
by mrkaktus
Quoteing myself :P :
Because of such architecture, Process Description Block must be always in memory and it can't be paged to the hard drive.
It is why having PID as a adress of that block could be possible if assume that never one PDB will be created in place after some old PDB, but I can't assume that so the idea is bad.
I was only thinking about such way , and I show that it is impossible on the beginning.

I'm using this "direct adress" to support fast messaging, because I know there is no way to make something bad from process space. If process will generate fake "process description block" and give it's pointer as a parameter in calling message: send or receive, it will just manage that kernel will put in that fake block message from that process or will return to that process message from its fake block. So nothing is going to be critical :).

And in future design's of my kernel I will try to remove it, but now it is just first version so a lot of thing's need to be redesigned and ofc, this API won't be "the last and forever" so I'm not worrying about that at all :).