I'm working on a memory tracking library where we use mprotect
to remove access to most of a program's memory and a SIGSEGV handler to restore access to individual pages as the program touches them. This works great most of the time.
My problem is that when the program invokes a system call (say read
) with memory that my library has marked no access, the system call just returns -1 and sets errno
to EFAULT
. This changes behavior of the programs being tested in strange ways. I would like to be able to restore access to each page of memory given to a system call before it actually goes to the kernel.
My current approach is to create a wrapper for each system call that touches memory. Each wrapper would touch all the memory given to it before handing it off to the real system call. It seems like this will work for calls made directly from the program, but not for those made by libc (for instance, fread
will call read
directly without using my wrapper). Is there any better approach? How is it possible to get this behavior?