The man page is likely missing the word "no", as that makes a lot more sense than the current wording meaning positive action.
2010/2/11 Vadim Zhukov <persg...@gmail.com>: > 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