Hello all. mprotect(2) says: "If len is 0, then action will be taken on the page that contains addr". The reality says it's not so:
$ cat ~/cvs/mprotect_test.c #include <sys/types.h> #include <sys/param.h> #include <sys/mman.h> #include <stdio.h> #include <unistd.h> void mymemset(char *p, int c, size_t len) { size_t i; char cc; cc = (char)(c & 0xFF); for (i = 0; i < len; i++) { fputc('.', stderr); p[i] = cc; } } int main(int argc, char **argv) { long pgsz; char *p; pgsz = sysconf(_SC_PAGESIZE); if ((p = (char*)mmap(NULL, pgsz * 3, PROT_NONE, MAP_ANON, -1, 0)) == NULL) err(1, "mmap"); if (mprotect(p + pgsz, 0, PROT_READ|PROT_WRITE) == -1) err(1, mprotect); fputs("writing to page 1: ", stderr); mymemset(p + pgsz, 0xCC, pgsz); fputs("OK\nwriting to page 0: ", stderr); mymemset(p, 0xCC, pgsz); fputs("OK (WTF?!)\nwriting to page 2: ", stderr); mymemset(p + (pgsz * 2), 0xCC, pgsz); fputs("OK (WTF?!)\n", stderr); return 1; } $ cc -O0 -ggdb -o mprotect_test mprotect_test.c $ ./mprotect_test writing to page 1: .Segmentation fault (core dumped) $ I checked the SUS, and it is not clear: "The mprotect() function shall change the access protections to be that specified by prot for those whole pages containing any part of the address space of the process starting at address addr and continuing for len bytes." So either sys_mprotect(), uvm_map_protect() or man page is not correct. As I'm totally newbie in UVM, please, do not bite me for the patch proposed below. At least, very much. :) -- Best wishes, Vadim Zhukov A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing in e-mail? @@ -778,6 +778,8 @@ sys_mprotect(struct proc *p, void *v, re if ((prot & VM_PROT_ALL) != prot) return (EINVAL); + if (size == 0) + size = PAGE_SIZE; /* * align the address to a page boundary, and adjust the size accordingly