-6

Can I set/disable read(or write)-access privilage of the last several elements of an ordinary array in C/C++ ? Since I cannot use other processes' memory, I suspect this could be possible but how? I googled but couldnt find.

If I can, how?

Because I want to try something like this:

SetPrivilage(arr,LAST_5_ELEMENTS,false);

try
{
    for(int i=0;;i++) //without bound checking. i know its evil. just trying if it is possible
    {
        arr[i]++;     //array is 1-billion elements
    } 
}
catch(int catch_end_of_array)
{
    printf("array-inc complete");
}

Memory:

|start of array |00|01|02|03|04|05|06|07|..|..|1B|start of protected page|xx|xx|xx|xx|xx|xx|xx|xx|xx|xx|xx|xx|xx|

Lets assume I learned how to protect a page, then how could i declare an array just near the page so arrays end-point will be next to the page. ?

huseyin tugrul buyukisik
  • 11,469
  • 4
  • 45
  • 97
  • The segfault caused by accessing memory not allocated to your process cannot be used to set read/write access. If you need read/write access, create your own array class, and implement it in code. – ronalchn Sep 04 '12 at 10:05
  • 2
    Why exactly are you asking? What is your overall goal? There are probably other ways to achieve that goal... – Basile Starynkevitch Sep 04 '12 at 10:29
  • I am trying to use turn segfault into advantage – huseyin tugrul buyukisik Sep 04 '12 at 10:32
  • 2
    Common wisdom and some research papers tell that it does not work well in practice (and is non-portable and tricky). GNU/Hurd has external pagers. But taking advantage of SIGSEGV is not a "overall goal", tell us more about your bigger picture.... – Basile Starynkevitch Sep 04 '12 at 10:40

3 Answers3

3

This can not be done in a portable manner and depends on your operating system. I suspect that it's not really possible anywhere since memory protection normally operates on a much coarser level (e.g. Linux has the mprotect syscall, but that can only protect entire pages (usually 4k blocks), not arbitrary ranges.

themel
  • 8,825
  • 2
  • 32
  • 31
2

If you protect a page using an operating system interface, then you could position an array so that the array ends where the protection begins. You would have to designate the array by a pointer that you set (e.g., int *p) rather than declare it as an array (e.g., int p[40]), because most C implementations do not give you a way to specify the address of an array.

Because of the granularity of most systems’ memory-protection, you typically can only align one end of an array with the protection boundary. So this is not a generally useful mechanism for protecting array bounds. I have used it for testing purposes, by testing both ends separately:

  • Align an array so that its end abuts the start of the protected memory. Execute tests.
  • Align an array so that its start abuts the end of the protected memory. Execute tests.

Thus, if the routines being tested improperly access memory before or after the array, then one of the tests will fail.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
1

I am assuming your arr is a POD (plain old data) array. You could make it in C++ a class and overload the operator[] to do runtime index checking.

You usually cannot do what you want, and if you could, it would be strongly implementation and operating system dependent.

On Linux, access permission to data is related to virtual memory mapping. This is related to the mmap(2) and munmap(2) with mprotect(2) system call. These calls work at a page-level granularity (a page is usually 4Kbytes, and 4Kbytes aligned).

You could make naughty tricks like mmap-ing a large region, mprotect its last page, and do unportable pointer arithmetic to compute the arr pointer. This is disgusting, so don't do that. And catching SIGSEGV with dirty mmap-based tricks like this is not very portable and probably not very efficient. And a signal handler cannot throw C++ exceptions.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547