Linux QEMU内存分配问题
我似乎遇到了qemu内存分配的问题Linux QEMU内存分配问题,linux,memory,x86-64,qemu,mmap,Linux,Memory,X86 64,Qemu,Mmap,我似乎遇到了qemu内存分配的问题 static void * x64_syscall_mmap(void *base_addr, u64 size, u32 memory_protection, u32 mapping_visibility, s32 fd, u64 fd_offset) { s64 result = 0; __asm__ __volatile__("mov r10, %5\n" "
static void *
x64_syscall_mmap(void *base_addr, u64 size, u32 memory_protection,
u32 mapping_visibility, s32 fd, u64 fd_offset)
{
s64 result = 0;
__asm__ __volatile__("mov r10, %5\n"
"mov r8, %6\n"
"mov r9, %7\n"
"syscall"
: "=a" (result)
: "a" (9),
"D" ((u64)base_addr),
"S" (size),
"d" ((u64)memory_protection),
"r" ((u64)mapping_visibility),
"r" ((u64)fd),
"r" (fd_offset)
: "r10", "r8", "r9", "r11", "rcx", "memory");
void *sys_result = (void *)((u64)result);
if ((u64)result >= (u64)(-MAX_ERRNO)) {
breakpoint();
sys_result = NULL;
}
return sys_result;
}
typedef struct {
void* base;
u64 size;
u64 used;
} X64MemArena;
static X64MemArena platform_mem_arena = {0};
static s32
x64_mem_arena_init(X64MemArena *mem_arena, u64 size)
{
mem_arena->base = x64_syscall_mmap(NULL, size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (mem_arena->base == NULL) {
breakpoint();
}
// I tried without this call, gives same result
if (x64_syscall_mlock(mem_arena->base, mem_arena->size) < 0) {
breakpoint();
}
mem_arena->used = 0;
mem_arena->size = size;
return 0;
}
// ...
// used here
if (x64_mem_arena_init(&platform_mem_arena, 1024 * 1024 * 200) == -1) {
breakpoint();
}
静态无效*
x64系统调用mmap(无效*基本地址、u64大小、u32内存保护、,
u32映射(可见性,s32 fd,u64 fd_偏移)
{
s64结果=0;
__asm\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
mov r8,%6\n
mov r9,%7\n
“系统调用”
:“=a”(结果)
:“a”(9),
“D”((u64)基本地址),
“S”(尺寸),
“d”((u64)内存保护),
“r”((u64)映射_可见性),
“r”((u64)fd),
“r”(fd_偏移量)
:“r10”、“r8”、“r9”、“r11”、“rcx”、“内存”);
无效*系统结果=(无效*)((u64)结果);
如果((u64)结果>=(u64)(-MAX\u ERRNO)){
断点();
sys_result=NULL;
}
返回系统结果;
}
类型定义结构{
空*基;
u64尺寸;
使用u64;
}X64MemArena;
静态X64MemArena平台_mem_arena={0};
静态s32
x64_mem_arena_init(X64MemArena*mem_arena,u64尺寸)
{
mem_arena->base=x64_syscall_mmap(NULL、size、PROT_READ、PROT_WRITE、,
MAP|u PRIVATE | MAP|u ANONYMOUS,-1,0);
if(mem_arena->base==NULL){
断点();
}
//我没有打这个电话就试过了,结果也一样
如果(x64系统调用锁(内存竞技场->基础,内存竞技场->大小)<0){
断点();
}
mem_arena->used=0;
mem_arena->size=size;
返回0;
}
// ...
//这里用
如果(x64内存竞技场初始化(&platform内存竞技场,1024*1024*200)=-1){
断点();
}
跑
qemu-system-x86_64-启用kvm-m512m-s-s-drive format=raw,file=ker.img-kernel/boot/vmlinuz-5.8.0-50-generic-追加“root=/dev/sda init=/sbin/x64 ker nokaslr”
当我在调试器中检查(u8*)platform\u mem\u arena.base
的内容时,我得到0xd6ad000
在qemu窗口中,我得到一行:
x86/mm:Checked W+X映射:passed,找不到W+X页面
。这可能与此有关吗
在我的Ubuntu主机上运行,效果很好。内存有效且已归零。所以,这似乎是qemu的一个问题。qemu下的Linux从
mmap
返回成功,我猜?这是一个总内存为512MB的VM中的200MB映射,但即使物理ram很紧,过度使用也会让它成功代码>强制“r”
拾取R10。此外,没有理由将参数强制转换为u64
。内核可以安全地忽略完整64位寄存器中任何可能的高垃圾,因为其C函数使用相同的原型。另外,9
可以是\uu NR\u mmap
而不是编写自己的包装。x86/mm:Checked W+X映射:已通过,未找到W+X页面。
听起来不错,只要检查是否有任何write+exec页面(如果有漏洞可以写入这些页面,则可能容易受到代码注入攻击)@彼得·科尔德有些不相关,但qemu的性情令人沮丧。我经常会遇到内核恐慌:不同步无法使用sbin/x64 ker
,这似乎是因为我运气不好,只是重新启动qemu
,直到它工作为止。我之所以提到这一点,是因为我觉得可能有一些不直接相关的东西在这里产生了影响。@penguin359你是对的,这是不正确的。但是,它不是致命的,因为结构已归零。我也删除了这个电话,但仍然收到同样的问题。