Files
ViperOS/vpsdk/stdlib.vp
T
TermiNexus 7b58758603 fix(vpsdk): 修正 malloc 块头越界写(ptr-hdr_size → ptr),修复全部 app 启动即 #PF
块头原写在 mmap 映射区起点之前 8 字节;第一次 malloc 时 mmap 返回用户堆起点 0x20000000,写 0x1ffffff8 落在映射区外 ⇒ #PF(err=0x7 用户态写、cr2=0x1ffffff8),四个 app 启动瞬间全部崩在同一个 stdlib.malloc 上。改为把块头写在映射区起始处 ptr,返回 ptr+hdr_size 不变,free/calloc/realloc 的 ptr-hdr_size 反查仍然正确。
2026-10-16 16:29:04 +08:00

60 lines
1.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import vpsdk.syscall as _sc
import string
define HEAP_BLOCK_MAGIC = 0x48454150
class _heap_hdr:
magic: uint32
size: uint32
_heap_inited: int = 0
def _heap_init():
global _heap_inited
_heap_inited = 1
export def malloc(size: sizet) -> rawptr:
global _heap_inited
if size == 0: return None
if _heap_inited == 0: _heap_init()
hdr_size: sizet = _heap_hdr.__sizeof__()
total: sizet = hdr_size + size
ptr: uint64 = _sc._syscall1(uint64(_sc.SYSCALL_MMAP), uint64(total))
if ptr == 0: return None
# 块头必须落在**映射区内部**(映射起点 ptr 处),不能写 ptr - hdr_size:
# 那 8 字节在映射之外 —— 第一次 malloc 时 mmap 返回的正是用户堆起点 0x20000000,
# 写 0x1ffffff8 就是映射区外 ⇒ #PF(err=0x7 用户态写),四个 app 启动即崩的现场。
hdr: _heap_hdr* = _heap_hdr*(uint64(ptr))
hdr.magic = HEAP_BLOCK_MAGIC
hdr.size = uint32(size)
return rawptr(ptr + hdr_size)
export def free(ptr: rawptr):
if ptr is None: return
hdr_size: sizet = _heap_hdr.__sizeof__()
hdr: _heap_hdr* = _heap_hdr*(uint64(ptr) - hdr_size)
if hdr.magic != HEAP_BLOCK_MAGIC: return
export def calloc(nmemb: sizet, size: sizet) -> rawptr:
total: sizet = nmemb * size
p: rawptr = malloc(total)
if p: string.memset(p, 0, total)
return p
export def realloc(ptr: rawptr, size: sizet) -> rawptr:
if ptr is None: return malloc(size)
if size == 0:
free(ptr)
return None
hdr_size: sizet = _heap_hdr.__sizeof__()
hdr: _heap_hdr* = _heap_hdr*(uint64(ptr) - hdr_size)
if hdr.magic != HEAP_BLOCK_MAGIC: return None
old_size: sizet = hdr.size
new_ptr: rawptr = malloc(size)
if new_ptr is None: return None
copy_size: sizet = old_size if old_size < size else size
string.memcpy(new_ptr, ptr, copy_size)
free(ptr)
return new_ptr