[英]Retrieving memory data with non-canonical-address causes SIGSEGV rather than SIGBUS
我無法使用以下匯編代碼生成“總線錯誤”。 這里我使用的 memory 地址不是合法的“規范地址”。 那么,如何觸發該錯誤?
我在 Ubuntu 20.04 LTS 和 NASM 2.14.02 下運行這段代碼,但它導致負載出現 SIGSEGV 分段錯誤,而不是 SIGBUS。
global _start
section .text
_start:
mov rax, [qword 0x11223344557788]
mov rax, 60
xor rdi, rdi
syscall
編譯后對應的X86-64匯編代碼:
Disassembly of section .text:
0000000000401000 <_start>:
401000: 48 a1 88 77 55 44 33 movabs 0x11223344557788,%rax
401007: 22 11 00
40100a: b8 3c 00 00 00 mov $0x3c,%eax
40100f: 48 31 ff xor %rdi,%rdi
401012: 0f 05 syscall
如果您查看MOV指令的指令集架構手冊,您會發現訪問非規范地址會產生#GP(0)
一般保護錯誤:
Linux 將所有#GP
異常映射到 SIGSEGV 信號(分段錯誤)。 但是,在 Linux 中,有一種方法可以讓非規范地址導致總線錯誤,即讓處理器引發#SS
(堆棧段)異常。 Linux 將#SS
異常映射到 SIGBUS 信號。 將堆棧指針設置為非規范地址,然后執行堆棧相關操作將產生這樣的異常。
此代碼應產生總線錯誤:
global _start
section .text
_start:
mov rsp, 0x8000000000000000 ; Set RSP to a non-canonical address
push rax ; Pushing value on stack should produce BUS ERROR
在 Linux 上產生總線錯誤的另一種方法是引發#AC
(對齊檢查)異常。 如果您在 RFLAGS 中編寫啟用 Alignment 檢查位(位 18)的環 3(用戶)代碼並執行未對齊的memory訪問,您還應該收到 SIGBUS 信號。 此代碼應產生總線錯誤:
global _start
section .text
_start:
pushf ; Put current RFLAGS on the stack
or dword [rsp], 1<<18 ; Enable bit 18 (Alignment Check) of the
; RFLAGS value saved on stack
popf ; Pop new RFLAGS flags value into the RFLAGS register
mov eax, [rsp + 1] ; Move a DWORD value from unaligned address
; Should produce a BUS ERROR
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.