Design of data-descriptor for code in ring 1 or 2
Posted: Fri May 16, 2014 11:47 am
Hi folks,
I wonder about how to design the data-descriptor for a “module” (driver, executable) in rings 1 and 2 and like to know your experiences or hints because maybe I’m totally wrong and lost.
The virtual memory of my OS defines the first virtual GB for use in ring 0-2, the virtual memory above is for ring 3. A task-change shall change the memory-mapping just for ring 3 (above 1GB), the first virtual GB remains the same in all tasks.
Now I do a call from ring 3 to ring 2. The SS changes regarding to my TSS, the DS doesn’t change. Now I’m in ring 2 with the DS of ring 3.
The DS of ring 3 points to a “user-mode-descriptor” using virtual memory above 1GB. I’m pretty sure that my ring-2-code might need to access data from this user-space for whatever reason. But I’m pretty sure too that my ring-2-code also need access to “local data” not in user-space but in the first virtual GB. Unfortunately, with the actual DS from user-space, the ring-2-code cannot access virtual memory in the first GB. Right?
So I think about changing the DS in my ring-2-code to use another descriptor. And now I don’t know how this descriptor should look like. I have two ideas, both I don’t like:
(1) Every “module” gets its own data-descriptor and describes exactly the data-space the module needs. I think the positive thing is that this is a safe memory-model. No driver/module could write into memory of another module. The disadvantages are a lot of work for the virtual manager if the module calls “malloc()”: I might need to reserve new virtual memory, copy the old mem into the new mem and adjust the DS-descriptor. Even its hard to access user-space: I would need to use a 2nd descriptor (ES) to access the user-memory (I code in C++, so using just one “DS” would be comfortable)
(2) Every “module” has access to virtual memory from 0 to FFFFFFFF. When a module is called, I don’t need to change DS. When I access mem in the 1st GB, I access “kernel data” independent on the current task and I can access user-data w/o any problems. But the big disadvantage: When my module is buggy and writes to whatever memory in the 1st GB, it is able to destroy all kernel/OS data because it is able to write into the virtual mem of all other modules.
How do you handle this? Are there other options? Am I basically wrong?
Thanks a lot,
Enrico.
I wonder about how to design the data-descriptor for a “module” (driver, executable) in rings 1 and 2 and like to know your experiences or hints because maybe I’m totally wrong and lost.
The virtual memory of my OS defines the first virtual GB for use in ring 0-2, the virtual memory above is for ring 3. A task-change shall change the memory-mapping just for ring 3 (above 1GB), the first virtual GB remains the same in all tasks.
Now I do a call from ring 3 to ring 2. The SS changes regarding to my TSS, the DS doesn’t change. Now I’m in ring 2 with the DS of ring 3.
The DS of ring 3 points to a “user-mode-descriptor” using virtual memory above 1GB. I’m pretty sure that my ring-2-code might need to access data from this user-space for whatever reason. But I’m pretty sure too that my ring-2-code also need access to “local data” not in user-space but in the first virtual GB. Unfortunately, with the actual DS from user-space, the ring-2-code cannot access virtual memory in the first GB. Right?
So I think about changing the DS in my ring-2-code to use another descriptor. And now I don’t know how this descriptor should look like. I have two ideas, both I don’t like:
(1) Every “module” gets its own data-descriptor and describes exactly the data-space the module needs. I think the positive thing is that this is a safe memory-model. No driver/module could write into memory of another module. The disadvantages are a lot of work for the virtual manager if the module calls “malloc()”: I might need to reserve new virtual memory, copy the old mem into the new mem and adjust the DS-descriptor. Even its hard to access user-space: I would need to use a 2nd descriptor (ES) to access the user-memory (I code in C++, so using just one “DS” would be comfortable)
(2) Every “module” has access to virtual memory from 0 to FFFFFFFF. When a module is called, I don’t need to change DS. When I access mem in the 1st GB, I access “kernel data” independent on the current task and I can access user-data w/o any problems. But the big disadvantage: When my module is buggy and writes to whatever memory in the 1st GB, it is able to destroy all kernel/OS data because it is able to write into the virtual mem of all other modules.
How do you handle this? Are there other options? Am I basically wrong?
Thanks a lot,
Enrico.