Linux:简单C程序缓冲区溢出触发SIGBUS问题咨询
Hey there, let's break down why you're hitting a SIGBUS signal instead of the more common SIGSEGV when triggering your buffer overflow, and walk through solutions tailored to your training scenario.
First, a quick refresher on the two signals to set context:
SIGSEGV(Segmentation Fault) happens when you try to access a virtual memory address that doesn't exist, or you don't have permission to access it.SIGBUS(Bus Error) occurs when you access a virtual memory address that's valid (exists in the address space) but can't be physically accessed—most often due to memory alignment issues or accessing a page that's mapped but not loaded into physical memory.
Common Causes for SIGBUS in Your Buffer Overflow
Let's tie this directly to your test program:
Misaligned Return Address
Most CPU architectures (like x86_64, ARM, MIPS) require instruction pointers (RIP/EIP) to point to aligned addresses (8-byte for x86_64, 4-byte for 32-bit x86). If your overflow payload sets the return address to an unaligned value (e.g.,0xdeadbeef1instead of0xdeadbeef0on x86_64), the CPU will refuse to execute instructions from that address and throw aSIGBUS.Crossing Stack Page Boundaries
Yourbuffer[64]lives on the stack, which is divided into fixed-size pages (usually 4KB). If your overflow exactly reaches the edge of a stack page and you try to access memory just beyond it, that adjacent page might be marked as "reserved but not mapped to physical memory"—leading to aSIGBUSinstead ofSIGSEGV(which would trigger if the page didn't exist at all).Unintended Compilation Protections
If you didn't disable stack protections when compiling, features like stack canaries or page-based stack guards might alter how memory is accessed during overflow. While these usually triggerSIGSEGV, in edge cases they can lead toSIGBUSif they block access to a valid but protected page.
Fixes to Try
Here's how to resolve each issue for your training:
Ensure Address Alignment
Double-check the return address you're overwriting with. For 32-bit programs, make sure it's a multiple of 4; for 64-bit, a multiple of 8. For example, if you're targeting a gadget at0x401235, round it down to0x401234(if that's still a valid instruction) or adjust your payload to hit an aligned address.Tweak Payload Length
If you suspect you're hitting a page boundary, adjust the length of your input. For example, if you're sending 72 bytes to overflow the 64-byte buffer + 8-byte RIP, try sending 71 or 73 bytes to shift where the return address lands—ensuring it's fully within a mapped stack page.Compile with Training-Friendly Flags
Since you're doing beginner training, disable all memory protections to eliminate environmental variables. Compile your program with:
gcc -fno-stack-protector -z execstack -no-pie -o temp_cleaner temp_cleaner.c
-fno-stack-protector: Disables stack canaries-z execstack: Makes the stack executable (so your shellcode runs if you inject it)-no-pie: Disables position-independent execution, making addresses predictableDebug with GDB to Confirm
Fire up GDB and run your program withgdb ./temp_cleaner. When it hitsSIGBUS, use:info registersto check the value of RIP/EIP—verify if it's alignedinfo proc mappingsto check if the address in RIP/EIP is within a mapped memory regionx/10x <rip-value>to see if the memory at that address is accessible
Quick Note on Your Code
I noticed your system call line is cut off (system("/bin/rm -rf /tmp/*...)—make sure to finish that statement to avoid compilation errors, though it won't affect your overflow issue.
内容的提问来源于stack exchange,提问作者Nim

