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

Last change on this file since 1494 was 1494, checked in by Sam Hocevar, 16 years ago
  • Split preload.c into load-fd.c and load-stream.c.
  • Property svn:keywords set to Id
File size: 4.5 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 1494 2006-12-17 17:17:31Z 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 <regex.h>
33#include <dlfcn.h>
34
35#include <sys/types.h>
36#include <unistd.h>
37#include <fcntl.h>
38#include <stdarg.h>
39
40#include "libzzuf.h"
41#include "debug.h"
42#include "fuzz.h"
43#include "load.h"
44
45/* Library functions that we divert */
46static int     (*open_orig)    (const char *file, int oflag, ...);
47static int     (*open64_orig)  (const char *file, int oflag, ...);
48static ssize_t (*read_orig)    (int fd, void *buf, size_t count);
49static off_t   (*lseek_orig)   (int fd, off_t offset, int whence);
50static off64_t (*lseek64_orig) (int fd, off64_t offset, int whence);
51static int     (*close_orig)   (int fd);
52
53void zzuf_load_fd(void)
54{
55    LOADSYM(open);
56    LOADSYM(open64);
57    LOADSYM(read);
58    LOADSYM(lseek);
59    LOADSYM(lseek64);
60    LOADSYM(close);
61}
62
63#define OPEN(fn) \
64    do \
65    { \
66        int mode = 0; \
67        if(!_zzuf_ready) \
68            LOADSYM(fn); \
69        if(oflag & O_CREAT) \
70        { \
71            va_list va; \
72            va_start(va, oflag); \
73            mode = va_arg(va, int); \
74            va_end(va); \
75            ret = ORIG(fn)(file, oflag, mode); \
76        } \
77        else \
78        { \
79            ret = ORIG(fn)(file, oflag); \
80        } \
81        if(!_zzuf_ready) \
82            return ret; \
83        if(ret >= 0 \
84            && ((oflag & (O_RDONLY | O_RDWR | O_WRONLY)) != O_WRONLY)) \
85        { \
86            if(_zzuf_include && \
87                regexec(_zzuf_include, file, 0, NULL, 0) == REG_NOMATCH) \
88                /* not included: ignore */ ; \
89            else if(_zzuf_exclude && \
90                    regexec(_zzuf_exclude, file, 0, NULL, 0) != REG_NOMATCH) \
91                /* excluded: ignore */ ; \
92            else \
93            { \
94                if(oflag & O_CREAT) \
95                    debug(STR(fn) "(\"%s\", %i, %i) = %i", \
96                          file, oflag, mode, ret); \
97                else \
98                    debug(STR(fn) "(\"%s\", %i) = %i", file, oflag, ret); \
99                files[ret].managed = 1; \
100                files[ret].pos = 0; \
101            } \
102        } \
103    } while(0)
104
105int open(const char *file, int oflag, ...)
106{
107    int ret; OPEN(open); return ret;
108}
109
110int open64(const char *file, int oflag, ...)
111{
112    int ret; OPEN(open64); return ret;
113}
114
115ssize_t read(int fd, void *buf, size_t count)
116{
117    int ret;
118
119    if(!_zzuf_ready)
120        LOADSYM(read);
121    ret = read_orig(fd, buf, count);
122    if(!_zzuf_ready)
123        return ret;
124
125    if(!files[fd].managed)
126        return ret;
127
128    debug("read(%i, %p, %li) = %i", fd, buf, (long int)count, ret);
129    if(ret > 0)
130    {
131        zzuf_fuzz(fd, buf, ret);
132        files[fd].pos += ret;
133    }
134
135    /* Sanity check, can be OK though (for instance with a character device) */
136    if((uint64_t)lseek64_orig(fd, 0, SEEK_CUR) != files[fd].pos)
137        debug("warning: offset inconsistency");
138
139    return ret;
140}
141
142#define LSEEK(fn, off_t) \
143    do { \
144        if(!_zzuf_ready) \
145            LOADSYM(fn); \
146        ret = ORIG(fn)(fd, offset, whence); \
147        if(!_zzuf_ready) \
148            return ret; \
149        if(!files[fd].managed) \
150            return ret; \
151        debug(STR(fn)"(%i, %lli, %i) = %lli", \
152              fd, (long long int)offset, whence, (long long int)ret); \
153        if(ret != (off_t)-1) \
154            files[fd].pos = (int64_t)ret; \
155    } while(0)
156
157off_t lseek(int fd, off_t offset, int whence)
158{
159    off_t ret;
160    LSEEK(lseek, off_t);
161    return ret;
162}
163
164off64_t lseek64(int fd, off64_t offset, int whence)
165{
166    off64_t ret;
167    LSEEK(lseek64, off64_t);
168    return ret;
169}
170
171int close(int fd)
172{
173    int ret;
174
175    if(!_zzuf_ready)
176        LOADSYM(close);
177    ret = close_orig(fd);
178    if(!_zzuf_ready)
179        return ret;
180
181    if(!files[fd].managed)
182        return ret;
183
184    debug("close(%i) = %i", fd, ret);
185    files[fd].managed = 0;
186
187    return ret;
188}
189
Note: See TracBrowser for help on using the repository browser.