2
votes

Using only (32 bits) x86 assembly, is it possible to check if an address is writable, without interacting with the operating system, and without risking a segfault?

The program will run on a Linux system in ring 3. I cannot use the "verw" instruction.

To give an example, I might want to check if the address 0x0804a000 is writable. But if I e.g. do "mov eax, 0x0804a000; mov [eax], eax" then, if the address is not writable, the program will segfault. The only other way I know is to e.g. call sys_read into the address and see if it fails, but this interacts with the operating system.

Is there a way to check if an address is writable given the constraints? If so, how?

1
You can of course handle the segfault. Is there any problem with that? - Jester
@Jester Handling it would require a syscall which is a problem. - Chris
You can look in /proc/self/maps and see which range, if any, the address falls into. Of course reading that file is also a syscall... Also, the address might not be accessible at the moment (paged out), but the OS could change that during the page fault handler obviously. You will never know this from user space. - Jester
@Jester Let's say I can ignore the segfault but not handle it with a custom function. Could this help? I imagine not because the bad instruction will just get re-executed on a segfault, yielding more segfaults. Am I missing something? - Chris
You are correct, the handler would have to change something to avoid the fault, for example change register value to a known good address (assuming the instruction is an indirect access). - Jester

1 Answers

1
votes

If you have kernel privileges you could probably find that info in the MMU.

But if you don't, you simply do not have access to it and must use OS facilities.

If you mean not calling an OS function, then it is possible at least on Windows by using Structured Exception Handling. It is still OS specific of course, because you need to access the Windows TIB at the FS segment.