ISR Customization
-
- Member
- Posts: 193
- Joined: Wed Jan 11, 2012 6:10 pm
ISR Customization
I know it's a bit early to be thinking about this, but I don't really care....
One of the ideas for my kernel is the use of sub-idt's customizable for each process, the reason being that it provides extra protection against interfering with drivers or installing spyware and adware. It'd probably be more of a sandbox-like feature than be used for all applications....
Now, the way it works is that one of the interrupts in the real idt looks up the table corresponding to the current process and calls sub-idt interrupts. So, basically, I need to find a way to hook all the interrupts called by process. My initial idea was this:
1. Run once through the entire application, storing the pc offsets and isr number for each isr into a table and changing the isr number for each call to whatever the isr for the sub-isr handler is going to be.
2. The isr itself checks the application type in order to figure out which sub-idt to use
3. The isr compares pc to the offsets in the table and calls the sub-isr of the value that matches.
The pro's:
1. Possible to have as many sub-idts as you want (within the boundaries of the obvious limitations such as memory).
2. Easy to hook, debug, or replace isr's without negatively affecting other processes
The con's:
1. Uses more memory
2. Applications take a little longer to start up
3. Dynamically allocated functions (such as those loaded into ram by the user, and called through a type-cast) can't be patched, and won't be protected against, defeating the purpose altogether
Can anyone else think of a better way to do this? Preferably a method that patches the code before execution so it doesn't negatively affect performance?
One of the ideas for my kernel is the use of sub-idt's customizable for each process, the reason being that it provides extra protection against interfering with drivers or installing spyware and adware. It'd probably be more of a sandbox-like feature than be used for all applications....
Now, the way it works is that one of the interrupts in the real idt looks up the table corresponding to the current process and calls sub-idt interrupts. So, basically, I need to find a way to hook all the interrupts called by process. My initial idea was this:
1. Run once through the entire application, storing the pc offsets and isr number for each isr into a table and changing the isr number for each call to whatever the isr for the sub-isr handler is going to be.
2. The isr itself checks the application type in order to figure out which sub-idt to use
3. The isr compares pc to the offsets in the table and calls the sub-isr of the value that matches.
The pro's:
1. Possible to have as many sub-idts as you want (within the boundaries of the obvious limitations such as memory).
2. Easy to hook, debug, or replace isr's without negatively affecting other processes
The con's:
1. Uses more memory
2. Applications take a little longer to start up
3. Dynamically allocated functions (such as those loaded into ram by the user, and called through a type-cast) can't be patched, and won't be protected against, defeating the purpose altogether
Can anyone else think of a better way to do this? Preferably a method that patches the code before execution so it doesn't negatively affect performance?
Re: ISR Customization
The best way to do it NOT to do it.
This seems like it's coming from a place of good intent, but I don't think this will work the way you want it to.
Even if you got the x86 processor to IGNORE running the ISR at the location given in the IDT, there would be no way to pass a "sub-idt" interrupt number....
The only way to use your proposed system would be either storing the ISR number (relative to sub-idt) ina known memory location (INSECURE) or identity (e.g. 1:1) mapping the real IDT and sub-IDT which literally defeats the purpose....
If you want to run a sandbox environment, then make a sandbox environment.
Sandbox implies protection from executing/accessing outside of a memory range and that is all. Those "features" can be implemented using paging and a half intelligent memory manager.
This seems like it's coming from a place of good intent, but I don't think this will work the way you want it to.
Even if you got the x86 processor to IGNORE running the ISR at the location given in the IDT, there would be no way to pass a "sub-idt" interrupt number....
The only way to use your proposed system would be either storing the ISR number (relative to sub-idt) ina known memory location (INSECURE) or identity (e.g. 1:1) mapping the real IDT and sub-IDT which literally defeats the purpose....
If you want to run a sandbox environment, then make a sandbox environment.
Sandbox implies protection from executing/accessing outside of a memory range and that is all. Those "features" can be implemented using paging and a half intelligent memory manager.
Re: ISR Customization
The main purpose of ISR is provide IRQ handlers. While you may swap IDTs you still react to the same piece of hardware, unless you do hardware virtualization, which is probably not you wanted.
In almost all other case, your objective can be done with delegate event/signal, which is very safe.
In almost all other case, your objective can be done with delegate event/signal, which is very safe.
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: ISR Customization
The security mechanism you are meant to use is the DPL field in the IDT. It tells you if userspace can call that interrupt or not. The only thing you are left to do is make sure that the interrupts userland can use do not overlap with hardware IRQs. That way userland can never interfere with hardware IRQs.
Re: ISR Customization
I can imagine an API call that installs a user-mode ISR for a given INT number, for a certain process. Then if the process issues an INT, the kernel-mode ISR calls the installed ISR for that process. This may even be sensible for some hardware interrupts (for example if the process owns a window that has keyboard focus). I'm not sure if this is what you mean though.
-
- Member
- Posts: 193
- Joined: Wed Jan 11, 2012 6:10 pm
Re: ISR Customization
Well, basically the idea is that one ISR handles all the ISR's used by an application, and there are several benefits for doing it this way:
1. It is impossible for any software to make changes to drivers without permission from the kernel
2. Changes can be made to the IDT without having to suspend the currently running applications
3. Applications can manage their own ISR's if they want, improving performance and cutting down on code size by using software interrupts.
4. Emulators such as WINE can take advantage of it to improve performance
I know it sounds like a hassle, but it's something that I don't think has ever been done before and I want to implement it in my kernel.
1. It is impossible for any software to make changes to drivers without permission from the kernel
2. Changes can be made to the IDT without having to suspend the currently running applications
3. Applications can manage their own ISR's if they want, improving performance and cutting down on code size by using software interrupts.
4. Emulators such as WINE can take advantage of it to improve performance
I know it sounds like a hassle, but it's something that I don't think has ever been done before and I want to implement it in my kernel.
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: ISR Customization
Use case wanted.3. Applications can manage their own ISR's if they want, improving performance
There is only one reason for userland to call an interrupt, and that is a system call. Changing the interrupt number doesn't change the speed. Not using interrupts and resorting to far call/syscall/sysenter is the way to speed up system calls at that level.
If the software in question is not an application, but a userland driver, there might be an excuse to forward IRQs in driver time directly to itself. The efficiency of that is doubtful, as you won't get any improvement of IRQs in other address spaces, and IRQs arriving when the CPU is in kernel land would mean an inverse task switch and the CPU will instead generate a GPF and consequently doubles the IRQ cost.
Then the following comments are irrelevant to the problem altogether:
A single global IDT is more than enough for that.1. It is impossible for any software to make changes to drivers without permission from the kernel
I don't believe you know the meaning of "suspend". If a process may not modify the IDT then the direct consequence of that is that any modifications will be performed out of the process' scope, and the process does not care.2. Changes can be made to the IDT without having to suspend the currently running applications
Point 4 covers a niche, and is only a quick and dirty hack around doing proper emulation or virtualisation.
-
- Member
- Posts: 193
- Joined: Wed Jan 11, 2012 6:10 pm
Re: ISR Customization
Userland drivers were pretty much the idea.Combuster wrote:Use case wanted.
There is only one reason for userland to call an interrupt, and that is a system call. Changing the interrupt number doesn't change the speed. Not using interrupts and resorting to far call/syscall/sysenter is the way to speed up system calls at that level.
If the software in question is not an application, but a userland driver, there might be an excuse to forward IRQs in driver time directly to itself. The efficiency of that is doubtful, as you won't get any improvement of IRQs in other address spaces, and IRQs arriving when the CPU is in kernel land would mean an inverse task switch and the CPU will instead generate a GPF and consequently doubles the IRQ cost.
This could fail if someone finds an exploit to get their applications into kernel space. Like I said, it's mainly a sandbox-like feature.Combuster wrote:Then the following comments are irrelevant to the problem altogether:A single global IDT is more than enough for that.1. It is impossible for any software to make changes to drivers without permission from the kernel
I don't think you understand what I meant. If you're changing drivers (such as the graphics drivers), you'd need to suspend the current processes so they don't accidentally call an ISR while you're changing it. If IDT's were customizable from user space, then the changes would only affect them after they've been restarted, and they could still be running while you do whatever you want to the IDT.Combuster wrote:I don't believe you know the meaning of "suspend". If a process may not modify the IDT then the direct consequence of that is that any modifications will be performed out of the process' scope, and the process does not care.2. Changes can be made to the IDT without having to suspend the currently running applications
I would prefer a quick and dirty hack that emulates software perfectly any day over emulating the 'proper way' and the applications being extremely slow and in many cases not being able to be run at all.Combuster wrote:Point 4 covers a niche, and is only a quick and dirty hack around doing proper emulation or virtualisation.
Re: ISR Customization
In that case, you're doomed. Once applications get into kernel space, it can do everything - there is no way to defense.SoulofDeity wrote:This could fail if someone finds an exploit to get their applications into kernel space.
The same logic can be implemented with function table, I don't see the advantage on abusing IDT.SoulofDeity wrote:I don't think you understand what I meant. If you're changing drivers (such as the graphics drivers), you'd need to suspend the current processes so they don't accidentally call an ISR while you're changing it. If IDT's were customizable from user space, then the changes would only affect them after they've been restarted, and they could still be running while you do whatever you want to the IDT.
Furthermore, you really don't want two drivers active as the same time, they will compete resources;
On the other hand, with proper design, the GUI could function without interrupt (draw to virtual buffers) while changing graphic driver, only the monitor may got blank out while driver changes.
-
- Member
- Posts: 193
- Joined: Wed Jan 11, 2012 6:10 pm
Re: ISR Customization
True, but it would be extremely difficult to impossible for the application to make any permanent changes since the remapped ISR's would limit it's access to the hard disk and prevent them from installing drivers; and if the kernel doesn't use a flat memory model then they can't inject code into the kernel either. Really all they could do is mess with memory in the kernel data section and perhaps cause the pc to crash, but anything they could do would just be temporary.bluemoon wrote:In that case, you're doomed. Once applications get into kernel space, it can do everything - there is no way to defense.SoulofDeity wrote:This could fail if someone finds an exploit to get their applications into kernel space.
Well, it's really more of a perk. Like I said before, the main uses are malware protection and virtualization.bluemoon wrote:The same logic can be implemented with function table, I don't see the advantage on abusing IDT.
Furthermore, you really don't want two drivers active as the same time, they will compete resources;
On the other hand, with proper design, the GUI could function without interrupt (draw to virtual buffers) while changing graphic driver, only the monitor may got blank out while driver changes.
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: ISR Customization
Unless the driver itself hosts an exploit, attacks typically do not contain device-specific code as that arbitrarily limits the amount of machines on which it would work. Instead it would simply use open/write calls and the code that protects ISR numbers would do the work for the attack.the remapped ISR's would limit it's access to the hard disk
Utter nonsense. You just claimed the equivalent of DOS being unhackable.if the kernel doesn't use a flat memory model then they can't inject code into the kernel either
I have the idea you're clueless about how exploits work.
-
- Member
- Posts: 193
- Joined: Wed Jan 11, 2012 6:10 pm
Re: ISR Customization
Again, you're misunderstanding me. I'm saying that the sub-idt would be cut off from low level functions such as modifying the real idt, modifying drivers, modifying system files and settings, etc. Once the ISR's have been remapped, it can't be undone unless the user restarts the process outside sandbox mode. So, if an application starts in user mode and miraculously gets into kernel mode, it still won't be able to call the kernel mode isr's. What I'm saying is that together with the below part:Combuster wrote:Unless the driver itself hosts an exploit, attacks typically do not contain device-specific code as that arbitrarily limits the amount of machines on which it would work. Instead it would simply use open/write calls and the code that protects ISR numbers would do the work for the attack.the remapped ISR's would limit it's access to the hard disk
...the applications cannot modify the kernel in RAM or on the hard disk. The kernel itself planned to be a virtualizing monolithic model; so you can understand why my primary focus is to prevent unauthorized installation of drivers, since that'll pretty much be the only way to exploit it.if the kernel doesn't use a flat memory model then they can't inject code into the kernel either
EDIT:
Not to be rude here, but this topic wasn't made to talk about isr customization being reasonable, I was asking the best way to hook all the isr's in an application and redirect them to a single isr.
Re: ISR Customization
No. any ring0 code can read&write IDT by SIDT, map it, LIDT, this including code injection - all supported by the CPU itself and do not require kernel call.SoulofDeity wrote:I'm saying that the sub-idt would be cut off from low level functions such as modifying the real idt
If your driver is not running ring0, I then do not see any advantage over traditional event mechanism.
I'm not sure why should on modify driver, but with a bit of reverse engineering(If the Os worth spending any effort at all), it should be possible to figure out the mechanism and data structures of permission, and grant permission, then it can call standard kernel/DDK function for driver manipulation.SoulofDeity wrote:modifying drivers
No. The ISR can be freely modified anytime by bad drivers.SoulofDeity wrote:Once the ISR's have been remapped, it can't be undone
Simple not true. Ring0 grant access to take over the whole machine.SoulofDeity wrote:...the applications cannot modify the kernel in RAM or on the hard disk.
To summarize, I do not see how sub-idt provide extra security, while the issue is about control of (code-signed) authorized driver.
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: ISR Customization
All in all,SoulofDeity wrote:Not to be rude here, but this topic wasn't made to talk about isr customization being reasonable, I was asking the best way to hook all the isr's in an application and redirect them to a single isr.
- You talk too much yet can't explain what you are doing
- You're continuously changing the subject slightly
- You repeatedly post nonsense
- You accuse me of not understanding said nonsense.
- You try to appear way too sophisticated for your post count.
In other words, I'm going to call a troll on this.
Re: ISR Customization
Me thinks that the thread creator doesn't know the difference between IRQs and software interrupts. I'm not even sure if the discussion is about IRQs or software interrupts. The main resources of a typical driver is not IRQs, but memory and IO, which are the resources a driver must claim (in addition to a possible IRQ). In fact, most drivers can be done without using IRQs. I've done USB drivers that are interrupt-less, mainly because I lacked ACPI and the ability to detect which IRQ the USB chip used. Additionally, if the discussion instead is about software interrupts, then I see no reason to involve IDT. A kernel can handle software interrupts from applications by virtualization via GPF. That can be done by setting all permission bits in IDT to kernel only. OTOH, call gates and sysenter/syscall are much more efficient on modern hardware than software interrupts, so I see no reason to use software interrupts in a new design.
Maybe the thread creator should study the DPMI-specification, which deals with all the gruesome details of interrupt hooking and routing that really is a nightmare to implement correctly. The initial specification was 0.9, and that was the one implemented in Windows. AFAIK, nobody implemented 1.0 (me excluded), which went further in its demands of the host.
Maybe the thread creator should study the DPMI-specification, which deals with all the gruesome details of interrupt hooking and routing that really is a nightmare to implement correctly. The initial specification was 0.9, and that was the one implemented in Windows. AFAIK, nobody implemented 1.0 (me excluded), which went further in its demands of the host.