Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting as much uninitialized memory as possible

I'm trying to create a C/C++ program that dumps as much uninitialized memory as possible. The program has to be run by a local user, i.e in user mode.

It does not work to use malloc: Why does malloc initialize the values to 0 in gcc?

The goal is not to use this data as a seed for randomness.

Does the OS always make sure that you can't see "leftovers" from other processes?

If possible, I would like references to implementations or further explanation.

like image 447
user144437 Avatar asked May 06 '16 17:05

user144437


People also ask

What does uninitialized memory mean?

Use of uninitialized memory means reading data from the buffer that was allocated but not filled with initial values. The program behavior in this case is considered an error which is quite difficult to detect sometimes. This is a so called "heisenbug".

What is initialized memory?

"initialized" is simply when you post some data to that memory for the first time. "It means setting the memory to a known value before you start. "


4 Answers

The most common multi-user operating systems (modern Windows, Linux, other Unix variants, VMS--probably all OSes with a concept of virtual memory) try to isolate processes from one another for security. If process A could read process B's leftover memory, it might get access to user data it shouldn't have, so these operating systems will clear pages of memory before they become available to a new process. You would probably have to have elevated privileges to get at uninitialized RAM, and the solution would likely depend on which operating system it was.

Embedded OSes, DOS, and ancient versions of Windows generally don't have the facilities for protecting memory. But they also don't have a concept of virtual memory or of strong process isolation. On these, just allocating memory through the usual methods (e.g., malloc) would give you uninitialized memory without you having to do anything special.

For more information on Windows, you can search for Windows zero page thread to learn about the OS thread whose only job is to write zeros in unused pages so that they can be doled out again. Also, Windows has a feature called superfetch which fills up unused RAM with files that Windows predicts you'll want to open soon. If you allocated memory and Windows decided to give you a superfetch page, there would be a risk that you'd see the contents of a file you don't have access to read. This is another reason why pages must be cleared before they can be allocated to a process.

like image 110
Adrian McCarthy Avatar answered Sep 25 '22 07:09

Adrian McCarthy


You got uninitialized memory. It contains indeterminate values. In your case those values are all 0. Nothing unexpected. If you want pseudo-random numbers use a PRNG. If you want real random numbers/entropy, use a legitimate random source like your operating system's random number device (e.g. /dev/urandom) or API.

like image 43
R.. GitHub STOP HELPING ICE Avatar answered Sep 27 '22 07:09

R.. GitHub STOP HELPING ICE


No operating system in its right mind is going to provide uninitialized memory to a process.

The closest thing you are going to find is the stack. That memory will have been initialized when mapped to the process but much of it will have been overwritten.

like image 28
user3344003 Avatar answered Sep 25 '22 07:09

user3344003


It's common sense. We don't need to document that 1+1=2 either.

An operating system that leaks secrets between processes would be useless for many applications. So if a general purpose operating system that wants to be general purpose it will isolate processes. Keeping track of which pages might contain secrets and which are safe would be too much work and too error-prone, so we assume that every page that has ever been used is dirty and contains secrets. Initializing new pages with garbage is slower than initializing them with just one value, so random garbage isn't used. The most useful value is zero (for calloc or bss for example), so new pages are zeroed to clear them.

There's really no other way to do it.

There might be special purpose operating systems that don't do it and do leak secrets between processes (it might be necessary for real-time requirements for example). Some older operating systems didn't have decent memory management and privilege isolation. Also, malloc will reuse previously freed memory within the same process. Therefore malloc will be documented to contain uninitialized garbage. But that doesn't mean you'll ever be able to obtain uninitialized memory from another process on a general purpose operating system.

I guess a simple rule of thumb is: if your operating system ever asks you for a password it will not give uninitialized pages to a process and since zeroing is the only reasonable way to initialize pages, they will be zeroed.

like image 26
Art Avatar answered Sep 26 '22 07:09

Art