What is a bus error?
Bus errors are rare nowadays on x86 and occur when your processor cannot even attempt the memory access requested, typically:
- using a processor instruction with an address that does not satisfy its alignment requirements.
Segmentation faults occur when accessing memory which does not belong to your process, they are very common and are typically the result of:
- using a pointer to something that was deallocated.
- using an uninitialized hence bogus pointer.
- using a null pointer.
- overflowing a buffer.
PS: To be more precise this is not manipulating the pointer itself that will cause issues, it's accessing the memory it points to (dereferencing).
A segfault is accessing memory that you're not allowed to access. It's read-only, you don't have permission, etc...
A bus error is trying to access memory that can't possibly be there. You've used an address that's meaningless to the system, or the wrong kind of address for that operation.
mmap
minimal POSIX 7 example
"Bus error" happens when the kernel sends SIGBUS
to a process.
A minimal example that produces it because ftruncate
was forgotten:
#include <fcntl.h> /* O_ constants */
#include <unistd.h> /* ftruncate */
#include <sys/mman.h> /* mmap */
int main() {
int fd;
int *map;
int size = sizeof(int);
char *name = "/a";
shm_unlink(name);
fd = shm_open(name, O_RDWR | O_CREAT, (mode_t)0600);
/* THIS is the cause of the problem. */
/*ftruncate(fd, size);*/
map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
/* This is what generates the SIGBUS. */
*map = 0;
}
Run with:
gcc -std=c99 main.c -lrt
./a.out
Tested in Ubuntu 14.04.
POSIX describes SIGBUS
as:
Access to an undefined portion of a memory object.
The mmap spec says that:
References within the address range starting at pa and continuing for len bytes to whole pages following the end of an object shall result in delivery of a SIGBUS signal.
And shm_open
says that it generates objects of size 0:
The shared memory object has a size of zero.
So at *map = 0
we are touching past the end of the allocated object.
Unaligned stack memory accesses in ARMv8 aarch64
This was mentioned at: What is a bus error? for SPARC, but here I will provide a more reproducible example.
All you need is a freestanding aarch64 program:
.global _start
_start:
asm_main_after_prologue:
/* misalign the stack out of 16-bit boundary */
add sp, sp, #-4
/* access the stack */
ldr w0, [sp]
/* exit syscall in case SIGBUS does not happen */
mov x0, 0
mov x8, 93
svc 0
That program then raises SIGBUS on Ubuntu 18.04 aarch64, Linux kernel 4.15.0 in a ThunderX2 server machine.
Unfortunately, I can't reproduce it on QEMU v4.0.0 user mode, I'm not sure why.
The fault appears to be optional and controlled by the SCTLR_ELx.SA
and SCTLR_EL1.SA0
fields, I have summarized the related docs a bit further here.