I maintain an example OS named MyOS that tries to have good implementations of basic things like the GDT, IDT, TSS, interrupt handling, PIC, and a general template for how to structure an operating system. It builds on top of my Meaty Skeleton tutorial from the wiki.
I've been linking this code a lot, especially the GDT ([1], [2]) and interrupt handling code ([3], [4]), as a way to get people to stop copying the old GDT and interrupt handling from from old tutorials, the same old bad implementations, and get people to copy better implementations instead. People have generally stopped criticizing this code when I link it, suggesting it's not obviously wrong, please let me know you find any problems.
Today I've updated the interrupt handler to add a cld instruction. This was a bad oversight. Without it, an user-space program could potentially have set the direction bit and kernel memory copies would have gone the wrong way, potentially being exploitable.
I'm posting a notification here in case you based your interrupt handling off my code, in which case you should make this change to your code as well.
If you didn't base your code off MyOS, assuming you are following the System V ABI normally used by toolchains such as gcc and clang, please confirm your code does not suffer from these problems:
- You clear the direction flag with the cld instruction.
- You set the kernel data segments (as user-space may be able to set them to the null segment, crashing your kernel) and restore the user-space segments afterwards.
- You 16-byte align the stack in any assembly before using the call instruction. This is a hard System V ABI requirement for both 32-bit and 64-bit x86. This is not only for SSE, the compiler will assume this is the case and you risk having bad mysterious bugs down the road.
- IRQ 2 cannot happen as it is only used internally for cascading IRQ 8 to IRQ 15. There is no reason to handle it and handling it only spreads the myth it can happen.
- You don't have useless instruction sequences like which is easily simplified into
Code: Select all
mov foo, %eax call *%eax
.Code: Select all
call foo
- Or any of James Molloy's Tutorial Known Bugs.