12

An application runs on an embedded battery-powered PC, accessible to some restricted public, that stores secrets in RAM. To prevent cold boot attacks and that the PC is stolen to extract its secrets, it has temper-proof sensors. If tampering is detected, the application exists (but does not wipe all process memory before doing it). I cannot change this behavior.

Does the Linux kernel wipes the released process memory by default? Do any Linux distro do it? Is there a patch to do it?

By wiping I mean zero fill, or multiple-pass rewriting.

forest
  • 64,616
  • 20
  • 206
  • 257
SDL
  • 223
  • 2
  • 5

2 Answers2

12

Linux zeroes out (i.e. fills with zeros) all pages of memory not when they are released, but when they are given to another process. Thus, no process may obtain data excerpts from another process. However, the pages will retain their old contents until they are reused. I am not aware of any patch which does the zeroing upon page release (Edit: as @user2313067 points out in his answer, the PaX patch offers this option, at a cost which may or may not be a problem on any given system); on a general basis, it would be detrimental to performance because it would fill caches with the zeros, evicting more "useful" data (and that's not counting swap space, which your embedded device probably lacks, but most Linux systems out there have swap).

You can force a sort-of wipeout of data by simply allocating every possible page from another process. Something like this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int
main(void)
{
    for (;;) {
        void *x = malloc(2000);
        if (x == NULL) {
            break;
        }
        memset(x, 'T', 2000);
    }
    return 0;
}

If you run this program as root, then it grabs all available memory and fills it (in order to force actual allocation), exiting only when there is no memory left. Running as root is needed because the kernel reserves the last few pages to root.

Note that filling memory up triggers OOM conditions, at which point the kernel feels allowed to shoot processes in order to make some room. This happens only when there is no free page left, i.e. the state that you want to achieve (no free page left means that all old pages have been reallocated, and therefore zeroed out). It is a kind of suicide for the OS, because the OOM handling code may kill some essential processes (it tries not to, but hey, these are just heuristics). However, this seems appropriate in your case: if tampering is detected, the device has no choice except honourable disembowelment.

So you just have to launch your critical application in a wrapper (a simple script) which launches the above program when the critical application exits (presumably because of detected tampering).

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949
  • Wiping private bytes(those not shared with other processes) on process termination should hurt caches. – CodesInChaos Sep 11 '13 at 19:33
  • Indeed, "it would be detrimental to performance because it would fill caches with the zeros" – Thomas Pornin Sep 11 '13 at 19:46
  • Unless you use non-temporal stores, in which case the caches will be unaffected – CAFxX Sep 03 '16 at 02:04
  • This may not work on systems that have KSM (Kernel Samepage Merging) enabled. – forest Mar 12 '18 at 12:30
  • 1
    While this answer is correct for normal Linux systems, note that some embedded systems may set MAP_UNINITIALIZED and CONFIG_MMAP_ALLOW_UNINITIALIZED, which means that applications may receive uninitialised pages containing the memory of a previous process. If you are working with sensitive data on these exotic embedded systems, you'll want to be aware of this potential security problem. – Lie Ryan Sep 22 '18 at 08:11
  • This isn't a complete solution because sensitive data may still exist in kernel slabs. Also just a nitpick, but the pages aren't wiped when they're given to another process, but when they're _written to_. Before they're written to, the pages just point to the zero page, so reads return zeros even though the page actually has leftover contents on it. Only when the page is written to does a page fault occur to actually initialize it. Though I suppose this is assuming an MMU, which an embedded system might not have. – forest Nov 01 '18 at 08:18
  • Also, I believe you are incorrect wrt saying that the last few pages are reserved for root. By default, `RLIMIT_AS` is the same for both root and non-root processes (i.e. unlimited). Perhaps you're thinking of the ext4 filesystem, where only a tiny hidden quota of 5% is kept for the root user? – forest Nov 01 '18 at 08:20
5

Grsecurity has PAX_MEMORY_SANITIZE to do this. See the option on this page.

forest
  • 64,616
  • 20
  • 206
  • 257
user2313067
  • 916
  • 1
  • 6
  • 9