source: zzuf/trunk/src/libzzuf.c @ 1553

Revision 1553, 4.9 KB checked in by sam, 6 years ago (diff)
  • Added a _zz_disabled flag. This is needed on OS X where we protect the fopen_orig() call because it will call our own diverted open() function and we don't want it to fiddle with our structures.
  • Property svn:keywords set to Id
Line 
1/*
2 *  zzuf - general purpose fuzzer
3 *  Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id$
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 *  libzzuf.c: preloaded wrapper library
17 */
18
19#include "config.h"
20#define _GNU_SOURCE
21
22#if defined HAVE_STDINT_H
23#   include <stdint.h>
24#elif defined HAVE_INTTYPES_H
25#   include <inttypes.h>
26#endif
27#include <stdio.h>
28#include <unistd.h>
29#include <stdlib.h>
30#include <fcntl.h>
31#include <regex.h>
32
33#include <stdarg.h>
34#include <dlfcn.h>
35
36#include "libzzuf.h"
37#include "debug.h"
38#include "load.h"
39
40/* Global variables */
41int   _zz_ready    = 0;
42int   _zz_disabled = 0;
43int   _zz_hasdebug = 0;
44float _zz_ratio    = 0.004f;
45int   _zz_seed     = 0;
46int   _zz_signal   = 0;
47
48/* Local variables */
49static regex_t * re_include = NULL;
50static regex_t * re_exclude = NULL;
51
52/* Local prototypes */
53static void _zz_fd_init(void);
54static void _zz_fd_fini(void);
55
56/* Library initialisation shit */
57void _zz_init(void)
58{
59    char *tmp;
60
61    tmp = getenv("ZZUF_DEBUG");
62    if(tmp && *tmp == '1')
63        _zz_hasdebug = 1;
64
65    tmp = getenv("ZZUF_SEED");
66    if(tmp && *tmp)
67        _zz_seed = atol(tmp);
68
69    tmp = getenv("ZZUF_RATIO");
70    if(tmp && *tmp)
71        _zz_ratio = atof(tmp);
72    if(_zz_ratio < 0.0f)
73        _zz_ratio = 0.0f;
74    else if(_zz_ratio > 5.0f)
75        _zz_ratio = 5.0f;
76
77    tmp = getenv("ZZUF_INCLUDE");
78    if(tmp && *tmp)
79    {
80        re_include = malloc(sizeof(*re_include));
81        regcomp(re_include, tmp, REG_EXTENDED);
82    }
83
84    tmp = getenv("ZZUF_EXCLUDE");
85    if(tmp && *tmp)
86    {
87        re_exclude = malloc(sizeof(*re_exclude));
88        regcomp(re_exclude, tmp, REG_EXTENDED);
89    }
90
91    tmp = getenv("ZZUF_SIGNAL");
92    if(tmp && *tmp == '1')
93        _zz_signal = 1;
94
95    _zz_fd_init();
96
97    tmp = getenv("ZZUF_STDIN");
98    if(tmp && *tmp == '1')
99        _zz_register(0);
100
101    _zz_load_fd();
102    _zz_load_signal();
103    _zz_load_stream();
104
105    _zz_ready = 1;
106
107    debug("libzzuf initialised");
108}
109
110/* Deinitialisation */
111void _zz_fini(void)
112{
113    _zz_fd_fini();
114}
115
116/* File descriptor stuff */
117static struct files
118{
119    int managed;
120    uint64_t seed;
121    uint64_t pos;
122    /* Public stuff */
123    struct fuzz fuzz;
124}
125*files;
126static int *fds;
127static int maxfd, nfiles;
128
129static void _zz_fd_init(void)
130{
131    files = NULL;
132    nfiles = 0;
133
134    /* Start with one fd in the lookup table */
135    fds = malloc(1 * sizeof(int));
136    for(maxfd = 0; maxfd < 1; maxfd++)
137        fds[maxfd] = -1;
138}
139
140static void _zz_fd_fini(void)
141{
142    int i;
143
144    for(i = 0; i < maxfd; i++)
145    {
146        if(!files[fds[i]].managed)
147            continue;
148
149        /* XXX: What are we supposed to do? If filedescriptors weren't
150         * closed properly, there's a leak, but it's not our problem. */
151    }
152
153    free(files);
154    free(fds);
155}
156
157int _zz_mustwatch(char const *file)
158{
159    if(re_include && regexec(re_include, file, 0, NULL, 0) == REG_NOMATCH)
160        return 0; /* not included: ignore */
161
162    if(re_exclude && regexec(re_exclude, file, 0, NULL, 0) != REG_NOMATCH)
163        return 0; /* excluded: ignore */
164
165    return 1; /* default */
166}
167
168int _zz_iswatched(int fd)
169{
170    if(fd < 0 || fd >= maxfd || fds[fd] == -1)
171        return 0;
172
173    return 1;
174}
175
176void _zz_register(int fd)
177{
178    int i;
179
180    if(fd < 0 || fd > 65535 || (fd < maxfd && fds[fd] != -1))
181        return;
182
183    while(fd >= maxfd)
184    {
185        fds = realloc(fds, 2 * maxfd * sizeof(int));
186        for(i = maxfd; i < maxfd * 2; i++)
187            fds[i] = -1;
188        maxfd *= 2;
189    }
190           
191    /* Find an empty slot */
192    for(i = 0; i < nfiles; i++)
193        if(files[i].managed == 0)
194            break;
195
196    /* No slot found, allocate memory */
197    if(i == nfiles)
198    {
199        nfiles++;
200        files = realloc(files, nfiles * sizeof(struct files));
201    }
202
203    files[i].managed = 1;
204    files[i].pos = 0;
205    files[i].fuzz.cur = -1;
206    files[i].fuzz.data = malloc(CHUNKBYTES);
207
208    fds[fd] = i;
209}
210
211void _zz_unregister(int fd)
212{
213    if(fd < 0 || fd >= maxfd || fds[fd] == -1)
214        return;
215
216    files[fds[fd]].managed = 0;
217    free(files[fds[fd]].fuzz.data);
218
219    fds[fd] = -1;
220}
221
222long int _zz_getpos(int fd)
223{
224    if(fd < 0 || fd >= maxfd || fds[fd] == -1)
225        return 0;
226
227    return files[fds[fd]].pos;
228}
229
230void _zz_setpos(int fd, long int pos)
231{
232    if(fd < 0 || fd >= maxfd || fds[fd] == -1)
233        return;
234
235    files[fds[fd]].pos = pos;
236}
237
238void _zz_addpos(int fd, long int off)
239{
240    if(fd < 0 || fd >= maxfd || fds[fd] == -1)
241        return;
242
243    files[fds[fd]].pos += off;
244}
245
246struct fuzz *_zz_getfuzz(int fd)
247{
248    if(fd < 0 || fd >= maxfd || fds[fd] == -1)
249        return NULL;
250
251    return &files[fds[fd]].fuzz;
252}
253
Note: See TracBrowser for help on using the repository browser.