MyOS example updated with `cld` instruction

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
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

MyOS example updated with `cld` instruction

Post by sortie »

Hi,

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

    Code: Select all

    mov foo, %eax
    call *%eax
    which is easily simplified into

    Code: Select all

    call foo
    .
  • Or any of James Molloy's Tutorial Known Bugs.
Thank you. If you find any further problems, please let me know so we can fight the community copying implementations full of old bugs.
Octocontrabass
Member
Member
Posts: 5586
Joined: Mon Mar 25, 2013 7:01 pm

Re: MyOS example updated with `cld` instruction

Post by Octocontrabass »

sortie wrote:
  • You don't have useless instruction sequences
This could be a ljmp instead of three instructions.
FallenAvatar
Member
Member
Posts: 283
Joined: Mon Jan 03, 2011 6:58 pm

Re: MyOS example updated with `cld` instruction

Post by FallenAvatar »

Your repository seems to be missing a license.

- Monk
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: MyOS example updated with `cld` instruction

Post by sortie »

Octocontrabass wrote:This could be a ljmp instead of three instructions.
Thanks, I will think about this. I recall doing retf on purpose, or maybe just to show it off, as it is more dynamic than the odd ljmp syntax.
tjmonk15 wrote:Your repository seems to be missing a license.
It is licensed under CC0 like the wiki and the meaty skeleton tutorial it is based on. I'll make a note to put the license in the repository for clarity.
Octocontrabass
Member
Member
Posts: 5586
Joined: Mon Mar 25, 2013 7:01 pm

Re: MyOS example updated with `cld` instruction

Post by Octocontrabass »

sortie wrote:I recall doing retf on purpose, or maybe just to show it off, as it is more dynamic than the odd ljmp syntax.
There's no ljmp in long mode, so perhaps your x86_64 target would be a better place to show it off.
isaacwoods
Member
Member
Posts: 47
Joined: Sun Sep 06, 2015 5:40 am

Re: MyOS example updated with `cld` instruction

Post by isaacwoods »

Hey; this is my first time seeing your code, and I think I have a lot more to learn, which is always good. In your interrupt handling stub, I noticed that you preserve CR2:

Code: Select all

	movl %cr2, %ebp
	pushl %ebp

	...

	popl %ebp
	movl %ebp, %cr2
My code doesn't and I haven't seen anywhere that recommends to do this, what is the rationale for doing this? I am not doubting that there's a good reason for it, I am pretty inexperienced.
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: MyOS example updated with `cld` instruction

Post by sortie »

Hi BaconWraith,

There's no strict reason to preserve cr2. The register is set when a page fault happens. The kernel can inspect the register to find out what happened. If your page fault handler is always non-preemptive nor reentrant there's no reason to preserve it. However, if recursive page fault handling can happen, or if your kernel is preemptive during page fault handling, you may want to preserve it. In my OS, I consider it just another thread register. It avoids it being unintentionally trashed and lets my kernel threads be entirely pre-emptive even during user-space page faults (actually it's not preemptive in that case, since the page fault might have happened in the kernel, but the kernel thread is allowed to enable interrupts and become preemptive).
Post Reply