80958

How can I identify an invalid memory address?

Question:

I was wondering if there some way to identify an invalid memory address on a particular platform (x86 64-bit, for my case). I need it to catch a program much before it dereferences the address and throws a SIGILL/SIGSEGV error.

Answer1:

In general, you can't. An invalid address looks much the same as a valid one. The only invalid address that is recognizable is NULL.

So be sure (write your code thus) that your pointers are either valid or NULL before you use them. <strong><em>Always</em></strong>. There is no way around that.

You can use tools to detect places where your pointers may be invalid (e.g. uninitialized, already freed, etc.), but that is not what you were asking.

Answer2:

You can see all the memory mappings of the current process in file /proc/self/maps. Just open that file and process its content: every line starts with two hexadecimal numbers separated by -, which are the addresses that can be accessed by the process.

All the memory addresses which are mapped by your process are there, but some of them may not have read, write or execute permissions; if you need to check for them, you will also have to read and parse the next field.

Sample contents of that file:

$ cat /proc/self/maps 00400000-0040c000 r-xp 00000000 08:01 24340229 /bin/cat 0060b000-0060c000 r--p 0000b000 08:01 24340229 /bin/cat 0060c000-0060d000 rw-p 0000c000 08:01 24340229 /bin/cat 0253e000-0255f000 rw-p 00000000 00:00 0 [heap] [...] 7f050d97e000-7f050d97f000 rw-p 00000000 00:00 0 7fff9509e000-7fff950bf000 rw-p 00000000 00:00 0 [stack] 7fff951fe000-7fff95200000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]

Answer3:

If specifically preventing SIGSEGV is your goal, remember that you can catch segfaults with signal. You don't need to wait to do this at the point of use (where it's presumably too late) - you could temporarily redefine the SIGSEGV handler, run all of the addresses you want to check through a simple identity routine (read the target value, write it back), and then - if your handler never detected any errors - restore the original handler and move on to your section of code that needs to know that all addresses it receives are safe ("safe") to dereference. If not, you can raise or return an error of your own to the caller.

However, you can't generally tell whether an address is truly valid or not, because the underlying system will probably have allocated some stuff around the actual objects you requested with malloc, and accessing into these areas will likely not cause the program to crash - as far as the act of reading memory is concerned these addresses are effectively "valid" too, even though they don't represent a C object. But if all you need to do is e.g. verify that reading an externally-supplied buffer won't make your code crash, that's not your obstacle to overcome.

Answer4:

You can use the mincore function. See description <a href="http://linux.die.net/man/2/mincore" rel="nofollow">here</a>.

If the address is not mapped to the process virtual address space, mincore will return an error.

This isn't 100% as memory can be mapped to the process virtual address space but not committed (no physical pages allocated). It will catch the bulk of your garbage pointers if not all.

You can read more on memory mapping with the mmap function in <a href="http://linux.die.net/man/2/mmap" rel="nofollow">here</a>

Recommend

  • How to upload files in php using html
  • WP7 difficulties binding data to listbox itemssource - won't refresh
  • Granting permissions to Azure Active Directory Web Application automatically
  • How to enable mapping the private property of the entity
  • What is corresponding c++ data type to SQL numeric(18,0) data type?
  • Ruby 1.8.6 Array#uniq not removing duplicate hashes
  • Configure Spring's MappingJacksonHttpMessageConverter
  • Do query loads all the data in memory
  • AppleScript : find open tab in safari by name and open it
  • Reading a file into a multidimensional array
  • Security issues with PHP's Readfile method
  • Android application: how to use the camera and grab the image bytes?
  • why xml file does not aligned properly after append the string in beginning and end of the file usin
  • onBackPressed() not being executed
  • chrome.tabs.executeScript only fires when the Developer Console is open
  • How to clear text inside text field when radio button is select
  • How to avoid particles glitching together in an elastic particle collision simulator?
  • Python CGI os.system causing malformed header
  • Handling un-mapped Rest path
  • Scrapy recursive link crawler
  • Recording logins for password protected directories
  • Is there a javascript serializer for JSON.Net?
  • Java Scanner input dilemma. Automatically inputs without allowing user to type
  • Retrieving value from sql ExecuteScalar()
  • Master page gives error
  • Splitting given String into two variables - php
  • Check if a string to interpolate provides expected placeholders
  • Jquery - Jquery Wysiwyg return html as a string
  • Delete MySQLi record without showing the id in the URL
  • Confusion with PayPal's monthly billing cycle
  • InvalidAuthenticityToken between subdomains when logging in with Rails app
  • SQL merge duplicate rows and join values that are different
  • KeystoneJS: Relationships in Admin UI not updating
  • Hits per day in Google Big Query
  • LevelDB C iterator
  • Can't mass-assign protected attributes when import data from csv file
  • sending mail using smtp is too slow
  • Checking variable from a different class in C#
  • Easiest way to encapsulate a HTML5 webpage into an android app?
  • Programmatically clearing map cache