source: zzuf/trunk/src/load-fd.c @ 1532

Last change on this file since 1532 was 1527, checked in by Sam Hocevar, 16 years ago
  • Factored regex matching stuff.
  • Property svn:keywords set to Id
File size: 4.0 KB
Line 
1/*
2 *  zzuf - general purpose fuzzer
3 *  Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id: load-fd.c 1527 2006-12-29 17:49:11Z 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 *  load-fd.c: loaded file descriptor functions
17 */
18
19#include "config.h"
20
21/* Can't remember what that's for */
22#define _GNU_SOURCE
23/* Use this to get lseek64() */
24#define _LARGEFILE64_SOURCE
25
26#if defined HAVE_STDINT_H
27#   include <stdint.h>
28#elif defined HAVE_INTTYPES_H
29#   include <inttypes.h>
30#endif
31#include <stdlib.h>
32#include <dlfcn.h>
33
34#include <sys/types.h>
35#include <unistd.h>
36#include <fcntl.h>
37#include <stdarg.h>
38
39#include "libzzuf.h"
40#include "debug.h"
41#include "fuzz.h"
42#include "load.h"
43
44/* Library functions that we divert */
45static int     (*open_orig)    (const char *file, int oflag, ...);
46static int     (*open64_orig)  (const char *file, int oflag, ...);
47static ssize_t (*read_orig)    (int fd, void *buf, size_t count);
48static off_t   (*lseek_orig)   (int fd, off_t offset, int whence);
49static off64_t (*lseek64_orig) (int fd, off64_t offset, int whence);
50static int     (*close_orig)   (int fd);
51
52void _zz_load_fd(void)
53{
54    LOADSYM(open);
55    LOADSYM(open64);
56    LOADSYM(read);
57    LOADSYM(lseek);
58    LOADSYM(lseek64);
59    LOADSYM(close);
60}
61
62#define OPEN(fn) \
63    do \
64    { \
65        int mode = 0; \
66        if(!_zz_ready) \
67            LOADSYM(fn); \
68        if(oflag & O_CREAT) \
69        { \
70            va_list va; \
71            va_start(va, oflag); \
72            mode = va_arg(va, int); \
73            va_end(va); \
74            ret = ORIG(fn)(file, oflag, mode); \
75        } \
76        else \
77        { \
78            ret = ORIG(fn)(file, oflag); \
79        } \
80        if(!_zz_ready) \
81            return ret; \
82        if(ret >= 0 \
83            && ((oflag & (O_RDONLY | O_RDWR | O_WRONLY)) != O_WRONLY) \
84            && _zz_mustwatch(file)) \
85        { \
86            if(oflag & O_CREAT) \
87                debug(STR(fn) "(\"%s\", %i, %i) = %i", \
88                      file, oflag, mode, ret); \
89            else \
90                debug(STR(fn) "(\"%s\", %i) = %i", file, oflag, ret); \
91            _zz_register(ret); \
92        } \
93    } while(0)
94
95int open(const char *file, int oflag, ...)
96{
97    int ret; OPEN(open); return ret;
98}
99
100int open64(const char *file, int oflag, ...)
101{
102    int ret; OPEN(open64); return ret;
103}
104
105ssize_t read(int fd, void *buf, size_t count)
106{
107    int ret;
108
109    if(!_zz_ready)
110        LOADSYM(read);
111    ret = read_orig(fd, buf, count);
112    if(!_zz_ready || !_zz_iswatched(fd))
113        return ret;
114
115    debug("read(%i, %p, %li) = %i", fd, buf, (long int)count, ret);
116    if(ret > 0)
117    {
118        _zz_fuzz(fd, buf, ret);
119        _zz_addpos(fd, ret);
120    }
121
122    /* Sanity check, can be OK though (for instance with a character device) */
123    if(lseek64_orig(fd, 0, SEEK_CUR) != _zz_getpos(fd))
124        debug("warning: offset inconsistency");
125
126    return ret;
127}
128
129#define LSEEK(fn, off_t) \
130    do { \
131        if(!_zz_ready) \
132            LOADSYM(fn); \
133        ret = ORIG(fn)(fd, offset, whence); \
134        if(!_zz_ready || !_zz_iswatched(fd)) \
135            return ret; \
136        debug(STR(fn)"(%i, %lli, %i) = %lli", \
137              fd, (long long int)offset, whence, (long long int)ret); \
138        if(ret != (off_t)-1) \
139            _zz_setpos(fd, ret); \
140    } while(0)
141
142off_t lseek(int fd, off_t offset, int whence)
143{
144    off_t ret;
145    LSEEK(lseek, off_t);
146    return ret;
147}
148
149off64_t lseek64(int fd, off64_t offset, int whence)
150{
151    off64_t ret;
152    LSEEK(lseek64, off64_t);
153    return ret;
154}
155
156int close(int fd)
157{
158    int ret;
159
160    if(!_zz_ready)
161        LOADSYM(close);
162    ret = close_orig(fd);
163    if(!_zz_ready || !_zz_iswatched(fd))
164        return ret;
165
166    debug("close(%i) = %i", fd, ret);
167    _zz_unregister(fd);
168
169    return ret;
170}
171
Note: See TracBrowser for help on using the repository browser.