Initial commit.
This commit is contained in:
18
Makefile
Normal file
18
Makefile
Normal file
@@ -0,0 +1,18 @@
|
||||
COMP ?= clang
|
||||
DISABLED_WARNINGS ?=
|
||||
CFLAGS ?= -Weverything -Werror -O3 -g --std=gnu11 --pedantic-errors -fPIE -fstack-protector-strong -D_GNU_SOURCE $(DISABLED_WARNINGS)
|
||||
LDFLAGS ?= $(CFLAGS) -Wl,-z,relro -Wl,-z,now -pie
|
||||
LIBS ?=
|
||||
|
||||
OBJ = buf.o rand.o
|
||||
|
||||
all: stutterfuzz
|
||||
|
||||
clean:
|
||||
rm -rf *.o stutterfuzz
|
||||
|
||||
%.o: %.c *.h
|
||||
$(COMP) -c $(CFLAGS) $< -o $@
|
||||
|
||||
stutterfuzz: stutterfuzz.o $(OBJ)
|
||||
$(COMP) $(LDFLAGS) -o stutterfuzz stutterfuzz.o $(OBJ)
|
||||
37
buf.c
Normal file
37
buf.c
Normal file
@@ -0,0 +1,37 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "buf.h"
|
||||
|
||||
void buf_init(struct buf *buf) {
|
||||
buf->start = 0;
|
||||
buf->length = 0;
|
||||
}
|
||||
|
||||
ssize_t buf_fill(struct buf *buf, int fd) {
|
||||
if (buf->start + buf->length == BUF_LEN_MAX) {
|
||||
assert(buf->start > 0);
|
||||
memmove(buf->buf, buf_at(buf, 0), buf->length);
|
||||
buf->start = 0;
|
||||
}
|
||||
|
||||
size_t space = BUF_LEN_MAX - buf->length - buf->start;
|
||||
ssize_t in = read(fd, buf_at(buf, buf->length), space);
|
||||
if (in <= 0) {
|
||||
return in;
|
||||
}
|
||||
buf->length += (size_t) in;
|
||||
return in;
|
||||
}
|
||||
|
||||
void buf_consume(struct buf *buf, size_t length) {
|
||||
assert(buf->length >= length);
|
||||
|
||||
buf->length -= length;
|
||||
if (buf->length) {
|
||||
buf->start += length;
|
||||
} else {
|
||||
buf->start = 0;
|
||||
}
|
||||
}
|
||||
23
buf.h
Normal file
23
buf.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define BUF_LEN_MAX 256
|
||||
struct buf {
|
||||
uint8_t buf[BUF_LEN_MAX];
|
||||
size_t start;
|
||||
size_t length;
|
||||
};
|
||||
#define BUF_INIT { \
|
||||
.start = 0, \
|
||||
.length = 0, \
|
||||
}
|
||||
|
||||
#define buf_chr(buff, at) ((buff)->buf[(buff)->start + (at)])
|
||||
#define buf_at(buff, at) (&buf_chr(buff, at))
|
||||
|
||||
void buf_init(struct buf *);
|
||||
ssize_t buf_fill(struct buf *, int);
|
||||
void buf_consume(struct buf *, size_t);
|
||||
52
rand.c
Normal file
52
rand.c
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "buf.h"
|
||||
|
||||
#include "rand.h"
|
||||
|
||||
static struct buf rand_buf = BUF_INIT;
|
||||
static int rand_fd;
|
||||
|
||||
void rand_init() {
|
||||
rand_fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
|
||||
assert(rand_fd >= 0);
|
||||
assert(read(rand_fd, buf_at(&rand_buf, 0), BUF_LEN_MAX) == BUF_LEN_MAX);
|
||||
rand_buf.length = BUF_LEN_MAX;
|
||||
}
|
||||
|
||||
void rand_cleanup() {
|
||||
assert(!close(rand_fd));
|
||||
}
|
||||
|
||||
void rand_fill(void *value, size_t size) {
|
||||
if (size <= rand_buf.length) {
|
||||
memcpy(value, buf_at(&rand_buf, 0), size);
|
||||
buf_consume(&rand_buf, size);
|
||||
return;
|
||||
}
|
||||
|
||||
struct iovec iov[2] = {
|
||||
{
|
||||
.iov_base = rand_buf.buf,
|
||||
.iov_len = rand_buf.start,
|
||||
},
|
||||
{
|
||||
.iov_base = value,
|
||||
.iov_len = size,
|
||||
},
|
||||
};
|
||||
|
||||
size_t bytes = rand_buf.start + size;
|
||||
assert(bytes < SSIZE_MAX);
|
||||
assert(readv(rand_fd, iov, 2) == (ssize_t) bytes);
|
||||
rand_buf.start = 0;
|
||||
rand_buf.length = BUF_LEN_MAX;
|
||||
}
|
||||
7
rand.h
Normal file
7
rand.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
void rand_init(void);
|
||||
void rand_cleanup(void);
|
||||
void rand_fill(void *, size_t);
|
||||
35
stutterfuzz.c
Normal file
35
stutterfuzz.c
Normal file
@@ -0,0 +1,35 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "rand.h"
|
||||
|
||||
static uint64_t sqrt64(uint64_t n) {
|
||||
uint64_t g = UINT64_C(1) << 31;
|
||||
|
||||
for (uint64_t c = g; c; g |= c) {
|
||||
if (g * g > n) {
|
||||
g ^= c;
|
||||
}
|
||||
c >>= 1;
|
||||
}
|
||||
return g;
|
||||
}
|
||||
|
||||
static uint64_t get_split(uint64_t len) {
|
||||
uint64_t rnd;
|
||||
rand_fill(&rnd, sizeof(rnd));
|
||||
rnd %= (len * len);
|
||||
return sqrt64(rnd) + 1;
|
||||
}
|
||||
|
||||
int main(int __attribute__ ((unused)) argc, char __attribute__ ((unused)) *argv[]) {
|
||||
rand_init();
|
||||
|
||||
for (uint64_t len = 1397; len;) {
|
||||
uint64_t consume = get_split(len);
|
||||
fprintf(stderr, "consume %ju bytes\n", (uintmax_t) consume);
|
||||
len -= consume;
|
||||
}
|
||||
|
||||
rand_cleanup();
|
||||
}
|
||||
Reference in New Issue
Block a user