Page 1 of 1

Paging Question

Posted: Sat Oct 18, 2014 7:10 pm
by eryjus
HI,

I'm working on a 64-bit virtual memory manager at the moment. My GDT is located in a frame at physical memory 0x0000000000100000 and my initial paging tables are in 7 contiguous frames at 0x0000000000108000. I have no IDT at the moment, but assume that the GDT and IDT will be analogous. The pages for these frames are addresses are identity mapped for the kernel. I am successfully in long mode and the kernel is also mapped to higher memory. I am working on freeing the 32-bit boot pages I won't need anymore.

I know I will need to keep the mapping for my kernel page tables and GDT, but for user-mode page tables will these addresses be required in those page tables as well? Specifically: should I be marking the GDT page and the page tables pages as shared pages?

Re: Paging Question

Posted: Sat Oct 18, 2014 8:47 pm
by Brendan
Hi,

eryjus wrote:I know I will need to keep the mapping for my kernel page tables and GDT, but for user-mode page tables will these addresses be required in those page tables as well? Specifically: should I be marking the GDT page and the page tables pages as shared pages?
You'd relocate the GDT (and create an IDT) in the kernel's higher memory; and typically none of the pages in kernel space are shared (for security reasons). All of the pages in that temporary identity mapping get removed (including the original GDT) and none of them become shared.


Cheers,

Brendan

Re: Paging Question

Posted: Sat Oct 18, 2014 9:13 pm
by eryjus
Brendan wrote:... and typically none of the pages in kernel space are shared (for security reasons).
Hmmm.... I thought the kernel code needed to be shared so that user space could make calls to the published kernel functions. I'll add it to my research list.

At any rate, Brendan, thank you for your reply.

Re: Paging Question

Posted: Sat Oct 18, 2014 11:43 pm
by dansmahajan
eryjus wrote:
Brendan wrote:... and typically none of the pages in kernel space are shared (for security reasons).
Hmmm.... I thought the kernel code needed to be shared so that user space could make calls to the published kernel functions. I'll add it to my research list.

At any rate, Brendan, thank you for your reply.
I think what @Brendan might have meant is only GDT/IDT code is not to be linked/shared.
AFAIK kernel code has to be linked(read only) in every address space to make a system call.
If kernel code is not linked then we've to switch page directory twice after every system call,i guess i'd be costly operation.

Re: Paging Question

Posted: Sun Oct 19, 2014 5:47 am
by sortie
You want to take advantage of the memory protection offered by paging. You can mark pages as user-space pages. When the CPU is in user-mode, it will refuse to access any pages that isn't marked for user-space use. When a CPU exception/trap/interrupt occurs, it will switch to kernel-mode and access the IDT, GDT and TSS as needed to do the privilege transfer. This means that the IDT/GDT/TSS must be mapped somewhere, but it doesn't need to be readable by user-space, indeed it really shouldn't be (or bad security vulnerabilities happen). You will usually put them among the kernel data, where the kernel is mapped in every single address space identically.

Re: Paging Question

Posted: Sun Oct 19, 2014 8:32 am
by xenos
sortie wrote:This means that the IDT/GDT/TSS must be mapped somewhere, but it doesn't need to be readable by user-space, indeed it really shouldn't be (or bad security vulnerabilities happen).
Just out of curiosity: What would be the security risk of having IDT and GDT user readable? In my kernel the GDT is static, it is once set up at system start and never modified, and it's contents are even in the source code. The same basically applies to the IDT, which is filled with the addresses of all interrupt stubs, and these are also known at system startup. So I see no information in the GDT and IDT that couldn't be also obtained from just looking at the source code / kernel binary / linker map.

Re: Paging Question

Posted: Sun Oct 19, 2014 9:58 am
by sortie
XenOS wrote:
sortie wrote:This means that the IDT/GDT/TSS must be mapped somewhere, but it doesn't need to be readable by user-space, indeed it really shouldn't be (or bad security vulnerabilities happen).
Just out of curiosity: What would be the security risk of having IDT and GDT user readable? In my kernel the GDT is static, it is once set up at system start and never modified, and it's contents are even in the source code. The same basically applies to the IDT, which is filled with the addresses of all interrupt stubs, and these are also known at system startup. So I see no information in the GDT and IDT that couldn't be also obtained from just looking at the source code / kernel binary / linker map.
Ah, I misstated. I meant writeable, where the attack is that the GDT is changed to make user-space kernel space, then do a syscall, and you are now the kernel executing user code. There are concerns with read access as well, but that's mostly just information leaks, if your kernel uses ALSR Internally. Otherwise it's harmless and public information given kernel sources. Still, there is no reason to make it user visible.