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

Last change on this file since 1522 was 1522, checked in by Sam Hocevar, 14 years ago
  • Fixed a partial read data loss bug in the fread implementation.
  • Cosmetic fixes.
  • Property svn:keywords set to Id
File size: 4.4 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 1522 2006-12-28 17:48:05Z 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                zfd_manage(ret); \
100            } \
101        } \
102    } while(0)
103
104int open(const char *file, int oflag, ...)
105{
106    int ret; OPEN(open); return ret;
107}
108
109int open64(const char *file, int oflag, ...)
110{
111    int ret; OPEN(open64); return ret;
112}
113
114ssize_t read(int fd, void *buf, size_t count)
115{
116    int ret;
117
118    if(!_zzuf_ready)
119        LOADSYM(read);
120    ret = read_orig(fd, buf, count);
121    if(!_zzuf_ready || !zfd_ismanaged(fd))
122        return ret;
123
124    debug("read(%i, %p, %li) = %i", fd, buf, (long int)count, ret);
125    if(ret > 0)
126    {
127        zzuf_fuzz(fd, buf, ret);
128        zfd_addpos(fd, ret);
129    }
130
131    /* Sanity check, can be OK though (for instance with a character device) */
132    if(lseek64_orig(fd, 0, SEEK_CUR) != zfd_getpos(fd))
133        debug("warning: offset inconsistency");
134
135    return ret;
136}
137
138#define LSEEK(fn, off_t) \
139    do { \
140        if(!_zzuf_ready) \
141            LOADSYM(fn); \
142        ret = ORIG(fn)(fd, offset, whence); \
143        if(!_zzuf_ready || !zfd_ismanaged(fd)) \
144            return ret; \
145        debug(STR(fn)"(%i, %lli, %i) = %lli", \
146              fd, (long long int)offset, whence, (long long int)ret); \
147        if(ret != (off_t)-1) \
148            zfd_setpos(fd, ret); \
149    } while(0)
150
151off_t lseek(int fd, off_t offset, int whence)
152{
153    off_t ret;
154    LSEEK(lseek, off_t);
155    return ret;
156}
157
158off64_t lseek64(int fd, off64_t offset, int whence)
159{
160    off64_t ret;
161    LSEEK(lseek64, off64_t);
162    return ret;
163}
164
165int close(int fd)
166{
167    int ret;
168
169    if(!_zzuf_ready)
170        LOADSYM(close);
171    ret = close_orig(fd);
172    if(!_zzuf_ready || !zfd_ismanaged(fd))
173        return ret;
174
175    debug("close(%i) = %i", fd, ret);
176    zfd_unmanage(fd);
177
178    return ret;
179}
180
Note: See TracBrowser for help on using the repository browser.