[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Unprivileged double fault with GDB and simple program written in ass
From: |
Luca |
Subject: |
Re: Unprivileged double fault with GDB and simple program written in assembly |
Date: |
Sat, 31 Aug 2024 09:42:59 +0200 |
Hi,
Il 28/08/24 15:01, J. E. Marinheiro ha scritto:
At this point, a double fault evidently happens, Mach starts panicking, and the
registers are dumped:
* RAX=4010DE
* RBX=0
* RCX=1
* RDX=0
* RSI=0
* RDI=0
* RBP=0
* RSP=0
* R8 to R12=0
* EFLAGS=4000CE
The error message is:
`trapno 0: Divide error, error 01402ff8'
`panic ../i386/i386/trap.c:677: handle_double_fault: DOUBLE FAULT! This is
critical'
I can reproduce the issues, both with and without gdb; in particular, I
see that there is a bug in decoding the registers after a double fault;
Fixing that I see
RAX 000000000000003c RBX 0000000000000000
RCX 00000000004000de RDX 0000000000000000
RSI 00000000004010de RDI 0000000000000000
RBP 0000000000400000 RSP 0000000000000000
R8 0000000000001403 R9 0000000000000000
R10 0000000000000000 R11 0000000000000000
R12 0000000000000000 R13 0000000000000000
R14 0000000000000000 R15 0000000000000000
RIP ffffffff81012164 EFLAGS 00010102
where RIP seems to point the the syscall64 entry. It's also weird to
have RSP=0 but that might be due to the bad state of the program being
debugged.
GDB correctly prints errors related to signals, as there is no signal
thread to handle them:
Thread 4 received signal ?, Unknown signal.
_start () at program.S:11
11 mov $60, %rax
warning: Signal ? does not exist on this system.
warning: Can't deliver signal ?: No signal thread.
The signal seems caused by an invalid opcode exception after the second
syscall, sent by the kernel and handled by GDB. From a kernel trace I
collected it seems that the exception is sent twice, and it seems that
somewhere after the second exception, when the program is resumed, the
double fault happens. There might be an issue with restarting twice a
task with an invalid state, if exceptions can be delivered; without GDB,
the kernel terminates the task at the first error, as there is no
exception port set.
When not using GDB, the program is simply killed by the system and nothing bad
seems to happen. I'm guessing Linux syscalls need not be the same as Mach
syscalls, but a double fault from some faulty program shouldn't trigger a panic
without even root privileges.
The kernel has no idea about unix users, AFAIK in userspace the
difference is basically the access to some privileged mach ports, but
this is implemented in glibc and the hurd servers.
Luca