사용자 공간에서 재부팅이 발생합니다.

사용자 공간에서 재부팅이 발생합니다.

이 프로그램은 x86 Linux 시스템의 Gnu Assembler용으로 작성되었으며 삼중 오류가 발생하고 재부팅됩니다.

.text
.global _start
_start:
# write our string to stdout

    movl    $len,%edx   # third argument: message length
    movl    $msg,%ecx   # second argument: pointer to message to write
    movl    $1,%ebx     # first argument: file handle (stdout)
    movl    $4,%eax     # system call number (sys_write)
    int $0x80       # call kernel
# Triple Fault -- reboot
    movq    $1, %rsp    # Load the stack pointer with a one
    pushq    %rax       # Push the A register, should cause a triple fault.

# and exit

    movl    $0,%ebx     # first argument: exit code
    movl    $1,%eax     # system call number (sys_exit)
    int $0x80       # call kernel

.data                   # section declaration

msg:
    .ascii  "Will reboot by triple fault!\n"    # our dear string
    len = . - msg           # length of our dear string

대신 분할 오류가 발생합니다. 루트로 실행하면 사용자 모드에서 작동하게 할 수 있나요?

답변1

Linux 커널은 사용자 공간이 다른 사용자에게 영향을 미칠 수 있는 작업을 수행하는 것을 허용하지 않습니다. 루트로서 유사한 작업을 수행할 수 있지만 커널은 여전히 ​​그러한 직접적인 제어를 방지할 수 있습니다. 결국 루트 프로세스는 여전히 사용자 모드 프로세스이지만 커널의 시스템 호출에 무제한으로 액세스할 수 있습니다.

보다 정확한/UNIXy 접근 방식은 커널에서 이 작업을 수행하고 사용자 영역 프로세스가 이를 호출하는 데 사용할 수 있는 인터페이스를 노출하는 것입니다. 그러면 코드가 커널 컨텍스트 내에서 실행되고 사용자가 일반적으로 액세스할 수 없는 하드웨어/시스템 기능에 대한 전체 액세스 권한을 갖게 됩니다.

답변2

이러한 CPU 오류는 커널 모드 인터럽트 핸들러에 의해 처리됩니다. 커널 코드는 괜찮으며 사용자 공간 오류가 발생하는 경우(예: 0으로 나누기 또는 잘못된 메모리 액세스) 첫 번째 인터럽트 핸들러가 이를 올바르게 처리해야 합니다. 다른 모든 것은 커널의 버그입니다. 인터럽트 핸들러에 결함이 있는 경우 기본적으로 유일하게 합리적인 방법은 레지스터와 스택을 덤프한 다음 이를 디버거(OpenBSD가 수행하는 것과 같은) 또는 HCF에 넣는 것입니다. 패닉 뉴스를 기록하세요. 그 시점에서 코드가 더 이상 제대로 작동하지 않기 때문에 삼중 오류가 발생합니다.

요약: 이것이 작동하려면 Linux의 문제 해결 코드에서 버그를 찾아야 합니다.

의도적으로 인터럽트 핸들러를 중단시키는 커널 모듈에서 이 작업을 수행할 수 있지만 시스템이 충돌할 가능성도 있습니다. 효과가 다릅니다 shutdown -r now!

답변3

rebootLinux에서는 시스템 호출을 사용할 수 있습니다 .

#include <unistd.h>
#include <sys/reboot.h>

int main(void) {
    return reboot(LINUX_REBOOT_CMD_RESTART);
}

답변4

정말 어셈블러(?!)가 필요한 경우 루트에서 작동했습니다(내 생각에는 nasm을 사용함).

BITS    32
    mov eax, 88
    mov ebx, 0xfee1dead
    mov ecx, 85072278
    mov edx, 0x01234567
    int  0x80

관련 정보