1

I need to test if memory address is readable, so I searched and found this question: How to test if an address is readable in linux userspace app As user @caf stated:

The canonical way is to use the write() system call to read from the page (writing to a dummy pipe() file descriptor).

Unfortunatelly he didn't provide any code example, and I can't comment (low reputation) nor send him a message (at least I don't know how).

EDIT

Can't I just omit creating the pipe by doing something like that?

int result = write(0, addr, 1);

@Mats Petersson: I'm trying to analyze and change a function after already loading it to memory using function pointer (I'm incrementing the pointer and copying its value byte by byte), so to determine whether it's still this function i need to know if the memory is writeable and readable (it's a little stupid thing to do, I know). Anyhow I'd like to not change my program's memory reading/writing privileges, so what you've said might be a problem.

EDIT 2 @Damon: so is there any other sure way to do this?

Community
  • 1
  • 1
Jezor
  • 31
  • 4
  • Note that this method suffers from the usual "toctou" (time of check to time of use) problem - you check that address X is valid, it is valid, the OS decides to reclaim that part of memory as a consequence of some operation [such as closing the pipe, but hundreds of other possible scenarios exists, especially in a multicore/multithreaded system] and the memory is no longer valid. Maybe if you describe the problem you are ACTUALLY trying to solve (as in "why do you think you need to know if memory is valid"), and we can come up with a better solution? – Mats Petersson Jan 07 '15 at 09:10
  • Also note that this will likely cause a page fault (presumed that the address is a valid page), which is not only slow, but also possibly purges another page from your working set. – Damon Jan 07 '15 at 11:00
  • Re edit: Well yes, there is a safe and efficient way. Do only ever read from or write to addresses which you have properly allocated (e.g. using `mmap` or `malloc`). In particular, do not write to addresses in the `text` segment (which will likely not work anyway due to DEP -- regardless of whether it's a valid address) or make assumptions about where a function in a compiled binary ends (it may very well have 2 or 3 end points and it may very well not fill a complete page). – Damon Jan 07 '15 at 12:10

2 Answers2

6

First, create a pipe pair to write the data to:

 int fd[2];
 pipe(fd);

Then try to write some data from your address to the write side of the pipe:

 int result = write(fd[1], addr, 1);

If result is 1, the write succeeded, so the address was readable. If it's zero and errno == EFAULT, the address is not readable. If errno is something else, something else went wrong.

Make sure to close the pipes once you're done, of course:

 close(fd[0]);
 close(fd[1]);
2

I've never used that method myself, but I think that yo have to create a pipe (using the pipe system call), when write to that pipe providing the address you want to check as the buffer.

So lets say you want to check address 0x1000000, then you do e.g.

int res = write(dummypipe[1], 0x1000000, 1);

If res is -1 then you check if errno == EFAULT which indicates that the address is not valid.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621