1

I am searching for an way to randomize or define patterns for the allocated memory for C++ applications using G++ or Clang on Linux systems. (e.G. re implementing malloc)

The goal is to define allocated memory patterns which is otherwise undefined by the C++ Standard.

The background/aim of this question is not to search for memory issues for which also other solutions exist.

2 Answers2

1

I found the solution I was looking for (here with 0xFF fixed initialization):

#include <stdio.h>
#include <dlfcn.h>
#include <malloc.h>


extern void abort();


void *malloc(size_t size) {
        void * (*ptr)(int);
        void * handle = (void*) -1; 
        ptr = (void *) dlsym(handle, "malloc");
        if (ptr == NULL) {
                printf("Opps\n");
                abort();
        }
        void *alloc = (*ptr)(size);
        size_t alloc_size = malloc_usable_size(alloc);
        for(int i=0;i<alloc_size;++i){
            *((__int8_t*)alloc+i) = 0xff;
        }
        return alloc;
}


void *realloc(void *alloc, size_t size) {
        void * (*ptr)(void *, int);
        void * handle = (void*) -1; 
        size_t old_size = malloc_usable_size(alloc);
        ptr = (void *) dlsym(handle, "realloc");
        if (ptr == NULL) {
                printf("Opps\n");
                abort();
        }
        alloc = (*ptr)(alloc, size);
        size_t new_size = malloc_usable_size(alloc);
        for(int i=old_size;i<new_size;++i){
            *((__int8_t*)alloc+i) = 0xff;
        }
        return alloc;
}

to compile and execute it:

$ cat run.sh 
#!/bin/bash
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/src/rand_alloc/ LD_PRELOAD=librand_alloc.so $*
$ cat Makefile 
all:
    gcc -Wall file.c -fPIC -shared -o librand_alloc.so -lc -ldl

Main inspiration from: https://www.stev.org/post/chowtooverridemallocfree

0

On some targets the code is causing issues, assuming due to non-zeroed memory

Don't assume. Profile. If reads from uninitialized memory are your problem you could install a signal handler for SIGSEGV, then when your program is at a state where you can start "probing" it use mprotect to mark all pages in the data segment as PROT_NONE and then inside the SIGSEGV handler re-add the PROT_READ and PROT_WRITE flags as required, taking notes which parts of your program did access which portion of the address space. But this will give you only coarse granularity and fail miserably for memory allocated from pools like malloc and new do.

Valgrind is exactly the tool for the job you have at hand.

Afaik Linux is "faking" malloc't memory which didn't belong to the process before to zero

On Linux ever since kernel version 2.6.33 memory allocated directly using mmap will always be initialized to zero. This is not so much a "fake" zero, rather than Linux will initially map to an all-zero page at first, so that reads come out as zero and upon the first write request a fresh page will be allocated, cleared to zero and replace the placeholder page map.

datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • I would first "ensure" that the memory initialization is the problem. There are different other reasons in such a large codebase for the issue (including hardware problems on the target). So to narrow down the issue and BEFORE going in depth to fix all the wrong reads, reproducing the issue i a fair way to go. – Matthias Goldhoorn May 10 '21 at 16:20
  • @MatthiasGoldhoorn: Running Memtest86+ should identify any hardware issues that might show up in address space mapping of physical memory. Of course memory mapped I/O regions may be subject to bus transmission faults. However given that modern I/O busses are extremely robust and liberally apply all sorts of error detection and forward correction methods this is unlikely. – datenwolf May 10 '21 at 19:35