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

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