Skip to content

Instantly share code, notes, and snippets.

@maxymania
Last active January 6, 2023 13:28
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save maxymania/50b47616dd1188be91e0 to your computer and use it in GitHub Desktop.
Save maxymania/50b47616dd1188be91e0 to your computer and use it in GitHub Desktop.
secmalloc.c: Small, Secure Malloc implementation.
This is a (probably incomplete) small, secure malloc implementation.
Background
==========
Regular malloc implementations such as dlmalloc, glibc's ptmalloc,
the old brk/sbrk/heap-based UNIX-malloc as well as jemalloc,
THEY ALL honor use-after-free bugs!!! As a result, every software
written for UNIX, Linux, OS X or BSD extensively relies on
use-after-free bugs. Even worse, major Libc implementations do a huge
effort in order to make sure, use-after-free contaminated software wont crash.
This is a giant security thread rendering major internet software insecure.
My malloc implementation is secure by default, as it calls mmap upon
EVERY malloc() and munmap on EVERY free(). It is guaranteed that every
use-after-free bug will cause an segmentation fault.
Still missing functions
=======================
#include <stdlib.h>
int posix_memalign(void **memptr, size_t alignment, size_t size);
void *aligned_alloc(size_t alignment, size_t size);
void *valloc(size_t size);
#include <malloc.h>
void *memalign(size_t alignment, size_t size);
void *pvalloc(size_t size);
/* This function is a GNU extension. */
size_t malloc_usable_size (void *ptr);
/*
* I found this function while i crawled the web for malloc-related functions.
* I included it, because it could be relevant (theoretically).
* Propably, this function is not available on Linux and thus not relevant,
* but AIX and HP-UX? Solaris? Mac OS? Other UNIXes?
*
* '''
* The reallocf() function is identical to the realloc() function, except
* that it will free the passed pointer when the requested memory cannot be
* allocated. This is a FreeBSD specific API designed to ease the problems
* with traditional coding styles for realloc causing memory leaks in
* libraries.
* '''
*/
void *reallocf(void *ptr, size_t size);
secmalloc.o: secmalloc.c
gcc -c -fPIC secmalloc.c -o secmalloc.o
secmalloc.so: secmalloc.o
gcc -shared -Wl,-soname,secmalloc.so -o secmalloc.so secmalloc.o
/*
* Copyright (c) 2016 Simon Schmidt
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <stdint.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>
#ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS MAP_ANON
#endif
#define MPT MAP_PRIVATE|MAP_ANONYMOUS
#define PRT PROT_WRITE|PROT_READ
typedef union Premap_s {
uintptr_t align;
size_t allocsize;
} Premap;
static size_t rndup(size_t size){
int pgs = getpagesize()-1;
size+=sizeof(Premap);
size+=pgs;
size&=~pgs;
return size;
}
void *malloc(size_t size){
if(!size)return NULL;
size=rndup(size);
Premap* map = mmap(NULL,size,PRT,MPT,-1,0);
if(map==MAP_FAILED)return NULL;
map->allocsize=size;
return &map[1];
}
void free(void *ptr){
if(!ptr)return;
Premap* map = (ptr-sizeof(Premap));
size_t size = map->allocsize;
munmap(map,size);
}
void *calloc(size_t nmemb, size_t size){
size*=nmemb;
return malloc(size);
}
void *realloc(void *ptr, size_t size){
size_t oldsz,rsize;
Premap *map,*nmap;
void* nptr;
if(!size){
free(ptr);
return NULL;
}
if(!ptr)return malloc(size);
rsize=rndup(size);
map = (ptr-sizeof(Premap));
oldsz=map->allocsize;
if(oldsz<rsize){ /* Growing the area */
nmap = mmap(NULL,rsize,PRT,MPT,-1,0);
if(nmap==MAP_FAILED) return NULL;
memcpy(nmap,map,oldsz);
nmap->allocsize = rsize;
free(ptr);
return &nmap[1];
}else if(oldsz>rsize){ /* Shrinking the area */
nmap = mmap(NULL,rsize,PRT,MPT,-1,0);
if(nmap==MAP_FAILED) return ptr;
memcpy(nmap,map,rsize);
nmap->allocsize = rsize;
free(ptr);
return &nmap[1];
}
return ptr;
}
/*
* Copyright (c) 2016 Simon Schmidt
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <stdlib.h>
#include <stdio.h>
void main(){
char* x = malloc(10000);
*x=1;
printf("Everythin is still fine!\n");
free(x);
*x=1;
printf("Your system has been taken over by a use-after-free bug!\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment