204 lines
3.9 KiB
C
204 lines
3.9 KiB
C
/*
|
|
* zzuf - general purpose fuzzer
|
|
* Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
|
|
* 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.
|
|
*/
|
|
|
|
/*
|
|
* libzzuf.c: preloaded wrapper library
|
|
*/
|
|
|
|
#include "config.h"
|
|
#define _GNU_SOURCE
|
|
|
|
#if defined HAVE_STDINT_H
|
|
# include <stdint.h>
|
|
#elif defined HAVE_INTTYPES_H
|
|
# include <inttypes.h>
|
|
#endif
|
|
#include <stdlib.h>
|
|
#include <regex.h>
|
|
|
|
#include "libzzuf.h"
|
|
#include "fd.h"
|
|
|
|
/* Regex stuff */
|
|
static regex_t * re_include = NULL;
|
|
static regex_t * re_exclude = NULL;
|
|
|
|
/* File descriptor stuff */
|
|
static struct files
|
|
{
|
|
int managed;
|
|
uint64_t seed;
|
|
uint64_t pos;
|
|
/* Public stuff */
|
|
struct fuzz fuzz;
|
|
}
|
|
*files;
|
|
static int *fds;
|
|
static int maxfd, nfiles;
|
|
|
|
void _zz_include(char const *regex)
|
|
{
|
|
re_include = malloc(sizeof(*re_include));
|
|
|
|
if(regcomp(re_include, regex, REG_EXTENDED) != 0)
|
|
{
|
|
free(re_include);
|
|
re_include = NULL;
|
|
}
|
|
}
|
|
|
|
void _zz_exclude(char const *regex)
|
|
{
|
|
re_exclude = malloc(sizeof(*re_exclude));
|
|
|
|
if(regcomp(re_exclude, regex, REG_EXTENDED) != 0)
|
|
{
|
|
free(re_exclude);
|
|
re_exclude = NULL;
|
|
}
|
|
}
|
|
|
|
void _zz_fd_init(void)
|
|
{
|
|
files = NULL;
|
|
nfiles = 0;
|
|
|
|
/* Start with one fd in the lookup table */
|
|
fds = malloc(1 * sizeof(int));
|
|
for(maxfd = 0; maxfd < 1; maxfd++)
|
|
fds[maxfd] = -1;
|
|
}
|
|
|
|
void _zz_fd_fini(void)
|
|
{
|
|
int i;
|
|
|
|
for(i = 0; i < maxfd; i++)
|
|
{
|
|
if(!files[fds[i]].managed)
|
|
continue;
|
|
|
|
/* XXX: What are we supposed to do? If filedescriptors weren't
|
|
* closed properly, there's a leak, but it's not our problem. */
|
|
}
|
|
|
|
free(files);
|
|
free(fds);
|
|
}
|
|
|
|
int _zz_mustwatch(char const *file)
|
|
{
|
|
if(re_include && regexec(re_include, file, 0, NULL, 0) == REG_NOMATCH)
|
|
return 0; /* not included: ignore */
|
|
|
|
if(re_exclude && regexec(re_exclude, file, 0, NULL, 0) != REG_NOMATCH)
|
|
return 0; /* excluded: ignore */
|
|
|
|
return 1; /* default */
|
|
}
|
|
|
|
int _zz_iswatched(int fd)
|
|
{
|
|
if(fd < 0 || fd >= maxfd || fds[fd] == -1)
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
void _zz_register(int fd)
|
|
{
|
|
int i;
|
|
|
|
if(fd < 0 || fd > 65535 || (fd < maxfd && fds[fd] != -1))
|
|
return;
|
|
|
|
while(fd >= maxfd)
|
|
{
|
|
fds = realloc(fds, 2 * maxfd * sizeof(int));
|
|
for(i = maxfd; i < maxfd * 2; i++)
|
|
fds[i] = -1;
|
|
maxfd *= 2;
|
|
}
|
|
|
|
/* Find an empty slot */
|
|
for(i = 0; i < nfiles; i++)
|
|
if(files[i].managed == 0)
|
|
break;
|
|
|
|
/* No slot found, allocate memory */
|
|
if(i == nfiles)
|
|
{
|
|
nfiles++;
|
|
files = realloc(files, nfiles * sizeof(struct files));
|
|
}
|
|
|
|
files[i].managed = 1;
|
|
files[i].pos = 0;
|
|
files[i].fuzz.cur = -1;
|
|
files[i].fuzz.data = malloc(CHUNKBYTES);
|
|
#ifdef HAVE_FGETLN
|
|
files[i].fuzz.tmp = NULL;
|
|
#endif
|
|
|
|
fds[fd] = i;
|
|
}
|
|
|
|
void _zz_unregister(int fd)
|
|
{
|
|
if(fd < 0 || fd >= maxfd || fds[fd] == -1)
|
|
return;
|
|
|
|
files[fds[fd]].managed = 0;
|
|
free(files[fds[fd]].fuzz.data);
|
|
#ifdef HAVE_FGETLN
|
|
if(files[fds[fd]].fuzz.tmp)
|
|
free(files[fds[fd]].fuzz.tmp);
|
|
#endif
|
|
|
|
fds[fd] = -1;
|
|
}
|
|
|
|
long int _zz_getpos(int fd)
|
|
{
|
|
if(fd < 0 || fd >= maxfd || fds[fd] == -1)
|
|
return 0;
|
|
|
|
return files[fds[fd]].pos;
|
|
}
|
|
|
|
void _zz_setpos(int fd, long int pos)
|
|
{
|
|
if(fd < 0 || fd >= maxfd || fds[fd] == -1)
|
|
return;
|
|
|
|
files[fds[fd]].pos = pos;
|
|
}
|
|
|
|
void _zz_addpos(int fd, long int off)
|
|
{
|
|
if(fd < 0 || fd >= maxfd || fds[fd] == -1)
|
|
return;
|
|
|
|
files[fds[fd]].pos += off;
|
|
}
|
|
|
|
struct fuzz *_zz_getfuzz(int fd)
|
|
{
|
|
if(fd < 0 || fd >= maxfd || fds[fd] == -1)
|
|
return NULL;
|
|
|
|
return &files[fds[fd]].fuzz;
|
|
}
|
|
|