简体   繁体   English

使用非规范地址检索 memory 数据会导致 SIGSEGV 而不是 SIGBUS

[英]Retrieving memory data with non-canonical-address causes SIGSEGV rather than SIGBUS

I can not produce a "Bus error" with the following assembly code.我无法使用以下汇编代码生成“总线错误”。 Here the memory address I use is not a legal "canonical-address".这里我使用的 memory 地址不是合法的“规范地址”。 So, how can I trigger that error?那么,如何触发该错误?

I was running this snippet of code under Ubuntu 20.04 LTS with NASM 2.14.02, but it results in a SIGSEGV segmentation fault on the load, not SIGBUS.我在 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

Corresponding X86-64 assembly code after compiling:编译后对应的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

If you review the Instruction Set Architecture manual for the MOV instruction you would find that accessing a non-canonical address yields a #GP(0) General Protection Fault:如果您查看MOV指令的指令集架构手册,您会发现访问非规范地址会产生#GP(0)一般保护错误:

在此处输入图像描述

Linux maps all #GP exceptions to SIGSEGV signal (Segmentation Fault). Linux 将所有#GP异常映射到 SIGSEGV 信号(分段错误)。 However, in Linux there is a way for a non-canonical address to cause a Bus Error and that is by getting the processor to raise an #SS (Stack Segment) exception.但是,在 Linux 中,有一种方法可以让非规范地址导致总线错误,即让处理器引发#SS (堆栈段)异常。 Linux maps #SS exceptions to the SIGBUS signal. Linux 将#SS异常映射到 SIGBUS 信号。 Setting the stack pointer to a non-canonical address and then performing a stack related operation will produce such an exception.将堆栈指针设置为非规范地址,然后执行堆栈相关操作将产生这样的异常。

This code should produce a Bus Error :此代码应产生总线错误

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

One other way of producing a Bus Error on Linux is to raise an #AC (Alignment Check) exception.在 Linux 上产生总线错误的另一种方法是引发#AC (对齐检查)异常。 If you write ring 3 (user) code that enables the Alignment Check bit (bit 18) in RFLAGS and do an unaligned memory access you should also receive a SIGBUS signal.如果您在 RFLAGS 中编写启用 Alignment 检查位(位 18)的环 3(用户)代码并执行未对齐的memory访问,您还应该收到 SIGBUS 信号。 This code should produce a Bus Error :此代码应产生总线错误

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM