mirror of
https://github.com/BoredDevNL/BoredOS.git
synced 2026-05-15 10:48:38 +00:00
memory leak fix userspace
This commit is contained in:
parent
8ba03fac72
commit
d19075750b
6 changed files with 72 additions and 14 deletions
BIN
boredos.iso
BIN
boredos.iso
Binary file not shown.
BIN
build/main.o
BIN
build/main.o
Binary file not shown.
BIN
disk.img
BIN
disk.img
Binary file not shown.
|
|
@ -22,16 +22,10 @@ static void write_cr3(uint64_t cr3) {
|
||||||
|
|
||||||
// Helper to allocate a page table and clear it
|
// Helper to allocate a page table and clear it
|
||||||
static uint64_t alloc_page_table_phys(void) {
|
static uint64_t alloc_page_table_phys(void) {
|
||||||
void* ptr = kmalloc(PAGE_SIZE * 2);
|
void *ptr = kmalloc_aligned(PAGE_SIZE, PAGE_SIZE);
|
||||||
if (!ptr) return 0;
|
if (!ptr) return 0;
|
||||||
|
|
||||||
// Align to PAGE_SIZE virtually
|
page_table_t* table = (page_table_t*)ptr;
|
||||||
uintptr_t addr = (uintptr_t)ptr;
|
|
||||||
if (addr % PAGE_SIZE != 0) {
|
|
||||||
addr = (addr + PAGE_SIZE) & ~(PAGE_SIZE - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
page_table_t* table = (page_table_t*)addr;
|
|
||||||
|
|
||||||
// Clear table
|
// Clear table
|
||||||
for (int i = 0; i < 512; i++) {
|
for (int i = 0; i < 512; i++) {
|
||||||
|
|
@ -120,3 +114,44 @@ uint64_t paging_create_user_pml4_phys(void) {
|
||||||
// The lower half (0-255) is left empty for the user process to use
|
// The lower half (0-255) is left empty for the user process to use
|
||||||
return new_pml4_phys;
|
return new_pml4_phys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void paging_destroy_user_pml4_phys(uint64_t pml4_phys) {
|
||||||
|
if (!pml4_phys) return;
|
||||||
|
page_table_t* pml4 = (page_table_t*)p2v(pml4_phys);
|
||||||
|
|
||||||
|
// Only traverse lower half (user space, indices 0-255)
|
||||||
|
for (int pml4_idx = 0; pml4_idx < 256; pml4_idx++) {
|
||||||
|
if (pml4->entries[pml4_idx] & PT_PRESENT) {
|
||||||
|
page_table_t* pdpt = (page_table_t*)p2v(pml4->entries[pml4_idx] & PT_ADDR_MASK);
|
||||||
|
|
||||||
|
for (int pdpt_idx = 0; pdpt_idx < 512; pdpt_idx++) {
|
||||||
|
if (pdpt->entries[pdpt_idx] & PT_PRESENT) {
|
||||||
|
page_table_t* pd = (page_table_t*)p2v(pdpt->entries[pdpt_idx] & PT_ADDR_MASK);
|
||||||
|
|
||||||
|
for (int pd_idx = 0; pd_idx < 512; pd_idx++) {
|
||||||
|
if (pd->entries[pd_idx] & PT_PRESENT) {
|
||||||
|
page_table_t* pt = (page_table_t*)p2v(pd->entries[pd_idx] & PT_ADDR_MASK);
|
||||||
|
|
||||||
|
for (int pt_idx = 0; pt_idx < 512; pt_idx++) {
|
||||||
|
if (pt->entries[pt_idx] & PT_PRESENT) {
|
||||||
|
uint64_t phys_addr = pt->entries[pt_idx] & PT_ADDR_MASK;
|
||||||
|
extern void kfree(void* ptr);
|
||||||
|
kfree((void*)p2v(phys_addr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
extern void kfree(void* ptr);
|
||||||
|
kfree((void*)pt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
extern void kfree(void* ptr);
|
||||||
|
kfree((void*)pd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
extern void kfree(void* ptr);
|
||||||
|
kfree((void*)pdpt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Finally free the pml4 itself
|
||||||
|
extern void kfree(void* ptr);
|
||||||
|
kfree((void*)pml4);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,19 +27,16 @@ typedef struct {
|
||||||
uint64_t entries[512];
|
uint64_t entries[512];
|
||||||
} __attribute__((aligned(PAGE_SIZE))) page_table_t;
|
} __attribute__((aligned(PAGE_SIZE))) page_table_t;
|
||||||
|
|
||||||
// Get the current PML4 physical address
|
|
||||||
uint64_t paging_get_pml4_phys(void);
|
uint64_t paging_get_pml4_phys(void);
|
||||||
|
|
||||||
// Map a physical address to a virtual address
|
|
||||||
void paging_map_page(uint64_t pml4_phys, uint64_t virtual_addr, uint64_t physical_addr, uint64_t flags);
|
void paging_map_page(uint64_t pml4_phys, uint64_t virtual_addr, uint64_t physical_addr, uint64_t flags);
|
||||||
|
|
||||||
// Create a new, isolated PML4 for a user process (returns physical address)
|
|
||||||
uint64_t paging_create_user_pml4_phys(void);
|
uint64_t paging_create_user_pml4_phys(void);
|
||||||
|
|
||||||
// Switch the active page table (takes physical address)
|
|
||||||
void paging_switch_directory(uint64_t pml4_phys);
|
void paging_switch_directory(uint64_t pml4_phys);
|
||||||
|
|
||||||
// Initialize paging system (if needed beyond Limine's setup)
|
void paging_destroy_user_pml4_phys(uint64_t pml4_phys);
|
||||||
|
|
||||||
void paging_init(void);
|
void paging_init(void);
|
||||||
|
|
||||||
#endif // PAGING_H
|
#endif // PAGING_H
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ process_t processes[MAX_PROCESSES] __attribute__((aligned(16)));
|
||||||
int process_count = 0;
|
int process_count = 0;
|
||||||
static process_t* current_process = NULL;
|
static process_t* current_process = NULL;
|
||||||
static uint32_t next_pid = 0;
|
static uint32_t next_pid = 0;
|
||||||
|
static void *free_kernel_stack_later = NULL;
|
||||||
|
|
||||||
void process_init(void) {
|
void process_init(void) {
|
||||||
for (int i = 0; i < MAX_PROCESSES; i++) {
|
for (int i = 0; i < MAX_PROCESSES; i++) {
|
||||||
|
|
@ -329,6 +330,11 @@ process_t* process_get_current(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t process_schedule(uint64_t current_rsp) {
|
uint64_t process_schedule(uint64_t current_rsp) {
|
||||||
|
if (free_kernel_stack_later) {
|
||||||
|
kfree(free_kernel_stack_later);
|
||||||
|
free_kernel_stack_later = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!current_process || !current_process->next || current_process == current_process->next)
|
if (!current_process || !current_process->next || current_process == current_process->next)
|
||||||
return current_rsp;
|
return current_rsp;
|
||||||
|
|
||||||
|
|
@ -433,9 +439,22 @@ void process_terminate(process_t *to_delete) {
|
||||||
to_delete->pid = 0xFFFFFFFF;
|
to_delete->pid = 0xFFFFFFFF;
|
||||||
|
|
||||||
if (to_delete->user_stack_alloc) kfree(to_delete->user_stack_alloc);
|
if (to_delete->user_stack_alloc) kfree(to_delete->user_stack_alloc);
|
||||||
if (to_delete->kernel_stack_alloc) kfree(to_delete->kernel_stack_alloc);
|
if (to_delete->kernel_stack_alloc) {
|
||||||
|
if (to_delete == current_process) {
|
||||||
|
free_kernel_stack_later = to_delete->kernel_stack_alloc;
|
||||||
|
} else {
|
||||||
|
kfree(to_delete->kernel_stack_alloc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void paging_destroy_user_pml4_phys(uint64_t pml4_phys);
|
||||||
|
if (to_delete->pml4_phys && to_delete->is_user) {
|
||||||
|
paging_destroy_user_pml4_phys(to_delete->pml4_phys);
|
||||||
|
}
|
||||||
|
|
||||||
to_delete->user_stack_alloc = NULL;
|
to_delete->user_stack_alloc = NULL;
|
||||||
to_delete->kernel_stack_alloc = NULL;
|
to_delete->kernel_stack_alloc = NULL;
|
||||||
|
to_delete->pml4_phys = 0;
|
||||||
|
|
||||||
asm volatile("push %0; popfq" : : "r"(rflags));
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
}
|
}
|
||||||
|
|
@ -486,9 +505,16 @@ uint64_t process_terminate_current(void) {
|
||||||
// kernel stack is unsafe while we are still running on it.
|
// kernel stack is unsafe while we are still running on it.
|
||||||
if (to_delete->user_stack_alloc) kfree(to_delete->user_stack_alloc);
|
if (to_delete->user_stack_alloc) kfree(to_delete->user_stack_alloc);
|
||||||
|
|
||||||
|
extern void paging_destroy_user_pml4_phys(uint64_t pml4_phys);
|
||||||
|
if (to_delete->pml4_phys && to_delete->is_user) {
|
||||||
|
paging_destroy_user_pml4_phys(to_delete->pml4_phys);
|
||||||
|
}
|
||||||
|
|
||||||
// Clear pointers to avoid double-free during slot reuse
|
// Clear pointers to avoid double-free during slot reuse
|
||||||
to_delete->user_stack_alloc = NULL;
|
to_delete->user_stack_alloc = NULL;
|
||||||
|
free_kernel_stack_later = to_delete->kernel_stack_alloc;
|
||||||
to_delete->kernel_stack_alloc = NULL; // Leak the small kernel stack for safety
|
to_delete->kernel_stack_alloc = NULL; // Leak the small kernel stack for safety
|
||||||
|
to_delete->pml4_phys = 0;
|
||||||
|
|
||||||
uint64_t next_rsp = current_process->rsp;
|
uint64_t next_rsp = current_process->rsp;
|
||||||
asm volatile("push %0; popfq" : : "r"(rflags));
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue