* Hide struct zzuf behind public functions. No real abstraction yet.
This commit is contained in:
27
src/fuzz.c
27
src/fuzz.c
@@ -38,21 +38,25 @@
|
||||
void zzuf_fuzz(int fd, uint8_t *buf, uint64_t len)
|
||||
{
|
||||
uint64_t start, stop;
|
||||
struct fuzz *fuzz;
|
||||
uint8_t *aligned_buf;
|
||||
unsigned long int pos = zzuf_fd_getpos(fd);
|
||||
unsigned int i, j, todo;
|
||||
|
||||
aligned_buf = buf - files[fd].pos;
|
||||
fuzz = zzuf_fd_getfuzz(fd);
|
||||
|
||||
for(i = files[fd].pos / CHUNKBYTES;
|
||||
i < (files[fd].pos + len + CHUNKBYTES - 1) / CHUNKBYTES;
|
||||
aligned_buf = buf - pos;
|
||||
|
||||
for(i = pos / CHUNKBYTES;
|
||||
i < (pos + len + CHUNKBYTES - 1) / CHUNKBYTES;
|
||||
i++)
|
||||
{
|
||||
/* Cache bitmask array */
|
||||
if(files[fd].cur != (int)i)
|
||||
if(fuzz->cur != (int)i)
|
||||
{
|
||||
uint32_t chunkseed = i * MAGIC1;
|
||||
|
||||
memset(files[fd].data, 0, CHUNKBYTES);
|
||||
memset(fuzz->data, 0, CHUNKBYTES);
|
||||
|
||||
/* Add some random dithering to handle ratio < 1.0/CHUNKBYTES */
|
||||
zzuf_srand(_zzuf_seed ^ chunkseed);
|
||||
@@ -65,21 +69,20 @@ void zzuf_fuzz(int fd, uint8_t *buf, uint64_t len)
|
||||
unsigned int idx = zzuf_rand(CHUNKBYTES);
|
||||
uint8_t byte = (1 << zzuf_rand(8));
|
||||
|
||||
files[fd].data[idx] ^= byte;
|
||||
fuzz->data[idx] ^= byte;
|
||||
}
|
||||
|
||||
files[fd].cur = i;
|
||||
fuzz->cur = i;
|
||||
}
|
||||
|
||||
/* Apply our bitmask array to the buffer */
|
||||
start = (i * CHUNKBYTES > files[fd].pos)
|
||||
? i * CHUNKBYTES : files[fd].pos;
|
||||
start = (i * CHUNKBYTES > pos) ? i * CHUNKBYTES : pos;
|
||||
|
||||
stop = ((i + 1) * CHUNKBYTES < files[fd].pos + len)
|
||||
? (i + 1) * CHUNKBYTES : files[fd].pos + len;
|
||||
stop = ((i + 1) * CHUNKBYTES < pos + len)
|
||||
? (i + 1) * CHUNKBYTES : pos + len;
|
||||
|
||||
for(j = start; j < stop; j++)
|
||||
aligned_buf[j] ^= files[fd].data[j % CHUNKBYTES];
|
||||
aligned_buf[j] ^= fuzz->data[j % CHUNKBYTES];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,13 @@ regex_t * _zzuf_include = NULL;
|
||||
regex_t * _zzuf_exclude = NULL;
|
||||
|
||||
#define MAXFD 1024
|
||||
struct zzuf files[MAXFD];
|
||||
struct zzuf
|
||||
{
|
||||
int managed;
|
||||
uint64_t seed;
|
||||
uint64_t pos;
|
||||
struct fuzz fuzz;
|
||||
} files[MAXFD];
|
||||
|
||||
/* Library initialisation shit */
|
||||
void zzuf_init(void)
|
||||
@@ -110,3 +116,43 @@ void zzuf_fini(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* fd stuff */
|
||||
int zzuf_fd_ismanaged(int fd)
|
||||
{
|
||||
return files[fd].managed;
|
||||
}
|
||||
|
||||
void zzuf_fd_manage(int fd)
|
||||
{
|
||||
files[fd].managed = 1;
|
||||
files[fd].pos = 0;
|
||||
files[fd].fuzz.cur = -1;
|
||||
files[fd].fuzz.data = malloc(CHUNKBYTES);
|
||||
}
|
||||
|
||||
void zzuf_fd_unmanage(int fd)
|
||||
{
|
||||
files[fd].managed = 0;
|
||||
free(files[fd].fuzz.data);
|
||||
}
|
||||
|
||||
long int zzuf_fd_getpos(int fd)
|
||||
{
|
||||
return files[fd].pos;
|
||||
}
|
||||
|
||||
void zzuf_fd_setpos(int fd, long int pos)
|
||||
{
|
||||
files[fd].pos = pos;
|
||||
}
|
||||
|
||||
void zzuf_fd_addpos(int fd, long int off)
|
||||
{
|
||||
files[fd].pos += off;
|
||||
}
|
||||
|
||||
struct fuzz *zzuf_fd_getfuzz(int fd)
|
||||
{
|
||||
return &files[fd].fuzz;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,18 +22,13 @@
|
||||
* any part of the file without reading the whole file. */
|
||||
#define CHUNKBYTES 1024
|
||||
|
||||
struct zzuf
|
||||
struct fuzz
|
||||
{
|
||||
int managed;
|
||||
uint64_t seed;
|
||||
uint64_t pos;
|
||||
int cur;
|
||||
char *data;
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
extern struct zzuf files[];
|
||||
|
||||
/* Internal stuff */
|
||||
/* Internal variables */
|
||||
extern int _zzuf_ready;
|
||||
extern int _zzuf_debug;
|
||||
extern int _zzuf_seed;
|
||||
@@ -45,3 +40,12 @@ extern regex_t * _zzuf_exclude;
|
||||
extern void zzuf_init(void) __attribute__((constructor));
|
||||
extern void zzuf_fini(void) __attribute__((destructor));
|
||||
|
||||
/* File descriptor handling */
|
||||
extern int zzuf_fd_ismanaged(int);
|
||||
extern void zzuf_fd_manage(int);
|
||||
extern void zzuf_fd_unmanage(int);
|
||||
extern long int zzuf_fd_getpos(int);
|
||||
extern void zzuf_fd_setpos(int, long int);
|
||||
extern void zzuf_fd_addpos(int, long int);
|
||||
extern struct fuzz *zzuf_fd_getfuzz(int);
|
||||
|
||||
|
||||
@@ -96,10 +96,7 @@ void zzuf_load_fd(void)
|
||||
file, oflag, mode, ret); \
|
||||
else \
|
||||
debug(STR(fn) "(\"%s\", %i) = %i", file, oflag, ret); \
|
||||
files[ret].managed = 1; \
|
||||
files[ret].cur = -1; \
|
||||
files[ret].data = malloc(CHUNKBYTES); \
|
||||
files[ret].pos = 0; \
|
||||
zzuf_fd_manage(ret); \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
@@ -124,18 +121,18 @@ ssize_t read(int fd, void *buf, size_t count)
|
||||
if(!_zzuf_ready)
|
||||
return ret;
|
||||
|
||||
if(!files[fd].managed)
|
||||
if(!zzuf_fd_ismanaged(fd))
|
||||
return ret;
|
||||
|
||||
debug("read(%i, %p, %li) = %i", fd, buf, (long int)count, ret);
|
||||
if(ret > 0)
|
||||
{
|
||||
zzuf_fuzz(fd, buf, ret);
|
||||
files[fd].pos += ret;
|
||||
zzuf_fd_addpos(fd, ret);
|
||||
}
|
||||
|
||||
/* Sanity check, can be OK though (for instance with a character device) */
|
||||
if((uint64_t)lseek64_orig(fd, 0, SEEK_CUR) != files[fd].pos)
|
||||
if(lseek64_orig(fd, 0, SEEK_CUR) != zzuf_fd_getpos(fd))
|
||||
debug("warning: offset inconsistency");
|
||||
|
||||
return ret;
|
||||
@@ -148,12 +145,12 @@ ssize_t read(int fd, void *buf, size_t count)
|
||||
ret = ORIG(fn)(fd, offset, whence); \
|
||||
if(!_zzuf_ready) \
|
||||
return ret; \
|
||||
if(!files[fd].managed) \
|
||||
if(!zzuf_fd_ismanaged(fd)) \
|
||||
return ret; \
|
||||
debug(STR(fn)"(%i, %lli, %i) = %lli", \
|
||||
fd, (long long int)offset, whence, (long long int)ret); \
|
||||
if(ret != (off_t)-1) \
|
||||
files[fd].pos = (int64_t)ret; \
|
||||
zzuf_fd_setpos(fd, ret); \
|
||||
} while(0)
|
||||
|
||||
off_t lseek(int fd, off_t offset, int whence)
|
||||
@@ -180,12 +177,11 @@ int close(int fd)
|
||||
if(!_zzuf_ready)
|
||||
return ret;
|
||||
|
||||
if(!files[fd].managed)
|
||||
if(!zzuf_fd_ismanaged(fd))
|
||||
return ret;
|
||||
|
||||
debug("close(%i) = %i", fd, ret);
|
||||
free(files[fd].data);
|
||||
files[fd].managed = 0;
|
||||
zzuf_fd_unmanage(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -93,10 +93,7 @@ void zzuf_load_stream(void)
|
||||
else \
|
||||
{ \
|
||||
int fd = fileno(ret); \
|
||||
files[fd].managed = 1; \
|
||||
files[fd].pos = 0; \
|
||||
files[fd].cur = -1; \
|
||||
files[fd].data = malloc(CHUNKBYTES); \
|
||||
zzuf_fd_manage(fd); \
|
||||
debug(STR(fn) "(\"%s\", \"%s\") = %p", path, mode, ret); \
|
||||
} \
|
||||
} \
|
||||
@@ -119,7 +116,7 @@ int fseek(FILE *stream, long offset, int whence)
|
||||
if(!_zzuf_ready)
|
||||
LOADSYM(fseek);
|
||||
fd = fileno(stream);
|
||||
if(!_zzuf_ready || !files[fd].managed)
|
||||
if(!_zzuf_ready || !zzuf_fd_ismanaged(fd))
|
||||
return fseek_orig(stream, offset, whence);
|
||||
|
||||
ret = fseek_orig(stream, offset, whence);
|
||||
@@ -128,9 +125,9 @@ int fseek(FILE *stream, long offset, int whence)
|
||||
{
|
||||
switch(whence)
|
||||
{
|
||||
case SEEK_SET: files[fd].pos = offset; break;
|
||||
case SEEK_CUR: files[fd].pos += offset; break;
|
||||
case SEEK_END: files[fd].pos = ftell(stream); break;
|
||||
case SEEK_SET: zzuf_fd_setpos(fd, offset); break;
|
||||
case SEEK_CUR: zzuf_fd_addpos(fd, offset); break;
|
||||
case SEEK_END: zzuf_fd_setpos(fd, ftell(stream)); break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@@ -144,7 +141,7 @@ size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||
if(!_zzuf_ready)
|
||||
LOADSYM(fread);
|
||||
fd = fileno(stream);
|
||||
if(!_zzuf_ready || !files[fd].managed)
|
||||
if(!_zzuf_ready || !zzuf_fd_ismanaged(fd))
|
||||
return fread_orig(ptr, size, nmemb, stream);
|
||||
|
||||
ret = fread_orig(ptr, size, nmemb, stream);
|
||||
@@ -153,7 +150,7 @@ size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||
if(ret > 0)
|
||||
{
|
||||
zzuf_fuzz(fd, ptr, ret * size);
|
||||
files[fd].pos += ret * size;
|
||||
zzuf_fd_addpos(fd, ret * size);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -164,14 +161,14 @@ size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||
if(!_zzuf_ready) \
|
||||
LOADSYM(fn); \
|
||||
fd = fileno(stream); \
|
||||
if(!_zzuf_ready || !files[fd].managed) \
|
||||
if(!_zzuf_ready || !zzuf_fd_ismanaged(fd)) \
|
||||
return ORIG(fn)(stream); \
|
||||
ret = ORIG(fn)(stream); \
|
||||
if(ret != EOF) \
|
||||
{ \
|
||||
uint8_t ch = ret; \
|
||||
zzuf_fuzz(fd, &ch, 1); \
|
||||
files[fd].pos += 1; \
|
||||
zzuf_fd_addpos(fd, 1); \
|
||||
ret = ch; \
|
||||
} \
|
||||
debug(STR(fn)"(%p) = 0x%02x", stream, ret); \
|
||||
@@ -195,7 +192,7 @@ char *fgets(char *s, int size, FILE *stream)
|
||||
if(!_zzuf_ready)
|
||||
LOADSYM(fgets);
|
||||
fd = fileno(stream);
|
||||
if(!_zzuf_ready || !files[fd].managed)
|
||||
if(!_zzuf_ready || !zzuf_fd_ismanaged(fd))
|
||||
return fgets_orig(s, size, stream);
|
||||
|
||||
if(size <= 0)
|
||||
@@ -217,7 +214,7 @@ char *fgets(char *s, int size, FILE *stream)
|
||||
}
|
||||
s[i] = (char)(unsigned char)ch;
|
||||
zzuf_fuzz(fd, (uint8_t *)s + i, 1); /* rather inefficient */
|
||||
files[fd].pos++;
|
||||
zzuf_fd_addpos(fd, 1);
|
||||
if(s[i] == '\n')
|
||||
{
|
||||
s[i + 1] = '\0';
|
||||
@@ -227,8 +224,6 @@ char *fgets(char *s, int size, FILE *stream)
|
||||
}
|
||||
|
||||
debug("fgets(%p, %i, %p) = %p", s, size, stream, ret);
|
||||
if(ret >= 0)
|
||||
files[fd].pos += 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -240,16 +235,16 @@ int ungetc(int c, FILE *stream)
|
||||
if(!_zzuf_ready)
|
||||
LOADSYM(ungetc);
|
||||
fd = fileno(stream);
|
||||
if(!_zzuf_ready || !files[fd].managed)
|
||||
if(!_zzuf_ready || !zzuf_fd_ismanaged(fd))
|
||||
return ungetc_orig(c, stream);
|
||||
|
||||
files[fd].pos -= 1;
|
||||
zzuf_fd_addpos(fd, -1);
|
||||
zzuf_fuzz(fd, &ch, 1);
|
||||
ret = ungetc_orig((int)ch, stream);
|
||||
if(ret >= 0)
|
||||
ret = c;
|
||||
else
|
||||
files[fd].pos += 1; /* revert what we did */
|
||||
zzuf_fd_addpos(fd, 1); /* revert what we did */
|
||||
debug("ungetc(0x%02x, %p) = 0x%02x", c, stream, ret);
|
||||
return ret;
|
||||
}
|
||||
@@ -261,13 +256,12 @@ int fclose(FILE *fp)
|
||||
if(!_zzuf_ready)
|
||||
LOADSYM(fclose);
|
||||
fd = fileno(fp);
|
||||
if(!_zzuf_ready || !files[fd].managed)
|
||||
if(!_zzuf_ready || !zzuf_fd_ismanaged(fd))
|
||||
return fclose_orig(fp);
|
||||
|
||||
ret = fclose_orig(fp);
|
||||
debug("fclose(%p) = %i", fp, ret);
|
||||
files[fd].managed = 0;
|
||||
free(files[fd].data);
|
||||
zzuf_fd_unmanage(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -280,7 +274,7 @@ int fclose(FILE *fp)
|
||||
if(!_zzuf_ready) \
|
||||
LOADSYM(fn); \
|
||||
fd = fileno(stream); \
|
||||
if(!_zzuf_ready || !files[fd].managed) \
|
||||
if(!_zzuf_ready || !zzuf_fd_ismanaged(fd)) \
|
||||
return getdelim_orig(lineptr, n, delim, stream); \
|
||||
line = *lineptr; \
|
||||
size = line ? *n : 0; \
|
||||
@@ -308,7 +302,7 @@ int fclose(FILE *fp)
|
||||
unsigned char c = ch; \
|
||||
zzuf_fuzz(fd, &c, 1); /* even more inefficient */ \
|
||||
line[done++] = c; \
|
||||
files[fd].pos++; \
|
||||
zzuf_fd_addpos(fd, 1); \
|
||||
if(c == delim) \
|
||||
{ \
|
||||
finished = 1; \
|
||||
|
||||
Reference in New Issue
Block a user