source: zzuf/trunk/src/load-mem.c @ 1639

Last change on this file since 1639 was 1639, checked in by Sam Hocevar, 15 years ago
  • Split load-fd.c into load-fd.c and load-mem.c (mmap, etc.).
  • Property svn:keywords set to Id
File size: 5.7 KB
Line 
1/*
2 *  zzuf - general purpose fuzzer
3 *  Copyright (c) 2006,2007 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id: load-mem.c 1639 2007-01-10 14:57:22Z sam $
7 *
8 *  This program is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15/*
16 *  load-mem.c: loaded memory handling functions
17 */
18
19#include "config.h"
20
21/* Need this for RTLD_NEXT */
22#define _GNU_SOURCE
23/* Use this to get mmap64() on glibc systems */
24#define _LARGEFILE64_SOURCE
25
26#if defined HAVE_STDINT_H
27#   include <stdint.h>
28#elif defined HAVE_INTTYPES_H
29#   include <inttypes.h>
30#endif
31#include <stdlib.h>
32#include <string.h>
33#include <dlfcn.h>
34
35#include <unistd.h>
36#include <sys/mman.h>
37#if defined HAVE_LIBC_H
38#   include <libc.h>
39#endif
40
41#include "libzzuf.h"
42#include "debug.h"
43#include "fuzz.h"
44#include "load.h"
45#include "fd.h"
46
47/* Library functions that we divert */
48static void *  (*mmap_orig)    (void *start, size_t length, int prot,
49                                int flags, int fd, off_t offset);
50#ifdef HAVE_MMAP64
51static void *  (*mmap64_orig)  (void *start, size_t length, int prot,
52                                int flags, int fd, off64_t offset);
53#endif
54static int     (*munmap_orig)  (void *start, size_t length);
55#ifdef HAVE_MAP_FD
56static kern_return_t (*map_fd_orig) (int fd, vm_offset_t offset,
57                                     vm_offset_t *addr, boolean_t find_space,
58                                     vm_size_t numbytes);
59#endif
60
61void _zz_load_mem(void)
62{
63    LOADSYM(mmap);
64#ifdef HAVE_MMAP64
65    LOADSYM(mmap64);
66#endif
67    LOADSYM(munmap);
68#ifdef HAVE_MAP_FD
69    LOADSYM(map_fd);
70#endif
71}
72
73/* Table used for mmap() and munmap() */
74void **maps = NULL;
75int nbmaps = 0;
76
77#define MMAP(fn, off_t) \
78    do { \
79        if(!_zz_ready) \
80            LOADSYM(fn); \
81        ret = ORIG(fn)(start, length, prot, flags, fd, offset); \
82        if(!_zz_ready || !_zz_iswatched(fd) || _zz_disabled) \
83            return ret; \
84        if(ret && length) \
85        { \
86            char *b = malloc(length); \
87            int i, oldpos; \
88            for(i = 0; i < nbmaps; i += 2) \
89                if(maps[i] == NULL) \
90                    break; \
91            if(i == nbmaps) \
92            { \
93                nbmaps += 2; \
94                maps = realloc(maps, nbmaps * sizeof(void *)); \
95            } \
96            maps[i] = b; \
97            maps[i + 1] = ret; \
98            oldpos = _zz_getpos(fd); \
99            _zz_setpos(fd, offset); /* mmap() maps the fd at offset 0 */ \
100            memcpy(b, ret, length); /* FIXME: get rid of this */ \
101            _zz_fuzz(fd, (uint8_t *)b, length); \
102            _zz_setpos(fd, oldpos); \
103            ret = b; \
104            if(length >= 4) \
105                debug(STR(fn)"(%p, %li, %i, %i, %i, %lli) = %p \"%c%c%c%c...", \
106                      start, (long int)length, prot, flags, fd, \
107                      (long long int)offset, ret, b[0], b[1], b[2], b[3]); \
108            else \
109                debug(STR(fn)"(%p, %li, %i, %i, %i, %lli) = %p \"%c...", \
110                      start, (long int)length, prot, flags, fd, \
111                      (long long int)offset, ret, b[0]); \
112        } \
113        else \
114            debug(STR(fn)"(%p, %li, %i, %i, %i, %lli) = %p", \
115                  start, (long int)length, prot, flags, fd, \
116                  (long long int)offset, ret); \
117    } while(0)
118
119void *mmap(void *start, size_t length, int prot, int flags,
120           int fd, off_t offset)
121{
122    void *ret; MMAP(mmap, off_t); return ret;
123}
124
125#ifdef HAVE_MMAP64
126void *mmap64(void *start, size_t length, int prot, int flags,
127             int fd, off64_t offset)
128{
129    void *ret; MMAP(mmap64, off64_t); return ret;
130}
131#endif
132
133int munmap(void *start, size_t length)
134{
135    int ret, i;
136
137    if(!_zz_ready)
138        LOADSYM(munmap);
139    for(i = 0; i < nbmaps; i++)
140    {
141        if(maps[i] != start)
142            continue;
143
144        free(start);
145        ret = munmap_orig(maps[i + 1], length);
146        maps[i] = NULL;
147        maps[i + 1] = NULL;
148        debug("munmap(%p, %li) = %i", start, (long int)length, ret);
149        return ret;
150    }
151
152    return munmap_orig(start, length);
153}
154
155#ifdef HAVE_MAP_FD
156kern_return_t map_fd(int fd, vm_offset_t offset, vm_offset_t *addr,
157                     boolean_t find_space, vm_size_t numbytes)
158{
159    kern_return_t ret;
160
161    if(!_zz_ready)
162        LOADSYM(map_fd);
163    ret = map_fd_orig(fd, offset, addr, find_space, numbytes);
164    if(!_zz_ready || !_zz_iswatched(fd) || _zz_disabled)
165        return ret;
166
167    if(ret == 0 && numbytes)
168    {
169        /* FIXME: do we also have to rewind the filedescriptor like in mmap? */
170        void *b = malloc(numbytes);
171        memcpy(b, (void *)*addr, numbytes);
172        _zz_fuzz(fd, b, numbytes);
173        *addr = (vm_offset_t)b;
174        /* FIXME: the map is never freed; there is no such thing as unmap_fd,
175         * but I suppose that kind of map should go when the filedescriptor is
176         * closed (unlike mmap, which returns a persistent buffer). */
177
178        if(numbytes >= 4)
179           debug("map_fd(%i, %lli, &%p, %i, %lli) = %i \"%c%c%c%c", fd,
180                 (long long int)offset, (void *)*addr, (int)find_space,
181                 (long long int)numbytes, ret, b[0], b[1], b[2], b[3]);
182        else
183           debug("map_fd(%i, %lli, &%p, %i, %lli) = %i \"%c", fd,
184                 (long long int)offset, (void *)*addr, (int)find_space,
185                 (long long int)numbytes, ret, b[0]);
186    }
187    else
188        debug("map_fd(%i, %lli, &%p, %i, %lli) = %i", fd, (long long int)offset,
189              (void *)*addr, (int)find_space, (long long int)numbytes, ret);
190
191    return ret;
192}
193#endif
194
Note: See TracBrowser for help on using the repository browser.