Syntactic Fructose Syntactic Fructose - 24 days ago 12
C Question

write() on protected memory region does not trigger sigsegv, but standard access does

I'm trying to understand why calling a write on a memory protected region does not trigger a

sigsegv
. Consider the example:

void *map_addr;
unsigned long addr;

map_addr = (void *)mmap(NULL, 0x4000, PROT_READ_WRITE, MAP_PRIVATE, fd, 0);
mprotect(map_addr, 0x4000, PROT_NONE);

addr = (unsigned long)map_addr;

// case 1:
*(volatile int*)(addr); // sigsegv sent
// case 2:
write(STDOUT_FILENO, map_addr, size); // sigsegv NOT sent


Instead of sending a
sigsegv
, write in this instance returns
-1
and sets
errno=EFAULT
. Why does write have this behavior? I would imagine write would have attempted reading from the address, which creates the sigsegv fault but this is evidently not the case.

Answer

write is a system call, so the memory access happens in the kernel, not in your process. The kernel first checks whether the passed address is valid for the calling process, and if it isn't, it simply returns EFAULT.

(I don't know why it was designed to work this way, though.)

Comments