Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SegFaults in my Assembler? But that's impossible! :O

Okay, so I understand all of us C/C++ programmers have at one time met our untimely nemesis, the diabolical signal SIGSEGV, the Segmentation Fault. Now, I understood (emphasis on the past tense) this to be some form of fail safe / checking system within some portion of the machine code spat out by the magical GCC (or g++) compiler, or what have you.

But! Today I was screwing around with some x86 assembler with good old NASM on a virtualized Arch Linux system, and much to my surprise and chagrin, was once again thwarted in my coding efforts by the nefarious SegFault.

Here is the code that spawned the dreaded signal:

mov eax, 0x7
mov [0xB8000], eax

Now, I understand that the Linux kernel loads your assembled program into a shell and executes it from there, but I thought this MOV instruction interacted 1 to 1 with the processor, how on Earth can the Kernel detect that I'm trying to access a bit of memory it doesn't want me to, and halt the instruction?

I don't pretend to understand what exactly happens when your program is loaded into a shell, what permissions you have once in the shell, or even what a shell is or how it works, but I used to be dang sure that ASM gave you full control over the processor. How does this magical Kernel interfere with my direct commands to the processor, and why am I still forced to go through this chain of Operating System command when writing, essentially, pure machine code? :O

like image 257
N8-bit Avatar asked Jan 22 '23 16:01

N8-bit


1 Answers

Linux executes your program is running in user-mode (ring 3 on x86). Additionally, it's using page-based memory protection to limit the memory locations your program can access. In particular, your program attempts to write to 0xB8000 (the VGA framebuffer), which it does not have permission to modify. The processor's MMU detects this, and it throws a CPU exception. The Linux kernel handles this exception, and translates it to a segment violation signal. Assuming you haven't set up a custom handler for your signal, the kernel then kills your process. To avoid this and get full access to your hardware, you'll either need to write a Linux device driver which will run in kernel mode (ring 0 on x86) with full permissions, or bypass Linux entirely by writing your own operating system.

like image 185
bcat Avatar answered Jan 28 '23 05:01

bcat