Pārlūkot izejas kodu

bugfix: 解决取消低地址映射时,错误的把重映射的物理页释放,从而导致的use after free问题。 (#321)

LoGin 1 gadu atpakaļ
vecāks
revīzija
26887c6334

+ 2 - 2
kernel/src/arch/x86_64/mm/mod.rs

@@ -610,10 +610,10 @@ impl LowAddressRemapping {
         assert!(mapper.as_mut().is_some());
         for i in 0..(Self::REMAP_SIZE / MMArch::PAGE_SIZE) {
             let vaddr = VirtAddr::new(i * MMArch::PAGE_SIZE);
-            let flusher = mapper
+            let (_, _, flusher) = mapper
                 .as_mut()
                 .unwrap()
-                .unmap(vaddr, true)
+                .unmap_phys(vaddr, true)
                 .expect("Failed to unmap frame");
             if flush == false {
                 flusher.ignore();

+ 2 - 4
kernel/src/driver/multiboot2/multiboot2.c

@@ -1,6 +1,5 @@
 #include "multiboot2.h"
 
-
 #include <common/glib.h>
 #include <common/kprint.h>
 uintptr_t multiboot2_boot_info_addr;
@@ -11,8 +10,7 @@ bool multiboot2_init(void)
 {
     uintptr_t *addr = (uintptr_t *)multiboot2_boot_info_addr;
     if (multiboot2_magic != MULTIBOOT2_BOOTLOADER_MAGIC)
-        ;
-    return false;
+        return false;
     // addr+0 处保存了大小
     multiboot2_boot_info_size = *(unsigned int *)addr;
     return true;
@@ -24,7 +22,7 @@ void multiboot2_iter(bool (*_fun)(const struct iter_data_t *, void *, unsigned i
 
     uintptr_t addr = multiboot2_boot_info_addr;
     // 接下来的第8字节开始,为 tag 信息
-    struct iter_data_t *tag = (struct iter_data_t *)((void*)addr + 8);
+    struct iter_data_t *tag = (struct iter_data_t *)((void *)addr + 8);
     for (; tag->type != MULTIBOOT_TAG_TYPE_END;
          tag = (struct iter_data_t *)((uint8_t *)tag + ALIGN(tag->size, 8)))
     {

+ 1 - 1
kernel/src/filesystem/mod.rs

@@ -3,6 +3,6 @@ pub mod fat;
 pub mod mbr;
 pub mod procfs;
 pub mod ramfs;
+pub mod syscall;
 pub mod sysfs;
 pub mod vfs;
-pub mod syscall;

+ 1 - 0
kernel/src/libs/notifier.rs

@@ -1,3 +1,4 @@
+#![allow(dead_code)]
 use crate::{
     kwarn,
     libs::{rwlock::RwLock, spinlock::SpinLock},

+ 13 - 6
kernel/src/mm/allocator/buddy.rs

@@ -7,7 +7,7 @@ use crate::arch::MMArch;
 use crate::mm::allocator::bump::BumpAllocator;
 use crate::mm::allocator::page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage};
 use crate::mm::{MemoryManagementArch, PhysAddr, VirtAddr};
-use crate::{kdebug, kerror, kwarn};
+use crate::{kdebug, kwarn};
 use core::cmp::{max, min};
 use core::fmt::Debug;
 use core::intrinsics::{likely, unlikely};
@@ -207,7 +207,8 @@ impl<A: MemoryManagementArch> BuddyAllocator<A> {
         assert!(remain_bytes < (1 << MAX_ORDER - 1));
 
         for i in (MIN_ORDER..MAX_ORDER).rev() {
-            if remain_bytes & (1 << i) != 0 {
+            if remain_bytes >= (1 << i) {
+                assert!(paddr & ((1 << i) - 1) == 0);
                 let page_list_paddr: PhysAddr = free_area[Self::order2index(i as u8)];
                 let mut page_list: PageList<A> = Self::read_page(page_list_paddr);
 
@@ -281,8 +282,6 @@ impl<A: MemoryManagementArch> BuddyAllocator<A> {
             let mut page_list_addr = self.free_area[Self::order2index(spec_order)];
             let mut page_list: PageList<A> = Self::read_page(page_list_addr);
 
-            // kdebug!("page_list={page_list:?}");
-
             // 循环删除头部的空闲链表页
             while page_list.entry_num == 0 {
                 let next_page_list_addr = page_list.next_page;
@@ -315,8 +314,15 @@ impl<A: MemoryManagementArch> BuddyAllocator<A> {
                         page_list.entry_num - 1,
                     ))
                 };
+                // 清除该entry
+                unsafe {
+                    A::write(
+                        Self::entry_virt_addr(page_list_addr, page_list.entry_num - 1),
+                        PhysAddr::new(0),
+                    )
+                };
                 if entry.is_null() {
-                    kerror!(
+                    panic!(
                         "entry is null, entry={:?}, order={}, entry_num = {}",
                         entry,
                         spec_order,
@@ -324,6 +330,7 @@ impl<A: MemoryManagementArch> BuddyAllocator<A> {
                     );
                 }
                 // kdebug!("entry={entry:?}");
+
                 // 更新page_list的entry_num
                 page_list.entry_num -= 1;
                 let tmp_current_entry_num = page_list.entry_num;
@@ -344,7 +351,7 @@ impl<A: MemoryManagementArch> BuddyAllocator<A> {
 
                 // 检测entry 是否对齐
                 if !entry.check_aligned(1 << spec_order) {
-                    panic!("entry={:?} is not aligned, spec_order={spec_order}, page_list.entry_num={}", entry,tmp_current_entry_num);
+                    panic!("entry={:?} is not aligned, spec_order={spec_order}, page_list.entry_num={}", entry, tmp_current_entry_num);
                 }
                 return Some(entry);
             }

+ 3 - 2
user/Makefile

@@ -12,7 +12,7 @@ output_dir=$(ROOT_PATH)/bin/user
 CFLAGS := $(GLOBAL_CFLAGS) -I $(shell pwd)/libs -I $(shell pwd)/libs/libc/src/include -I $(shell pwd)/libs/libc/src/include/export
 current_CFLAGS := $(CFLAGS)
 
-DADK_VERSION = $(shell dadk -V | awk 'END {print $2}')
+DADK_VERSION=$(shell dadk -V | awk 'END {print $$2}')
 # 最小的DADK版本
 MIN_DADK_VERSION = 0.1.2
 DADK_CACHE_DIR = $(ROOT_PATH)/bin/dadk_cache
@@ -37,9 +37,10 @@ ifeq ("$(DADK_VERSION)", "")
 	@echo "Auto installing dadk..."
 	CC=gcc AS=as AR=ar LD=ld OBJCOPY=objcopy NM=nm cargo install dadk
 else
+# 如果DADK版本过低,则自动更新
 	@echo "dadk version $(DADK_VERSION) installed"
 # 如果DADK版本过低,则自动更新
-ifeq ($(shell printf '%s\n' "$(DADK_VERSION)" "$(MIN_DADK_VERSION)" | sort -V | head -n1), $(MIN_DADK_VERSION))
+ifneq ($(shell printf '%s\n%s' "$(DADK_VERSION)" "$(MIN_DADK_VERSION)" | sort -V | head -n1), $(MIN_DADK_VERSION))
 	@echo "dadk version is too low, please update to $(MIN_DADK_VERSION) or higher version"
 	@echo "Updating dadk..."
 	CC=gcc AS=as AR=ar LD=ld OBJCOPY=objcopy NM=nm cargo install dadk || (echo "dadk update failed" && exit 1)