diff --git a/AUTHORS b/AUTHORS index 02b02a9..6f8a56b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -5,4 +5,5 @@ main zzuf author: other contributors: Rémi Denis-Courmont (readv support) + Clément Stenac (pread support) diff --git a/doc/zzuf.1 b/doc/zzuf.1 index 1a30dbd..7b53fe2 100644 --- a/doc/zzuf.1 +++ b/doc/zzuf.1 @@ -317,8 +317,8 @@ allocations, \fBzzuf\fR diverts and reimplements the following functions, which can be private libc symbols, too: .TP Unix file descriptor handling: -\fBopen\fR(), \fBlseek\fR(), \fBread\fR(), \freadv\fR(), \fBaccept\fR(), -\fBsocket\fR(), \fBclose\fR() +\fBopen\fR(), \fBlseek\fR(), \fBread\fR(), \fBreadv\fR(), \fBpread\fR(), +\fBaccept\fR(), \fBsocket\fR(), \fBclose\fR() .TP Standard IO streams: \fBfopen\fR(), \fBfreopen\fR(), \fBfseek\fR(), \fBfseeko\fR(), \fBrewind\fR(), diff --git a/src/load-fd.c b/src/load-fd.c index 74faf78..3ee743d 100644 --- a/src/load-fd.c +++ b/src/load-fd.c @@ -2,6 +2,7 @@ * zzuf - general purpose fuzzer * Copyright (c) 2006, 2007 Sam Hocevar * 2007 Rémi Denis-Courmont + * 2007 Clément Stenac * All Rights Reserved * * $Id$ @@ -62,6 +63,7 @@ static int (*accept_orig) (int sockfd, struct sockaddr *addr, static int (*socket_orig) (int domain, int type, int protocol); static ssize_t (*read_orig) (int fd, void *buf, size_t count); static ssize_t (*readv_orig) (int fd, const struct iovec *iov, int count); +static ssize_t (*pread_orig) (int fd, void *buf, size_t count, off_t offset); static off_t (*lseek_orig) (int fd, off_t offset, int whence); #ifdef HAVE_LSEEK64 static off64_t (*lseek64_orig) (int fd, off64_t offset, int whence); @@ -78,6 +80,8 @@ void _zz_load_fd(void) LOADSYM(accept); LOADSYM(socket); LOADSYM(read); + LOADSYM(readv); + LOADSYM(pread); LOADSYM(lseek); #ifdef HAVE_LSEEK64 LOADSYM(lseek64); @@ -237,6 +241,39 @@ ssize_t readv(int fd, const struct iovec *iov, int count) return ret; } +ssize_t pread(int fd, void *buf, size_t count, off_t offset) +{ + int ret; + + LOADSYM(pread); + ret = pread_orig(fd, buf, count, offset); + if(!_zz_ready || !_zz_iswatched(fd) || _zz_disabled) + return ret; + + if(ret > 0) + { + long int curoff = _zz_getpos(fd); + char *b = buf; + + _zz_setpos(fd, offset); + _zz_fuzz(fd, buf, ret); + _zz_setpos(fd, curoff); + + if(ret >= 4) + debug("pread(%i, %p, %li, %li) = %i \"%c%c%c%c...", fd, buf, + (long int)count, (long int)offset, ret, + b[0], b[1], b[2], b[3]); + else + debug("pread(%i, %p, %li, %li) = %i \"%c...", fd, buf, + (long int)count, (long int)offset, ret, b[0]); + } + else + debug("pread(%i, %p, %li, %li) = %i", fd, buf, + (long int)count, (long int)offset, ret); + + return ret; +} + #define LSEEK(fn, off_t) \ do \ { \