30

Theoretically, if I were to build a program that allocated all the unused memory on a system, and continued to request more and more memory as other applications released memory that they no longer need, would it be possible to read recently released memory from another applications? Or is this somehow protected by modern operating system?

I have no practical application for this, I'm just curious. I realize there are some issues with allocating "all available memory" in real-life.

Edit: To clarify, I'm asking specifically about "Released" memory, not accessing memory that is currently allocated by another application.

5 Answers 5

26

No, because a good kernel wipes the contents of memory before it is issued to a process to protect against exactly the kind of attack you propose.

On Unixy systems, memory is allocated to processes by extending what's called the program break, which is the limit of virtually-addressable space a process can use. A process tells the kernel it wants to extend its addressable space, and the kernel will allow it if memory is available or the call will fail if not. (The name of the brk() system call comes from this concept.)

In practice, large blocks of freed memory don't often butt up against the program break, which is what would be required for a process to return memory to the kernel by shrinking the program break. This is, of course, all dependent on your system's implementation of malloc() and free(). If you have sources available, they'll tell you whether or not memory is ever returned.

There are no security implications for malloc() not initializing memory because anything it got via brk() will have been scrubbed and anything previously free()d will have been written by the same process.

21

Yes, it's theoretically possible to read another process' released memory. It was the source of a number of privilege escalation attacks back in the day. Because of that, operating systems nowadays effectively zero out memory if it was previously allocated by another process. The reason you don't always see zeroed out memory is because it is more efficient not to zero out the memory if it was previously allocated by the same process. The OS tries to give back memory pages to the same process if it can.

7
  • 1
    "Yes but no" is "no". @Blrfl has it right. Commented Jan 4, 2013 at 22:01
  • 4
    @RossPatterson: On the theoretical point, Karl is actually more right than I am. The practical reality is that mainstream OSes closed that hole years ago.
    – Blrfl
    Commented Jan 5, 2013 at 13:28
  • @Blrfl Understood. But "years ago" was in the late 1960s, when paging systems and virtual memory were first introduced. Certainly by the time of Multics, VM/370, and OS/VS. Absent bugs, this hasn't been possible in the memory of most practicing programmers. Commented Jan 5, 2013 at 15:47
  • 1
    I think I'm missing something. Why then, when I compile and run some C++ program with, say, uninitialized integers, they're not equal to 0 when I read those variables?
    – jakub.g
    Commented Mar 18, 2013 at 16:31
  • 1
    Because that specific memory address was previously used by your program and has been recycled, possibly even before main() started. Commented Mar 18, 2013 at 16:50
2

There are several layers involved here that affect the answer.

If you assume a modern virtual memory operating system, you will not be able to see the remnants of another processes data in pages you allocate.

When a process first gets loaded, the page table is loaded, and potentially frames of real memory are allocated to those pages. At a minimum, the page table or its supplemental table, will contain a map of all memory the process can allocate. This is also where the initial process break, mentioned above, gets set.

While malloc() may, if the process is allowed, cause the process break to change, adding more pages to a processes page (supplemental page) table to satisfy the request, the place where one process may "get another" processes data is at the lower real memory layer.

In both of these scenarios a modern operating system that uses demand paging, or lazy allocation, is not allocating physical memory (frames) yet. The operating system is just "making notes" about which virtual memory for that process is considered valid. Actual memory gets assigned only when needed.

Physical memory or frames get allocated to a process when the virtual page is realized and mapped into a processes page table This is where the potential for data exposure exists. This happens during a page fault. The exposure is because a previous process may have been using that same frame and its data were either abandoned or swapped out, to make room for the current physical memory request. The operating system must be careful to ensure that the requesting processes data is properly swapped in or the frame is cleared (zeroed) before resuming the process. This is also mentioned above as an "old but solved" problem.

This makes it somewhat irrelevant if the other processes memory was "released" or not. Another processes "released" memory still resides in pages assigned to that process and are not usually unmapped until the process ends as they will just get swapped out when memory gets low or they are otherwise evicted. malloc() and free() manage the virtual memory assigned to the process at the (user) level.

In your question, your process, continues to request more and more memory, in theory, pushing all other processes out of memory. In reality, there are frame allocation strategies -- global and local -- that may affect the answer as well. It is as likely that the process will force its own pages out of memory before it is allowed to overrun the operating system and all other processes. Though this goes beyond your initial question.

All this is moot in a system like MS-DOS. MS-DOS (and other, simpler systems) don't use virtual memory (by themselves) and you could easily poke and prod at another "processes" data.

Some good references, that may be easier to understand than the Linux source code would be a good operating systems text book, Operating Systems Concepts by Silberscatz, Gavin, and Gange, or Operating Systems Design by Andrew Tanenbaum. Also something like Nachos from Berkeley or Pintos from Stanford are small operating systems built for learning and have these same ideas within them.

1

I tried this on Ubuntu 16.04 months ago. Just as 0xACE said, modern OS allocates an all-zero, virtual page once you called malloc(). But, if you do not write anything to the allocated buffer, it won't be mapped into physical memory (that is, copy-on-write principle), thus you'll always read zeros from an "uninitialized" block. Maybe there are some embedded OS compiled with "CONFIG_MMAP_ALLOW_UNITIALIZED" option for better performance, in this case you could get what you expceted for.

-1

No, this won't allow another program to read another's memory thanks to the magic of paging. This way, total memory use can exceed the physical ram by offloading parts of it to the harddrive.

Also, the maximum memory a process can allocate is arbitrarily limited by the OS (up to 4 gigs for a 32 bit architecture) after which the next alloc call will return an out of memory error.

6
  • Aren't there platform specific APIs that can circumvent this? I honestly don't know, but I wouldn't be surprised (for example, Linux allows preventing the OS from moving a page out of physical memory, via mlock).
    – user7043
    Commented Jan 4, 2013 at 21:29
  • If there are 4 GB of RAM and paging is limited to 8 GB, what if the application requests 12 GB (on an x64)? Commented Jan 4, 2013 at 21:30
  • then the system calls should return an error when too little free memory will remain, that or the computer will simply grind to a halt when there isn't any left... Commented Jan 4, 2013 at 21:35
  • 4
    He's not asking about reading another's memory, but rather reading their RELEASED memory. That section of ram is currently free, and.... I don't think... that paging schemes zero out memory after it's freed. So the program would allocate a block of memory, and analyze the uninitialized data that's already there.
    – Philip
    Commented Jan 4, 2013 at 21:38
  • @philip correct, I am asking specifically about released memory. Commented Jan 4, 2013 at 21:42

Not the answer you're looking for? Browse other questions tagged or ask your own question.