From 6e0907a22ffbf7abf4b4b4a7e9e9e670202d77c2 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Wed, 10 Jan 2007 14:57:22 +0000 Subject: [PATCH] * Split load-fd.c into load-fd.c and load-mem.c (mmap, etc.). --- src/Makefile.am | 2 +- src/libzzuf.c | 1 + src/load-fd.c | 148 +----------------------------------- src/load-mem.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++ src/load.h | 1 + 5 files changed, 198 insertions(+), 148 deletions(-) create mode 100644 src/load-mem.c diff --git a/src/Makefile.am b/src/Makefile.am index 9fdd958..6cb573d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,7 +6,7 @@ zzuf_CFLAGS = -DLIBDIR=\"$(libdir)/zzuf\" pkglib_LTLIBRARIES = libzzuf.la libzzuf_la_SOURCES = libzzuf.c libzzuf.h $(COMMON) debug.c debug.h \ - load-fd.c load-signal.c load-stream.c load.h + load-fd.c load-mem.c load-signal.c load-stream.c load.h libzzuf_la_LDFLAGS = -avoid-version -no-undefined libzzuf_la_LIBADD = @GETOPT_LIBS@ @DL_LIBS@ diff --git a/src/libzzuf.c b/src/libzzuf.c index 3c9d370..8268c85 100644 --- a/src/libzzuf.c +++ b/src/libzzuf.c @@ -94,6 +94,7 @@ void _zz_init(void) _zz_register(0); _zz_load_fd(); + _zz_load_mem(); _zz_load_signal(); _zz_load_stream(); diff --git a/src/load-fd.c b/src/load-fd.c index b9e931b..c1e45a2 100644 --- a/src/load-fd.c +++ b/src/load-fd.c @@ -18,7 +18,7 @@ #include "config.h" -/* Can't remember what that's for */ +/* Need this for RTLD_NEXT */ #define _GNU_SOURCE /* Use this to get lseek64() on glibc systems */ #define _LARGEFILE64_SOURCE @@ -34,13 +34,9 @@ #include #include -#include #include #include #include -#if defined HAVE_LIBC_H -# include -#endif #include "libzzuf.h" #include "debug.h" @@ -67,18 +63,6 @@ static off_t (*lseek_orig) (int fd, off_t offset, int whence); #ifdef HAVE_LSEEK64 static off64_t (*lseek64_orig) (int fd, off64_t offset, int whence); #endif -static void * (*mmap_orig) (void *start, size_t length, int prot, - int flags, int fd, off_t offset); -#ifdef HAVE_LSEEK64 -static void * (*mmap64_orig) (void *start, size_t length, int prot, - int flags, int fd, off64_t offset); -#endif -static int (*munmap_orig) (void *start, size_t length); -#ifdef HAVE_MAP_FD -static kern_return_t (*map_fd_orig) (int fd, vm_offset_t offset, - vm_offset_t *addr, boolean_t find_space, - vm_size_t numbytes); -#endif static int (*close_orig) (int fd); @@ -94,14 +78,6 @@ void _zz_load_fd(void) LOADSYM(lseek); #ifdef HAVE_LSEEK64 LOADSYM(lseek64); -#endif - LOADSYM(mmap); -#ifdef HAVE_MMAP64 - LOADSYM(mmap64); -#endif - LOADSYM(munmap); -#ifdef HAVE_MAP_FD - LOADSYM(map_fd); #endif LOADSYM(close); } @@ -257,128 +233,6 @@ off64_t lseek64(int fd, off64_t offset, int whence) } #endif -/* Used for mmap() and munmap() */ -void **maps = NULL; -int nbmaps = 0; - -#define MMAP(fn, off_t) \ - do { \ - if(!_zz_ready) \ - LOADSYM(fn); \ - ret = ORIG(fn)(start, length, prot, flags, fd, offset); \ - if(!_zz_ready || !_zz_iswatched(fd) || _zz_disabled) \ - return ret; \ - if(ret && length) \ - { \ - char *b = malloc(length); \ - int i, oldpos; \ - for(i = 0; i < nbmaps; i += 2) \ - if(maps[i] == NULL) \ - break; \ - if(i == nbmaps) \ - { \ - nbmaps += 2; \ - maps = realloc(maps, nbmaps * sizeof(void *)); \ - } \ - maps[i] = b; \ - maps[i + 1] = ret; \ - oldpos = _zz_getpos(fd); \ - _zz_setpos(fd, offset); /* mmap() maps the fd at offset 0 */ \ - memcpy(b, ret, length); /* FIXME: get rid of this */ \ - _zz_fuzz(fd, (uint8_t *)b, length); \ - _zz_setpos(fd, oldpos); \ - ret = b; \ - if(length >= 4) \ - debug(STR(fn)"(%p, %li, %i, %i, %i, %lli) = %p \"%c%c%c%c...", \ - start, (long int)length, prot, flags, fd, \ - (long long int)offset, ret, b[0], b[1], b[2], b[3]); \ - else \ - debug(STR(fn)"(%p, %li, %i, %i, %i, %lli) = %p \"%c...", \ - start, (long int)length, prot, flags, fd, \ - (long long int)offset, ret, b[0]); \ - } \ - else \ - debug(STR(fn)"(%p, %li, %i, %i, %i, %lli) = %p", \ - start, (long int)length, prot, flags, fd, \ - (long long int)offset, ret); \ - } while(0) - -void *mmap(void *start, size_t length, int prot, int flags, - int fd, off_t offset) -{ - void *ret; MMAP(mmap, off_t); return ret; -} - -#ifdef HAVE_MMAP64 -void *mmap64(void *start, size_t length, int prot, int flags, - int fd, off64_t offset) -{ - void *ret; MMAP(mmap64, off64_t); return ret; -} -#endif - -int munmap(void *start, size_t length) -{ - int ret, i; - - if(!_zz_ready) - LOADSYM(munmap); - for(i = 0; i < nbmaps; i++) - { - if(maps[i] != start) - continue; - - free(start); - ret = munmap_orig(maps[i + 1], length); - maps[i] = NULL; - maps[i + 1] = NULL; - debug("munmap(%p, %li) = %i", start, (long int)length, ret); - return ret; - } - - return munmap_orig(start, length); -} - -#ifdef HAVE_MAP_FD -kern_return_t map_fd(int fd, vm_offset_t offset, vm_offset_t *addr, - boolean_t find_space, vm_size_t numbytes) -{ - kern_return_t ret; - - if(!_zz_ready) - LOADSYM(map_fd); - ret = map_fd_orig(fd, offset, addr, find_space, numbytes); - if(!_zz_ready || !_zz_iswatched(fd) || _zz_disabled) - return ret; - - if(ret == 0 && numbytes) - { - /* FIXME: do we also have to rewind the filedescriptor like in mmap? */ - void *b = malloc(numbytes); - memcpy(b, (void *)*addr, numbytes); - _zz_fuzz(fd, b, numbytes); - *addr = (vm_offset_t)b; - /* FIXME: the map is never freed; there is no such thing as unmap_fd, - * but I suppose that kind of map should go when the filedescriptor is - * closed (unlike mmap, which returns a persistent buffer). */ - - if(numbytes >= 4) - debug("map_fd(%i, %lli, &%p, %i, %lli) = %i \"%c%c%c%c", fd, - (long long int)offset, (void *)*addr, (int)find_space, - (long long int)numbytes, ret, b[0], b[1], b[2], b[3]); - else - debug("map_fd(%i, %lli, &%p, %i, %lli) = %i \"%c", fd, - (long long int)offset, (void *)*addr, (int)find_space, - (long long int)numbytes, ret, b[0]); - } - else - debug("map_fd(%i, %lli, &%p, %i, %lli) = %i", fd, (long long int)offset, - (void *)*addr, (int)find_space, (long long int)numbytes, ret); - - return ret; -} -#endif - int close(int fd) { int ret; diff --git a/src/load-mem.c b/src/load-mem.c new file mode 100644 index 0000000..badaaa6 --- /dev/null +++ b/src/load-mem.c @@ -0,0 +1,194 @@ +/* + * zzuf - general purpose fuzzer + * Copyright (c) 2006,2007 Sam Hocevar + * All Rights Reserved + * + * $Id$ + * + * This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + */ + +/* + * load-mem.c: loaded memory handling functions + */ + +#include "config.h" + +/* Need this for RTLD_NEXT */ +#define _GNU_SOURCE +/* Use this to get mmap64() on glibc systems */ +#define _LARGEFILE64_SOURCE + +#if defined HAVE_STDINT_H +# include +#elif defined HAVE_INTTYPES_H +# include +#endif +#include +#include +#include + +#include +#include +#if defined HAVE_LIBC_H +# include +#endif + +#include "libzzuf.h" +#include "debug.h" +#include "fuzz.h" +#include "load.h" +#include "fd.h" + +/* Library functions that we divert */ +static void * (*mmap_orig) (void *start, size_t length, int prot, + int flags, int fd, off_t offset); +#ifdef HAVE_MMAP64 +static void * (*mmap64_orig) (void *start, size_t length, int prot, + int flags, int fd, off64_t offset); +#endif +static int (*munmap_orig) (void *start, size_t length); +#ifdef HAVE_MAP_FD +static kern_return_t (*map_fd_orig) (int fd, vm_offset_t offset, + vm_offset_t *addr, boolean_t find_space, + vm_size_t numbytes); +#endif + +void _zz_load_mem(void) +{ + LOADSYM(mmap); +#ifdef HAVE_MMAP64 + LOADSYM(mmap64); +#endif + LOADSYM(munmap); +#ifdef HAVE_MAP_FD + LOADSYM(map_fd); +#endif +} + +/* Table used for mmap() and munmap() */ +void **maps = NULL; +int nbmaps = 0; + +#define MMAP(fn, off_t) \ + do { \ + if(!_zz_ready) \ + LOADSYM(fn); \ + ret = ORIG(fn)(start, length, prot, flags, fd, offset); \ + if(!_zz_ready || !_zz_iswatched(fd) || _zz_disabled) \ + return ret; \ + if(ret && length) \ + { \ + char *b = malloc(length); \ + int i, oldpos; \ + for(i = 0; i < nbmaps; i += 2) \ + if(maps[i] == NULL) \ + break; \ + if(i == nbmaps) \ + { \ + nbmaps += 2; \ + maps = realloc(maps, nbmaps * sizeof(void *)); \ + } \ + maps[i] = b; \ + maps[i + 1] = ret; \ + oldpos = _zz_getpos(fd); \ + _zz_setpos(fd, offset); /* mmap() maps the fd at offset 0 */ \ + memcpy(b, ret, length); /* FIXME: get rid of this */ \ + _zz_fuzz(fd, (uint8_t *)b, length); \ + _zz_setpos(fd, oldpos); \ + ret = b; \ + if(length >= 4) \ + debug(STR(fn)"(%p, %li, %i, %i, %i, %lli) = %p \"%c%c%c%c...", \ + start, (long int)length, prot, flags, fd, \ + (long long int)offset, ret, b[0], b[1], b[2], b[3]); \ + else \ + debug(STR(fn)"(%p, %li, %i, %i, %i, %lli) = %p \"%c...", \ + start, (long int)length, prot, flags, fd, \ + (long long int)offset, ret, b[0]); \ + } \ + else \ + debug(STR(fn)"(%p, %li, %i, %i, %i, %lli) = %p", \ + start, (long int)length, prot, flags, fd, \ + (long long int)offset, ret); \ + } while(0) + +void *mmap(void *start, size_t length, int prot, int flags, + int fd, off_t offset) +{ + void *ret; MMAP(mmap, off_t); return ret; +} + +#ifdef HAVE_MMAP64 +void *mmap64(void *start, size_t length, int prot, int flags, + int fd, off64_t offset) +{ + void *ret; MMAP(mmap64, off64_t); return ret; +} +#endif + +int munmap(void *start, size_t length) +{ + int ret, i; + + if(!_zz_ready) + LOADSYM(munmap); + for(i = 0; i < nbmaps; i++) + { + if(maps[i] != start) + continue; + + free(start); + ret = munmap_orig(maps[i + 1], length); + maps[i] = NULL; + maps[i + 1] = NULL; + debug("munmap(%p, %li) = %i", start, (long int)length, ret); + return ret; + } + + return munmap_orig(start, length); +} + +#ifdef HAVE_MAP_FD +kern_return_t map_fd(int fd, vm_offset_t offset, vm_offset_t *addr, + boolean_t find_space, vm_size_t numbytes) +{ + kern_return_t ret; + + if(!_zz_ready) + LOADSYM(map_fd); + ret = map_fd_orig(fd, offset, addr, find_space, numbytes); + if(!_zz_ready || !_zz_iswatched(fd) || _zz_disabled) + return ret; + + if(ret == 0 && numbytes) + { + /* FIXME: do we also have to rewind the filedescriptor like in mmap? */ + void *b = malloc(numbytes); + memcpy(b, (void *)*addr, numbytes); + _zz_fuzz(fd, b, numbytes); + *addr = (vm_offset_t)b; + /* FIXME: the map is never freed; there is no such thing as unmap_fd, + * but I suppose that kind of map should go when the filedescriptor is + * closed (unlike mmap, which returns a persistent buffer). */ + + if(numbytes >= 4) + debug("map_fd(%i, %lli, &%p, %i, %lli) = %i \"%c%c%c%c", fd, + (long long int)offset, (void *)*addr, (int)find_space, + (long long int)numbytes, ret, b[0], b[1], b[2], b[3]); + else + debug("map_fd(%i, %lli, &%p, %i, %lli) = %i \"%c", fd, + (long long int)offset, (void *)*addr, (int)find_space, + (long long int)numbytes, ret, b[0]); + } + else + debug("map_fd(%i, %lli, &%p, %i, %lli) = %i", fd, (long long int)offset, + (void *)*addr, (int)find_space, (long long int)numbytes, ret); + + return ret; +} +#endif + diff --git a/src/load.h b/src/load.h index 503e243..86efd8c 100644 --- a/src/load.h +++ b/src/load.h @@ -27,6 +27,7 @@ } while(0) extern void _zz_load_fd(void); +extern void _zz_load_mem(void); extern void _zz_load_signal(void); extern void _zz_load_stream(void);