* Added enough autoconf checks and #ifdefs so that libzzuf builds on Win32.
zzuf itself doesn't build yet, though.
This commit is contained in:
11
configure.ac
11
configure.ac
@@ -14,8 +14,8 @@ AM_PROG_CC_C_O
|
||||
AC_PROG_CPP
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
AC_CHECK_HEADERS(inttypes.h stdint.h getopt.h libc.h malloc.h)
|
||||
AC_CHECK_FUNCS(open64 lseek64 mmap64 fopen64 fseeko _IO_getc getline getdelim __getdelim fgetln __srefill map_fd memalign posix_memalign)
|
||||
AC_CHECK_HEADERS(inttypes.h stdint.h getopt.h libc.h malloc.h dlfcn.h regex.h sys/socket.h sys/uio.h aio.h sys/mman.h sys/wait.h sys/resource.h)
|
||||
AC_CHECK_FUNCS(open64 lseek64 mmap64 fopen64 fseeko _IO_getc getline getdelim __getdelim fgetln __srefill map_fd memalign posix_memalign aio_read accept socket readv pread recv recvfrom recvmsg mmap valloc sigaction)
|
||||
AC_CHECK_TYPES(sighandler_t, [], [],
|
||||
[#define _GNU_SOURCE
|
||||
#include <signal.h>])
|
||||
@@ -25,6 +25,13 @@ AC_CHECK_TYPES(socklen_t, [], [],
|
||||
[#include <sys/types.h>
|
||||
#include <sys/socket.h>])
|
||||
|
||||
AC_MSG_CHECKING(for read() prototype)
|
||||
AC_TRY_COMPILE([#include <unistd.h>],
|
||||
[ssize_t read(int fd, void *buf, size_t count);],
|
||||
[AC_MSG_RESULT(ssize_t read(... size_t);)
|
||||
AC_DEFINE(READ_USES_SSIZE_T, 1, [Define to 1 if read() uses ssize_t.])],
|
||||
[AC_MSG_RESULT(int read(... unsigned int);)])
|
||||
|
||||
AC_CHECK_FUNCS(getopt_long,
|
||||
[AC_DEFINE(HAVE_GETOPT_LONG, 1, Define to 1 if you have the `getopt_long' function.)],
|
||||
[AC_CHECK_LIB(gnugetopt, getopt_long,
|
||||
|
||||
22
src/fd.c
22
src/fd.c
@@ -25,7 +25,9 @@
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <regex.h>
|
||||
#if defined HAVE_REGEX_H
|
||||
# include <regex.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
@@ -34,8 +36,10 @@
|
||||
#include "fd.h"
|
||||
|
||||
/* Regex stuff */
|
||||
#if defined HAVE_REGEX_H
|
||||
static regex_t re_include, re_exclude;
|
||||
static int has_include = 0, has_exclude = 0;
|
||||
#endif
|
||||
|
||||
/* File descriptor stuff. When program is launched, we use the static array of
|
||||
* 32 structures, which ought to be enough for most programs. If it happens
|
||||
@@ -66,14 +70,22 @@ static int autoinc = 0;
|
||||
|
||||
void _zz_include(char const *regex)
|
||||
{
|
||||
#if defined HAVE_REGEX_H
|
||||
if(regcomp(&re_include, regex, REG_EXTENDED) == 0)
|
||||
has_include = 1;
|
||||
#else
|
||||
(void)regex;
|
||||
#endif
|
||||
}
|
||||
|
||||
void _zz_exclude(char const *regex)
|
||||
{
|
||||
#if defined HAVE_REGEX_H
|
||||
if(regcomp(&re_exclude, regex, REG_EXTENDED) == 0)
|
||||
has_exclude = 1;
|
||||
#else
|
||||
(void)regex;
|
||||
#endif
|
||||
}
|
||||
|
||||
void _zz_setseed(int32_t s)
|
||||
@@ -161,11 +173,15 @@ void _zz_fd_fini(void)
|
||||
|
||||
int _zz_mustwatch(char const *file)
|
||||
{
|
||||
#if defined HAVE_REGEX_H
|
||||
if(has_include && regexec(&re_include, file, 0, NULL, 0) == REG_NOMATCH)
|
||||
return 0; /* not included: ignore */
|
||||
|
||||
if(has_exclude && regexec(&re_exclude, file, 0, NULL, 0) != REG_NOMATCH)
|
||||
return 0; /* excluded: ignore */
|
||||
#else
|
||||
(void)file;
|
||||
#endif
|
||||
|
||||
return 1; /* default */
|
||||
}
|
||||
@@ -229,7 +245,7 @@ void _zz_register(int fd)
|
||||
files[i].fuzz.seed = seed;
|
||||
files[i].fuzz.ratio = _zz_getratio();
|
||||
files[i].fuzz.cur = -1;
|
||||
#ifdef HAVE_FGETLN
|
||||
#if defined HAVE_FGETLN
|
||||
files[i].fuzz.tmp = NULL;
|
||||
#endif
|
||||
|
||||
@@ -245,7 +261,7 @@ void _zz_unregister(int fd)
|
||||
return;
|
||||
|
||||
files[fds[fd]].managed = 0;
|
||||
#ifdef HAVE_FGETLN
|
||||
#if defined HAVE_FGETLN
|
||||
if(files[fds[fd]].fuzz.tmp)
|
||||
free(files[fds[fd]].fuzz.tmp);
|
||||
#endif
|
||||
|
||||
70
src/lib-fd.c
70
src/lib-fd.c
@@ -33,15 +33,21 @@
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#if defined HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
#if defined HAVE_SYS_UIO_H
|
||||
# include <sys/uio.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <aio.h>
|
||||
#if defined HAVE_AIO_H
|
||||
# include <aio.h>
|
||||
#endif
|
||||
|
||||
#include "libzzuf.h"
|
||||
#include "lib-load.h"
|
||||
@@ -49,35 +55,57 @@
|
||||
#include "fuzz.h"
|
||||
#include "fd.h"
|
||||
|
||||
#ifdef HAVE_SOCKLEN_T
|
||||
#if defined HAVE_SOCKLEN_T
|
||||
# define SOCKLEN_T socklen_t
|
||||
#else
|
||||
# define SOCKLEN_T int
|
||||
#endif
|
||||
|
||||
/* Local prototypes */
|
||||
#if defined HAVE_READV || defined HAVE_RECVMSG
|
||||
static void fuzz_iovec (int fd, const struct iovec *iov, ssize_t ret);
|
||||
#endif
|
||||
static void offset_check (int fd);
|
||||
|
||||
/* Library functions that we divert */
|
||||
static int (*open_orig) (const char *file, int oflag, ...);
|
||||
#ifdef HAVE_OPEN64
|
||||
#if defined HAVE_OPEN64
|
||||
static int (*open64_orig) (const char *file, int oflag, ...);
|
||||
#endif
|
||||
#if defined HAVE_ACCEPT
|
||||
static int (*accept_orig) (int sockfd, struct sockaddr *addr,
|
||||
SOCKLEN_T *addrlen);
|
||||
#endif
|
||||
#if defined HAVE_SOCKET
|
||||
static int (*socket_orig) (int domain, int type, int protocol);
|
||||
#endif
|
||||
#if defined HAVE_RECV
|
||||
static int (*recv_orig) (int s, void *buf, size_t len, int flags);
|
||||
#endif
|
||||
#if defined HAVE_RECVFROM
|
||||
static int (*recvfrom_orig)(int s, void *buf, size_t len, int flags,
|
||||
struct sockaddr *from, SOCKLEN_T *fromlen);
|
||||
#endif
|
||||
#if defined HAVE_RECVMSG
|
||||
static int (*recvmsg_orig) (int s, struct msghdr *hdr, int flags);
|
||||
#endif
|
||||
#if defined READ_USES_SSIZE_T
|
||||
static ssize_t (*read_orig) (int fd, void *buf, size_t count);
|
||||
#else
|
||||
static int (*read_orig) (int fd, void *buf, unsigned int count);
|
||||
#endif
|
||||
#if defined HAVE_READV
|
||||
static ssize_t (*readv_orig) (int fd, const struct iovec *iov, int count);
|
||||
#endif
|
||||
#if defined HAVE_PREAD
|
||||
static ssize_t (*pread_orig) (int fd, void *buf, size_t count, off_t offset);
|
||||
#endif
|
||||
#if defined HAVE_AIO_READ
|
||||
static int (*aio_read_orig) (struct aiocb *aiocbp);
|
||||
static ssize_t (*aio_return_orig) (struct aiocb *aiocbp);
|
||||
#endif
|
||||
static off_t (*lseek_orig) (int fd, off_t offset, int whence);
|
||||
#ifdef HAVE_LSEEK64
|
||||
#if defined HAVE_LSEEK64
|
||||
static off64_t (*lseek64_orig) (int fd, off64_t offset, int whence);
|
||||
#endif
|
||||
static int (*close_orig) (int fd);
|
||||
@@ -119,13 +147,14 @@ int open(const char *file, int oflag, ...)
|
||||
int ret; OPEN(open); return ret;
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPEN64
|
||||
#if defined HAVE_OPEN64
|
||||
int open64(const char *file, int oflag, ...)
|
||||
{
|
||||
int ret; OPEN(open64); return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined HAVE_ACCEPT
|
||||
int accept(int sockfd, struct sockaddr *addr, SOCKLEN_T *addrlen)
|
||||
{
|
||||
int ret;
|
||||
@@ -143,7 +172,9 @@ int accept(int sockfd, struct sockaddr *addr, SOCKLEN_T *addrlen)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined HAVE_SOCKET
|
||||
int socket(int domain, int type, int protocol)
|
||||
{
|
||||
int ret;
|
||||
@@ -161,7 +192,9 @@ int socket(int domain, int type, int protocol)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined HAVE_RECV
|
||||
int recv(int s, void *buf, size_t len, int flags)
|
||||
{
|
||||
int ret;
|
||||
@@ -191,7 +224,9 @@ int recv(int s, void *buf, size_t len, int flags)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined HAVE_RECVFROM
|
||||
int recvfrom(int s, void *buf, size_t len, int flags,
|
||||
struct sockaddr *from, SOCKLEN_T *fromlen)
|
||||
{
|
||||
@@ -223,7 +258,9 @@ int recvfrom(int s, void *buf, size_t len, int flags,
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined HAVE_RECVMSG
|
||||
int recvmsg(int s, struct msghdr *hdr, int flags)
|
||||
{
|
||||
ssize_t ret;
|
||||
@@ -238,8 +275,13 @@ int recvmsg(int s, struct msghdr *hdr, int flags)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined READ_USES_SSIZE_T
|
||||
ssize_t read(int fd, void *buf, size_t count)
|
||||
#else
|
||||
int read(int fd, void *buf, unsigned int count)
|
||||
#endif
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -269,6 +311,7 @@ ssize_t read(int fd, void *buf, size_t count)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined HAVE_READV
|
||||
ssize_t readv(int fd, const struct iovec *iov, int count)
|
||||
{
|
||||
ssize_t ret;
|
||||
@@ -284,7 +327,9 @@ ssize_t readv(int fd, const struct iovec *iov, int count)
|
||||
offset_check(fd);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined HAVE_PREAD
|
||||
ssize_t pread(int fd, void *buf, size_t count, off_t offset)
|
||||
{
|
||||
int ret;
|
||||
@@ -317,6 +362,7 @@ ssize_t pread(int fd, void *buf, size_t count, off_t offset)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define LSEEK(fn, off_t) \
|
||||
do \
|
||||
@@ -338,7 +384,7 @@ off_t lseek(int fd, off_t offset, int whence)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LSEEK64
|
||||
#if defined HAVE_LSEEK64
|
||||
off64_t lseek64(int fd, off64_t offset, int whence)
|
||||
{
|
||||
off64_t ret;
|
||||
@@ -347,6 +393,7 @@ off64_t lseek64(int fd, off64_t offset, int whence)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined HAVE_AIO_READ
|
||||
int aio_read(struct aiocb *aiocbp)
|
||||
{
|
||||
int ret;
|
||||
@@ -393,6 +440,7 @@ ssize_t aio_return(struct aiocb *aiocbp)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
int close(int fd)
|
||||
{
|
||||
@@ -415,6 +463,7 @@ int close(int fd)
|
||||
|
||||
/* XXX: the following functions are local */
|
||||
|
||||
#if defined HAVE_READV || defined HAVE_RECVMSG
|
||||
static void fuzz_iovec(int fd, const struct iovec *iov, ssize_t ret)
|
||||
{
|
||||
/* NOTE: We assume that iov countains at least <ret> bytes. */
|
||||
@@ -433,11 +482,12 @@ static void fuzz_iovec(int fd, const struct iovec *iov, ssize_t ret)
|
||||
ret -= len;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void offset_check(int fd)
|
||||
{
|
||||
/* Sanity check, can be OK though (for instance with a character device) */
|
||||
#ifdef HAVE_LSEEK64
|
||||
#if defined HAVE_LSEEK64
|
||||
off64_t ret;
|
||||
LOADSYM(lseek64);
|
||||
ret = lseek64_orig(fd, 0, SEEK_CUR);
|
||||
|
||||
@@ -29,11 +29,21 @@
|
||||
#define STR(x) #x
|
||||
#define ORIG(x) x##_orig
|
||||
|
||||
#define LOADSYM(x) \
|
||||
do { \
|
||||
if(!ORIG(x)) \
|
||||
ORIG(x) = dlsym(RTLD_NEXT, STR(x)); \
|
||||
if(!ORIG(x)) \
|
||||
abort(); \
|
||||
} while(0)
|
||||
/* TODO: do the Win32 part */
|
||||
#ifdef HAVE_DLFCN_H
|
||||
# include <dlfcn.h>
|
||||
# define LOADSYM(x) \
|
||||
do { \
|
||||
if(!ORIG(x)) \
|
||||
ORIG(x) = dlsym(RTLD_NEXT, STR(x)); \
|
||||
if(!ORIG(x)) \
|
||||
abort(); \
|
||||
} while(0)
|
||||
#else
|
||||
# define LOADSYM(x) \
|
||||
do { \
|
||||
if(!ORIG(x)) \
|
||||
abort(); \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
@@ -42,7 +41,9 @@
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#if defined HAVE_SYS_MMAN_H
|
||||
# include <sys/mman.h>
|
||||
#endif
|
||||
#if defined HAVE_LIBC_H
|
||||
# include <libc.h>
|
||||
#endif
|
||||
@@ -53,30 +54,40 @@
|
||||
#include "fuzz.h"
|
||||
#include "fd.h"
|
||||
|
||||
#if !defined SIGKILL
|
||||
# define SIGKILL 9
|
||||
#endif
|
||||
|
||||
/* TODO: mremap, maybe brk/sbrk (haha) */
|
||||
|
||||
/* Library functions that we divert */
|
||||
static void * (*calloc_orig) (size_t nmemb, size_t size);
|
||||
static void * (*malloc_orig) (size_t size);
|
||||
static void (*free_orig) (void *ptr);
|
||||
#if defined HAVE_VALLOC
|
||||
static void * (*valloc_orig) (size_t size);
|
||||
#ifdef HAVE_MEMALIGN
|
||||
#endif
|
||||
#if defined HAVE_MEMALIGN
|
||||
static void * (*memalign_orig) (size_t boundary, size_t size);
|
||||
#endif
|
||||
#ifdef HAVE_POSIX_MEMALIGN
|
||||
#if defined HAVE_POSIX_MEMALIGN
|
||||
static int (*posix_memalign_orig) (void **memptr, size_t alignment,
|
||||
size_t size);
|
||||
#endif
|
||||
static void * (*realloc_orig) (void *ptr, size_t size);
|
||||
|
||||
#if defined HAVE_MMAP
|
||||
static void * (*mmap_orig) (void *start, size_t length, int prot,
|
||||
int flags, int fd, off_t offset);
|
||||
#ifdef HAVE_MMAP64
|
||||
#endif
|
||||
#if defined HAVE_MMAP64
|
||||
static void * (*mmap64_orig) (void *start, size_t length, int prot,
|
||||
int flags, int fd, off64_t offset);
|
||||
#endif
|
||||
#if defined HAVE_MUNMAP
|
||||
static int (*munmap_orig) (void *start, size_t length);
|
||||
#ifdef HAVE_MAP_FD
|
||||
#endif
|
||||
#if defined 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);
|
||||
@@ -147,6 +158,7 @@ void *realloc(void *ptr, size_t size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined HAVE_VALLOC
|
||||
void *valloc(size_t size)
|
||||
{
|
||||
void *ret;
|
||||
@@ -156,8 +168,9 @@ void *valloc(size_t size)
|
||||
raise(SIGKILL);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MEMALIGN
|
||||
#if defined HAVE_MEMALIGN
|
||||
void *memalign(size_t boundary, size_t size)
|
||||
{
|
||||
void *ret;
|
||||
@@ -169,7 +182,7 @@ void *memalign(size_t boundary, size_t size)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_POSIX_MEMALIGN
|
||||
#if defined HAVE_POSIX_MEMALIGN
|
||||
int posix_memalign(void **memptr, size_t alignment, size_t size)
|
||||
{
|
||||
int ret;
|
||||
@@ -226,13 +239,15 @@ int nbmaps = 0;
|
||||
(long long int)offset, ret); \
|
||||
} while(0)
|
||||
|
||||
#if defined HAVE_MMAP
|
||||
void *mmap(void *start, size_t length, int prot, int flags,
|
||||
int fd, off_t offset)
|
||||
{
|
||||
void *ret; MMAP(mmap, off_t); return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MMAP64
|
||||
#if defined HAVE_MMAP64
|
||||
void *mmap64(void *start, size_t length, int prot, int flags,
|
||||
int fd, off64_t offset)
|
||||
{
|
||||
@@ -240,6 +255,7 @@ void *mmap64(void *start, size_t length, int prot, int flags,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined HAVE_MUNMAP
|
||||
int munmap(void *start, size_t length)
|
||||
{
|
||||
int ret, i;
|
||||
@@ -260,8 +276,9 @@ int munmap(void *start, size_t length)
|
||||
|
||||
return munmap_orig(start, length);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MAP_FD
|
||||
#if defined 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)
|
||||
{
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
@@ -47,8 +46,10 @@
|
||||
|
||||
/* Library functions that we divert */
|
||||
static SIG_T (*signal_orig) (int signum, SIG_T handler);
|
||||
#if defined HAVE_SIGACTION
|
||||
static int (*sigaction_orig) (int signum, const struct sigaction *act,
|
||||
struct sigaction *oldact);
|
||||
#endif
|
||||
/* Local functions */
|
||||
static int isfatal(int signum);
|
||||
|
||||
@@ -59,22 +60,26 @@ static int isfatal(int signum)
|
||||
case SIGABRT:
|
||||
case SIGFPE:
|
||||
case SIGILL:
|
||||
#if defined SIGQUIT
|
||||
case SIGQUIT:
|
||||
#endif
|
||||
case SIGSEGV:
|
||||
#if defined SIGTRAP
|
||||
case SIGTRAP:
|
||||
#ifdef SIGSYS
|
||||
#endif
|
||||
#if defined SIGSYS
|
||||
case SIGSYS:
|
||||
#endif
|
||||
#ifdef SIGEMT
|
||||
#if defined SIGEMT
|
||||
case SIGEMT:
|
||||
#endif
|
||||
#ifdef SIGBUS
|
||||
#if defined SIGBUS
|
||||
case SIGBUS:
|
||||
#endif
|
||||
#ifdef SIGXCPU
|
||||
#if defined SIGXCPU
|
||||
case SIGXCPU:
|
||||
#endif
|
||||
#ifdef SIGXFSZ
|
||||
#if defined SIGXFSZ
|
||||
case SIGXFSZ:
|
||||
#endif
|
||||
return 1;
|
||||
@@ -99,6 +104,7 @@ SIG_T signal(int signum, SIG_T handler)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined HAVE_SIGACTION
|
||||
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
|
||||
{
|
||||
int ret;
|
||||
@@ -122,4 +128,5 @@ int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -26,11 +26,10 @@
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE___SREFILL
|
||||
#if defined HAVE___SREFILL
|
||||
# include <unistd.h> /* Needed for __srefill’s lseek() call */
|
||||
#endif
|
||||
|
||||
@@ -40,19 +39,19 @@
|
||||
#include "fuzz.h"
|
||||
#include "fd.h"
|
||||
|
||||
#ifdef HAVE___SREFILL
|
||||
#if defined HAVE___SREFILL
|
||||
int __srefill(FILE *fp);
|
||||
#endif
|
||||
|
||||
/* Library functions that we divert */
|
||||
static FILE * (*fopen_orig) (const char *path, const char *mode);
|
||||
#ifdef HAVE_FOPEN64
|
||||
#if defined HAVE_FOPEN64
|
||||
static FILE * (*fopen64_orig) (const char *path, const char *mode);
|
||||
#endif
|
||||
static FILE * (*freopen_orig) (const char *path, const char *mode,
|
||||
FILE *stream);
|
||||
static int (*fseek_orig) (FILE *stream, long offset, int whence);
|
||||
#ifdef HAVE_FSEEKO
|
||||
#if defined HAVE_FSEEKO
|
||||
static int (*fseeko_orig) (FILE *stream, off_t offset, int whence);
|
||||
#endif
|
||||
static void (*rewind_orig) (FILE *stream);
|
||||
@@ -60,7 +59,7 @@ static size_t (*fread_orig) (void *ptr, size_t size, size_t nmemb,
|
||||
FILE *stream);
|
||||
static int (*getc_orig) (FILE *stream);
|
||||
static int (*fgetc_orig) (FILE *stream);
|
||||
#ifdef HAVE__IO_GETC
|
||||
#if defined HAVE__IO_GETC
|
||||
static int (*_IO_getc_orig) (FILE *stream);
|
||||
#endif
|
||||
static char * (*fgets_orig) (char *s, int size, FILE *stream);
|
||||
@@ -68,23 +67,23 @@ static int (*ungetc_orig) (int c, FILE *stream);
|
||||
static int (*fclose_orig) (FILE *fp);
|
||||
|
||||
/* Additional GNUisms */
|
||||
#ifdef HAVE_GETLINE
|
||||
#if defined HAVE_GETLINE
|
||||
static ssize_t (*getline_orig) (char **lineptr, size_t *n, FILE *stream);
|
||||
#endif
|
||||
#ifdef HAVE_GETDELIM
|
||||
#if defined HAVE_GETDELIM
|
||||
static ssize_t (*getdelim_orig) (char **lineptr, size_t *n, int delim,
|
||||
FILE *stream);
|
||||
#endif
|
||||
#ifdef HAVE___GETDELIM
|
||||
#if defined HAVE___GETDELIM
|
||||
static ssize_t (*__getdelim_orig) (char **lineptr, size_t *n, int delim,
|
||||
FILE *stream);
|
||||
#endif
|
||||
|
||||
/* Additional BSDisms */
|
||||
#ifdef HAVE_FGETLN
|
||||
#if defined HAVE_FGETLN
|
||||
static char * (*fgetln_orig) (FILE *stream, size_t *len);
|
||||
#endif
|
||||
#ifdef HAVE___SREFILL
|
||||
#if defined HAVE___SREFILL
|
||||
int (*__srefill_orig) (FILE *fp);
|
||||
#endif
|
||||
|
||||
@@ -111,7 +110,7 @@ FILE *fopen(const char *path, const char *mode)
|
||||
FILE *ret; FOPEN(fopen); return ret;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FOPEN64
|
||||
#if defined HAVE_FOPEN64
|
||||
FILE *fopen64(const char *path, const char *mode)
|
||||
{
|
||||
FILE *ret; FOPEN(fopen64); return ret;
|
||||
@@ -191,7 +190,7 @@ int fseek(FILE *stream, long offset, int whence)
|
||||
int ret; FSEEK(fseek, ftell); return ret;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FSEEKO
|
||||
#if defined HAVE_FSEEKO
|
||||
int fseeko(FILE *stream, off_t offset, int whence)
|
||||
{
|
||||
int ret; FSEEK(fseeko, ftello); return ret;
|
||||
@@ -301,7 +300,7 @@ int fgetc(FILE *stream)
|
||||
int ret; FGETC(fgetc); return ret;
|
||||
}
|
||||
|
||||
#ifdef HAVE__IO_GETC
|
||||
#if defined HAVE__IO_GETC
|
||||
int _IO_getc(FILE *stream)
|
||||
{
|
||||
int ret; FGETC(_IO_getc); return ret;
|
||||
@@ -468,28 +467,28 @@ int fclose(FILE *fp)
|
||||
return ret; \
|
||||
} while(0)
|
||||
|
||||
#ifdef HAVE_GETLINE
|
||||
#if defined HAVE_GETLINE
|
||||
ssize_t getline(char **lineptr, size_t *n, FILE *stream)
|
||||
{
|
||||
ssize_t ret; GETDELIM(getline, '\n', 0); return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETDELIM
|
||||
#if defined HAVE_GETDELIM
|
||||
ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream)
|
||||
{
|
||||
ssize_t ret; GETDELIM(getdelim, delim, 1); return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE___GETDELIM
|
||||
#if defined HAVE___GETDELIM
|
||||
ssize_t __getdelim(char **lineptr, size_t *n, int delim, FILE *stream)
|
||||
{
|
||||
ssize_t ret; GETDELIM(__getdelim, delim, 1); return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FGETLN
|
||||
#if defined HAVE_FGETLN
|
||||
char *fgetln(FILE *stream, size_t *len)
|
||||
{
|
||||
char *ret;
|
||||
@@ -544,7 +543,7 @@ char *fgetln(FILE *stream, size_t *len)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE___SREFILL
|
||||
#if defined HAVE___SREFILL
|
||||
int __srefill(FILE *fp)
|
||||
{
|
||||
off_t newpos;
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "libzzuf.h"
|
||||
#include "debug.h"
|
||||
|
||||
84
src/zzuf.c
84
src/zzuf.c
@@ -23,19 +23,25 @@
|
||||
#elif defined HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
#if defined(HAVE_GETOPT_H)
|
||||
#if defined HAVE_GETOPT_H
|
||||
# include <getopt.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <regex.h>
|
||||
#if defined HAVE_REGEX_H
|
||||
# include <regex.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#if defined HAVE_SYS_WAIT_H
|
||||
# include <sys/wait.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#if defined HAVE_SYS_RESOURCE_H
|
||||
# include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#include "libzzuf.h"
|
||||
#include "opts.h"
|
||||
@@ -45,6 +51,10 @@
|
||||
#include "md5.h"
|
||||
#include "timer.h"
|
||||
|
||||
#if !defined SIGKILL
|
||||
# define SIGKILL 9
|
||||
#endif
|
||||
|
||||
static void loop_stdin(struct opts *opts);
|
||||
|
||||
static void spawn_children(struct opts *opts);
|
||||
@@ -52,11 +62,13 @@ static void clean_children(struct opts *opts);
|
||||
static void read_children(struct opts *opts);
|
||||
|
||||
static char const *sig2str(int);
|
||||
#if defined HAVE_REGEX_H
|
||||
static char *merge_regex(char *, char *);
|
||||
static char *merge_file(char *, char *);
|
||||
#endif
|
||||
static void set_environment(char const *);
|
||||
static void version(void);
|
||||
#if defined(HAVE_GETOPT_H)
|
||||
#if defined HAVE_GETOPT_H
|
||||
static void usage(void);
|
||||
#endif
|
||||
|
||||
@@ -74,18 +86,24 @@ static void usage(void);
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct opts _opts, *opts = &_opts;
|
||||
char *tmp, *include, *exclude;
|
||||
int i, cmdline = 0;
|
||||
|
||||
include = exclude = NULL;
|
||||
char *tmp;
|
||||
#if defined HAVE_REGEX_H
|
||||
char *include = NULL, *exclude = NULL;
|
||||
int cmdline = 0;
|
||||
#endif
|
||||
int i;
|
||||
|
||||
_zz_opts_init(opts);
|
||||
|
||||
#if defined(HAVE_GETOPT_H)
|
||||
#if defined HAVE_GETOPT_H
|
||||
for(;;)
|
||||
{
|
||||
# define OPTSTR "AB:cC:dD:E:F:iI:mM:nP:qr:R:s:ST:vxhV"
|
||||
# ifdef HAVE_GETOPT_LONG
|
||||
# if defined HAVE_REGEX_H
|
||||
# define OPTSTR "AB:cC:dD:E:F:iI:mM:nP:qr:R:s:ST:vxhV"
|
||||
# else
|
||||
# define OPTSTR "AB:C:dD:F:imM:nP:qr:R:s:ST:vxhV"
|
||||
# endif
|
||||
# if defined HAVE_GETOPT_LONG
|
||||
# define MOREINFO "Try `%s --help' for more information.\n"
|
||||
int option_index = 0;
|
||||
static struct option long_options[] =
|
||||
@@ -93,14 +111,20 @@ int main(int argc, char *argv[])
|
||||
/* Long option, needs arg, flag, short option */
|
||||
{ "autoinc", 0, NULL, 'A' },
|
||||
{ "max-bytes", 1, NULL, 'B' },
|
||||
#if defined HAVE_REGEX_H
|
||||
{ "cmdline", 0, NULL, 'c' },
|
||||
#endif
|
||||
{ "max-crashes", 1, NULL, 'C' },
|
||||
{ "debug", 0, NULL, 'd' },
|
||||
{ "delay", 1, NULL, 'D' },
|
||||
#if defined HAVE_REGEX_H
|
||||
{ "exclude", 1, NULL, 'E' },
|
||||
#endif
|
||||
{ "max-forks", 1, NULL, 'F' },
|
||||
{ "stdin", 0, NULL, 'i' },
|
||||
#if defined HAVE_REGEX_H
|
||||
{ "include", 1, NULL, 'I' },
|
||||
#endif
|
||||
{ "md5", 0, NULL, 'm' },
|
||||
{ "max-memory", 1, NULL, 'M' },
|
||||
{ "network", 0, NULL, 'n' },
|
||||
@@ -133,9 +157,11 @@ int main(int argc, char *argv[])
|
||||
case 'B': /* --max-bytes */
|
||||
opts->maxbytes = atoi(optarg);
|
||||
break;
|
||||
#if defined HAVE_REGEX_H
|
||||
case 'c': /* --cmdline */
|
||||
cmdline = 1;
|
||||
break;
|
||||
#endif
|
||||
case 'C': /* --max-crashes */
|
||||
opts->maxcrashes = atoi(optarg);
|
||||
if(opts->maxcrashes <= 0)
|
||||
@@ -147,6 +173,7 @@ int main(int argc, char *argv[])
|
||||
case 'D': /* --delay */
|
||||
opts->delay = (int64_t)(atof(optarg) * 1000000.0);
|
||||
break;
|
||||
#if defined HAVE_REGEX_H
|
||||
case 'E': /* --exclude */
|
||||
exclude = merge_regex(exclude, optarg);
|
||||
if(!exclude)
|
||||
@@ -156,12 +183,14 @@ int main(int argc, char *argv[])
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case 'F': /* --max-forks */
|
||||
opts->maxchild = atoi(optarg) > 1 ? atoi(optarg) : 1;
|
||||
break;
|
||||
case 'i': /* --stdin */
|
||||
setenv("ZZUF_STDIN", "1", 1);
|
||||
break;
|
||||
#if defined HAVE_REGEX_H
|
||||
case 'I': /* --include */
|
||||
include = merge_regex(include, optarg);
|
||||
if(!include)
|
||||
@@ -171,6 +200,7 @@ int main(int argc, char *argv[])
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case 'm': /* --md5 */
|
||||
opts->md5 = 1;
|
||||
break;
|
||||
@@ -254,6 +284,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* If asked to launch programs */
|
||||
#if defined HAVE_REGEX_H
|
||||
if(cmdline)
|
||||
{
|
||||
int dashdash = 0;
|
||||
@@ -273,6 +304,8 @@ int main(int argc, char *argv[])
|
||||
setenv("ZZUF_INCLUDE", include, 1);
|
||||
if(exclude)
|
||||
setenv("ZZUF_EXCLUDE", exclude, 1);
|
||||
#endif
|
||||
|
||||
if(opts->protect)
|
||||
setenv("ZZUF_PROTECT", opts->protect, 1);
|
||||
if(opts->refuse)
|
||||
@@ -370,6 +403,7 @@ static void loop_stdin(struct opts *opts)
|
||||
_zz_fd_fini();
|
||||
}
|
||||
|
||||
#if defined HAVE_REGEX_H
|
||||
static char *merge_file(char *regex, char *file)
|
||||
{
|
||||
char *newfile = malloc(5 + 2 * strlen(file) + 1 + 1), *tmp = newfile;
|
||||
@@ -417,6 +451,7 @@ static char *merge_regex(char *regex, char *string)
|
||||
|
||||
return regex;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void spawn_children(struct opts *opts)
|
||||
{
|
||||
@@ -769,14 +804,21 @@ static void version(void)
|
||||
printf("Written by Sam Hocevar. Report bugs to <sam@zoy.org>.\n");
|
||||
}
|
||||
|
||||
#if defined(HAVE_GETOPT_H)
|
||||
#if defined HAVE_GETOPT_H
|
||||
static void usage(void)
|
||||
{
|
||||
#if defined HAVE_REGEX_H
|
||||
printf("Usage: zzuf [-AcdimnqSvx] [-r ratio] [-s seed | -s start:stop]\n");
|
||||
printf(" [-D delay] [-F forks] [-C crashes] [-B bytes]\n");
|
||||
printf(" [-T seconds] [-M bytes] [-P protect] [-R refuse]\n");
|
||||
printf(" [-I include] [-E exclude] [PROGRAM [--] [ARGS]...]\n");
|
||||
# ifdef HAVE_GETOPT_LONG
|
||||
#else
|
||||
printf("Usage: zzuf [-AdimnqSvx] [-r ratio] [-s seed | -s start:stop]\n");
|
||||
printf(" [-D delay] [-F forks] [-C crashes] [-B bytes]\n");
|
||||
printf(" [-T seconds] [-M bytes] [-P protect] [-R refuse]\n");
|
||||
printf(" [PROGRAM [--] [ARGS]...]\n");
|
||||
#endif
|
||||
# if defined HAVE_GETOPT_LONG
|
||||
printf(" zzuf -h | --help\n");
|
||||
printf(" zzuf -V | --version\n");
|
||||
# else
|
||||
@@ -786,17 +828,23 @@ static void usage(void)
|
||||
printf("Run PROGRAM with optional arguments ARGS and fuzz its input.\n");
|
||||
printf("\n");
|
||||
printf("Mandatory arguments to long options are mandatory for short options too.\n");
|
||||
# ifdef HAVE_GETOPT_LONG
|
||||
# if defined HAVE_GETOPT_LONG
|
||||
printf(" -A, --autoinc increment seed each time a new file is opened\n");
|
||||
printf(" -B, --max-bytes <n> kill children that output more than <n> bytes\n");
|
||||
#if defined HAVE_REGEX_H
|
||||
printf(" -c, --cmdline only fuzz files specified in the command line\n");
|
||||
#endif
|
||||
printf(" -C, --max-crashes <n> stop after <n> children have crashed (default 1)\n");
|
||||
printf(" -d, --debug print debug messages\n");
|
||||
printf(" -D, --delay delay between forks\n");
|
||||
#if defined HAVE_REGEX_H
|
||||
printf(" -E, --exclude <regex> do not fuzz files matching <regex>\n");
|
||||
#endif
|
||||
printf(" -F, --max-forks <n> number of concurrent children (default 1)\n");
|
||||
printf(" -i, --stdin fuzz standard input\n");
|
||||
#if defined HAVE_REGEX_H
|
||||
printf(" -I, --include <regex> only fuzz files matching <regex>\n");
|
||||
#endif
|
||||
printf(" -m, --md5 compute the output's MD5 hash\n");
|
||||
printf(" -M, --max-memory <n> maximum child virtual memory size in MB\n");
|
||||
printf(" -n, --network fuzz network input\n");
|
||||
@@ -816,14 +864,20 @@ static void usage(void)
|
||||
# else
|
||||
printf(" -A increment seed each time a new file is opened\n");
|
||||
printf(" -B <n> kill children that output more than <n> bytes\n");
|
||||
#if defined HAVE_REGEX_H
|
||||
printf(" -c only fuzz files specified in the command line\n");
|
||||
#endif
|
||||
printf(" -C <n> stop after <n> children have crashed (default 1)\n");
|
||||
printf(" -d print debug messages\n");
|
||||
printf(" -D delay between forks\n");
|
||||
#if defined HAVE_REGEX_H
|
||||
printf(" -E <regex> do not fuzz files matching <regex>\n");
|
||||
#endif
|
||||
printf(" -F <n> number of concurrent forks (default 1)\n");
|
||||
printf(" -i fuzz standard input\n");
|
||||
#if defined HAVE_REGEX_H
|
||||
printf(" -I <regex> only fuzz files matching <regex>\n");
|
||||
#endif
|
||||
printf(" -m compute the output's MD5 hash\n");
|
||||
printf(" -M maximum child virtual memory size in MB\n");
|
||||
printf(" -n fuzz network input\n");
|
||||
|
||||
Reference in New Issue
Block a user