fix(desk): 清空共享区槽表并按版本拒绝旧 app
现场:所有窗口消失、任务栏多出若干图标,点击后 explorer 以 [0E] rip=0x4061e8 cr2=0x1207e8fff 缺页退出。 原因:desk_format 只清 DeskHeader,没有清 0x100 起的 WinSlot 表。 DESK_SHM_SIZE 从 8MB 提到 32MB 后,mm.malloc 拿到的内存不再恰好全零 (混入 bootloader/固件遗留数据),随机 used/active 被当成窗口, 合成时按垃圾 fb_off 越界读像素。 - desk_format 先 memset 整个控制区(0x000000 ~ 0x200000) - 分配槽位时整槽清零,避免复用残留 - DESK_VERSION 1 → 2,desk_ready 校验版本: 旧 app 按旧 WinSlot 偏移读写会写坏共享区,现在直接拒绝挂载 - render_window_rows 校验 fb_off 范围,坏槽位只跳过,不再拖崩合成器
This commit is contained in:
1 parent
8e94458fc2
commit
6ecd891f64
2 files changed
+14
-1
No files matched your search
@@ -459,6 +459,8 @@ class DeskServer:
|
||||
for i in range(desk.DESK_MAX_WIN):
|
||||
s: desk.WinSlot* = self.slot(i)
|
||||
if s.used == 0:
|
||||
# 槽位复用前整块清零:避免上一任窗口的 pid/几何/缓冲区偏移残留。
|
||||
string.memset(s, 0, desk.desk_slot_size())
|
||||
cap_px: int = w * content_h
|
||||
buf_off: uint32 = desk.desk_arena_alloc(self.shm, uint32(cap_px) * uint32(4))
|
||||
if buf_off == uint32(0): return -1
|
||||
@@ -1202,6 +1204,10 @@ class DeskServer:
|
||||
buf: uint32* = uint32*(self.shm + uint64(s.fb_off))
|
||||
fw: int = int(s.fb_w)
|
||||
fh: int = int(s.fb_h)
|
||||
# 槽表被写坏时宁可跳过该窗口,也不要按越界 fb_off 读像素把整个合成器带崩。
|
||||
need_bytes: uint64 = uint64(fw) * uint64(fh) * uint64(4)
|
||||
if s.fb_off < uint32(desk.DESK_OFF_ARENA) or uint64(s.fb_off) + need_bytes > uint64(desk.DESK_SHM_SIZE):
|
||||
return
|
||||
content_y0: int = wy + th + TITLE_GAP
|
||||
r: int = WIN_RADIUS
|
||||
yy: int = y0
|
||||
|
||||
+8
-1
@@ -29,7 +29,7 @@ from stdint import *
|
||||
# 32MB:1920×1080 全屏窗口的内容缓冲约 7.3MB,最大化需要足够 arena。
|
||||
define DESK_SHM_SIZE = 33554432
|
||||
define DESK_MAGIC = 0x4B534544 # 'DESK'
|
||||
define DESK_VERSION = 1
|
||||
define DESK_VERSION = 2 # WinSlot 布局变更必须 +1,旧 app 拒绝挂载
|
||||
|
||||
define DESK_MAX_WIN = 8
|
||||
define DESK_TITLE_MAX = 32
|
||||
@@ -213,6 +213,9 @@ def desk_map(fd: int) -> uint64:
|
||||
|
||||
def desk_format(base: uint64, fb_w: uint32, fb_h: uint32, fb_pitch: uint32):
|
||||
"""explorer 专用:初始化共享区头与各环。"""
|
||||
# 先清空整个控制区(头 + 窗口槽表 + 各环):共享区来自 mm.malloc,不能假设为 0。
|
||||
# 否则槽表里的随机 used/active 会被当成"多出来的窗口",合成器还会按垃圾 fb_off 取像素。
|
||||
string.memset(rawptr(base), 0, uint64(DESK_OFF_ARENA))
|
||||
h: DeskHeader* = DeskHeader*(base + desk_header_off())
|
||||
string.memset(h, 0, DeskHeader.__sizeof__())
|
||||
h.magic = uint32(DESK_MAGIC)
|
||||
@@ -236,6 +239,10 @@ def desk_ready(base: uint64) -> int:
|
||||
h: DeskHeader* = DeskHeader*(base + desk_header_off())
|
||||
if h.magic != uint32(DESK_MAGIC):
|
||||
return 0
|
||||
# 共享结构布局变了(WinSlot 增字段)就拒绝挂载:旧 app 按错偏移读写会把
|
||||
# 头部/槽表/别人的像素缓冲写坏,比"连不上"危险得多。
|
||||
if h.version != uint32(DESK_VERSION):
|
||||
return 0
|
||||
return h.ready
|
||||
|
||||
def desk_arena_alloc(base: uint64, size: uint32) -> uint32:
|
||||
|
||||
Reference in new issue
Block a user