1

There's probably already an answer to this somewhere, but I can't find it.

As noted in this question: Accessing an array out of bounds gives no error, why?, C++ does not enforce array bounds, instead opting to provide undefined behavior. What I'm concerned about is the power of this behavior.

So suppose I write some simple program:

#include <iostream>
int main() {
    int* a = new int[1];
    long large_number = 9223372036854775807l; //2**63 - 1
    for (long i = 0l; i < large_number; i++) {
        std::cout << i << " " << a[i] << std::endl;
    }
    return 0;
}

This will continue to print the next 32-bit number stored on my system (assuming 32 bit-sized ints, obviously). When I run this on my machine, the program segfaults when i is around 30,000, which I'm guessing is around the size of the memory allocated for my program. This brings me to my question, which is three-fold:

  1. What's preventing me from continuing to read (not write) values outside this range? Is this prevention of reading system-specific? Compiler-specific?

  2. If I was clever with how I manipulate my pointer, could I read or write values outside of the scope of my program (without, obviously, having direct/normal access to these values)?

  3. I'm running all of this on a virtual machine. Can I access read/write memory values on my host machine? (If (2) is a no, then this is a no as well).

Note that I'm running g++ 5.3.1, no c++11, on a ubuntu virtualbox with a windows host machine.

Also, I recognize this question could be considered a security issue (reading/writing memory). I'm certainly not intending anything malicious, but if this is a problem, let me know and I will be glad to close the question.

EDIT: The following question appears related and interesting: Accessing outside the memory allocated by the program. (Accessing other app's memory) There doesn't seem to be a consensus on whether or not a program can read outside of it's virtual memory space though.

Community
  • 1
  • 1
Checkmate
  • 1,074
  • 9
  • 16
  • 4
    Look up _virtual memory_. Each process in modern OS's has its own memory space, and the memory of other processes (or the host machine on a VM) are not visible. – Colonel Thirty Two Jul 25 '16 at 02:16
  • Ok, that makes sense. Out of curiosity, do all modern OS's use virtual memory management? Can you give a program access to information outside of its virtual memory space? I can't find much of a consensus... – Checkmate Jul 25 '16 at 02:30
  • 1
    Unless you're the kernel (or there is a bug in the kernel's implementation), no - you don't have access to other programs' memory space in user mode. – roelofs Jul 25 '16 at 02:35
  • Sorry, what do you mean by user mode? If I run the program as a superuser (sudo), could I get access? Do you mean user mode as opposed to kernel mode, as in: https://msdn.microsoft.com/en-us/library/windows/hardware/ff554836(v=vs.85).aspx ? – Checkmate Jul 25 '16 at 02:38
  • 1
    If you're superuser, you can pretty much do whatever you want. For example, under Linux the root user can read or write directly to physical RAM via the /dev/mem device. Good times! – Jeremy Friesner Jul 25 '16 at 02:52
  • Wow, that's kind of terrifying. Good to know, thanks. – Checkmate Jul 25 '16 at 02:55
  • 2
    _Usermode_ or _userspace_ is the mode that programs run in. They usually run in a restricted environment (ex. can't access hardware or other process' memory directly) and must communicate with the OS. In contrast _kernelspace_ is the mode that the kernel runs in. It has full access to the hardware. (Root programs do _not_ execute in kernel mode; they are user mode apps where the OS will grant all permissions. Only kernel code can run in kernel mode) – Colonel Thirty Two Jul 25 '16 at 03:05
  • Alright, that makes sense. So even with running code with sudo, there should be no way on a modern OS to manipulate data outside of your virtual machine since it isn't kernel code. Fascinating, thank you! – Checkmate Jul 25 '16 at 03:10

1 Answers1

2
  1. The operating system. The operating system mapped only a certain range of virtual addresses onto physical addresses. After reaching the end of the mapped virtual address ranges, an attempt to access a nonexistent virtual address generates a SIGSEGV.

  2. No. At least not on any modern operating system.

  3. Not unless you can find a bug in your host operating system's virtual machine, and exploit it.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148