Skip to content

Commit ef024e1

Browse files
authored
adapt fuzzer_bufq to new API (#166)
Adapt and re-enable bufq fuzzer
1 parent b21d8d7 commit ef024e1

File tree

3 files changed

+56
-55
lines changed

3 files changed

+56
-55
lines changed

CMakeLists.txt

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -374,13 +374,12 @@ add_curl_fuzzer(curl_fuzzer_tftp TFTP)
374374
add_curl_fuzzer(curl_fuzzer_ws WS)
375375

376376
# BUFQ fuzzer
377-
# temporary disable bufq fuzzer for merging API change
378-
# add_executable(curl_fuzzer_bufq fuzz_bufq.cc)
379-
# target_compile_options(curl_fuzzer_bufq PRIVATE ${COMMON_FLAGS})
380-
# target_include_directories(curl_fuzzer_bufq PRIVATE ${CURL_INCLUDE_DIRS})
381-
# target_link_libraries(curl_fuzzer_bufq PRIVATE ${COMMON_LINK_LIBS})
382-
# target_link_options(curl_fuzzer_bufq PRIVATE ${COMMON_LINK_OPTIONS})
383-
# add_dependencies(curl_fuzzer_bufq ${FUZZ_DEPS})
377+
add_executable(curl_fuzzer_bufq fuzz_bufq.cc)
378+
target_compile_options(curl_fuzzer_bufq PRIVATE ${COMMON_FLAGS})
379+
target_include_directories(curl_fuzzer_bufq PRIVATE ${CURL_INCLUDE_DIRS})
380+
target_link_libraries(curl_fuzzer_bufq PRIVATE ${COMMON_LINK_LIBS})
381+
target_link_options(curl_fuzzer_bufq PRIVATE ${COMMON_LINK_OPTIONS})
382+
add_dependencies(curl_fuzzer_bufq ${FUZZ_DEPS})
384383

385384
# URL fuzzer
386385
add_executable(fuzz_url fuzz_url.cc)
@@ -416,7 +415,7 @@ add_custom_target(fuzz
416415
curl_fuzzer_smtp
417416
curl_fuzzer_tftp
418417
curl_fuzzer_ws
419-
# curl_fuzzer_bufq
418+
curl_fuzzer_bufq
420419
fuzz_url
421420
curl_fuzzer_fnmatch
422421
)

fuzz_bufq.cc

Lines changed: 48 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -69,67 +69,65 @@ static unsigned char *compute_buffer(unsigned char next_byte, unsigned char *buf
6969
struct writer_cb_ctx {
7070
bool verbose;
7171
unsigned char *template_buf;
72-
ssize_t read_len;
72+
size_t read_len;
7373
unsigned char next_byte_read;
7474
};
7575

7676
/**
7777
* Consume and verify up to read_len from a BUFQ via callback for Curl_bufq_pass.
7878
*/
79-
ssize_t bufq_writer_cb(void *writer_ctx,
79+
CURLcode bufq_writer_cb(void *writer_ctx,
8080
const unsigned char *buf, size_t len,
81-
CURLcode *err)
81+
size_t *pnwritten)
8282
{
8383
struct writer_cb_ctx *ctx = (struct writer_cb_ctx *)writer_ctx;
8484

85-
if (ctx->read_len <= 0) {
86-
*err = CURLE_AGAIN;
87-
return -1;
88-
}
85+
*pnwritten = 0;
86+
if (ctx->read_len <= 0)
87+
return CURLE_AGAIN;
8988

9089
FV_PRINTF(ctx->verbose, "Writer CB: %zu space available, %zu pending\n", len, ctx->read_len);
9190

92-
size_t sz = len > ctx->read_len ? ctx->read_len : len;
91+
*pnwritten = len > ctx->read_len ? ctx->read_len : len;
9392

9493
unsigned char *compare = compute_buffer(ctx->next_byte_read, ctx->template_buf);
95-
assert(memcmp(buf, compare, sz) == 0);
96-
ctx->next_byte_read += sz;
97-
ctx->read_len -= sz;
94+
assert(memcmp(buf, compare, *pnwritten) == 0);
95+
ctx->next_byte_read += *pnwritten;
96+
ctx->read_len -= *pnwritten;
9897

99-
return sz;
98+
return CURLE_OK;
10099
}
101100

102101
struct reader_cb_ctx {
103102
bool verbose;
104103
unsigned char *template_buf;
105-
ssize_t write_len;
104+
size_t write_len;
106105
unsigned char next_byte_write;
107106
};
108107

109108
/**
110109
* Write up to write_len to a BUFQ via callback for Curl_bufq_slurp/sipn.
111110
*/
112-
static ssize_t bufq_reader_cb(void *reader_ctx,
111+
static CURLcode bufq_reader_cb(void *reader_ctx,
113112
unsigned char *buf, size_t len,
114-
CURLcode *err)
113+
size_t *pnread)
115114
{
116115
struct reader_cb_ctx *ctx = (struct reader_cb_ctx *)reader_ctx;
117116

118-
if (ctx->write_len <= 0) {
119-
*err = CURLE_AGAIN;
120-
return -1;
121-
}
117+
*pnread = 0;
118+
if (ctx->write_len <= 0)
119+
return CURLE_AGAIN;
122120

123121
FV_PRINTF(ctx->verbose, "Reader CB: %zu space available, %zu pending\n", len, ctx->write_len);
124122

125-
size_t sz = len > ctx->write_len ? ctx->write_len : len;
123+
*pnread = len > ctx->write_len ? ctx->write_len : len;
126124

127125
unsigned char *compare = compute_buffer(ctx->next_byte_write, ctx->template_buf);
128-
memcpy(buf, compare, sz);
129-
ctx->next_byte_write += sz;
130-
ctx->write_len -= sz;
126+
memcpy(buf, compare, *pnread);
127+
ctx->next_byte_write += *pnread;
128+
ctx->write_len -= *pnread;
131129

132-
return sz;
130+
return CURLE_OK;
133131
}
134132

135133
/**
@@ -161,7 +159,7 @@ int fuzz_handle_bufq(FuzzedDataProvider *fuzz)
161159
Curl_bufq_init(&q, chunk_size, max_chunks);
162160
}
163161

164-
ssize_t buffer_bytes = 0;
162+
size_t buffer_bytes = 0;
165163
unsigned char next_byte_read = 0;
166164
unsigned char next_byte_write = 0;
167165
while (fuzz->remaining_bytes() > 0) {
@@ -213,9 +211,10 @@ int fuzz_handle_bufq(FuzzedDataProvider *fuzz)
213211
size_t op_size = fuzz->ConsumeIntegralInRange(0, FUZZ_MAX_RW_SIZE);
214212
FV_PRINTF(verbose, "OP: read, size %zu\n", op_size);
215213
unsigned char *buf = (unsigned char *)malloc(op_size * sizeof(*buf));
216-
ssize_t read = Curl_bufq_read(&q, buf, op_size, &err);
217-
if (read != -1) {
218-
FV_PRINTF(verbose, "OP: read, success, read %zd, expect begins with %x\n", read, next_byte_read);
214+
size_t read;
215+
CURLcode result = Curl_bufq_read(&q, buf, op_size, &read);
216+
if (!result) {
217+
FV_PRINTF(verbose, "OP: read, success, read %zu, expect begins with %x\n", read, next_byte_read);
219218
buffer_bytes -= read;
220219
assert(buffer_bytes >= 0);
221220
unsigned char *compare = compute_buffer(next_byte_read, template_buf);
@@ -229,12 +228,13 @@ int fuzz_handle_bufq(FuzzedDataProvider *fuzz)
229228
}
230229

231230
case OP_TYPE_SLURP: {
232-
ssize_t op_size = fuzz->ConsumeIntegralInRange(0, FUZZ_MAX_RW_SIZE);
231+
size_t op_size = fuzz->ConsumeIntegralInRange(0, FUZZ_MAX_RW_SIZE);
233232
FV_PRINTF(verbose, "OP: slurp, size %zd\n", op_size);
234233
struct reader_cb_ctx ctx = { .verbose = verbose, .template_buf = template_buf, .write_len = op_size, .next_byte_write = next_byte_write };
235-
ssize_t write = Curl_bufq_slurp(&q, bufq_reader_cb, &ctx, &err);
236-
if (write != -1) {
237-
FV_PRINTF(verbose, "OP: slurp, success, wrote %zd, expect begins with %x\n", write, ctx.next_byte_write);
234+
size_t write;
235+
CURLcode result = Curl_bufq_slurp(&q, bufq_reader_cb, &ctx, &write);
236+
if (!result) {
237+
FV_PRINTF(verbose, "OP: slurp, success, wrote %zu, expect begins with %x\n", write, ctx.next_byte_write);
238238
buffer_bytes += write;
239239
} else {
240240
FV_PRINTF(verbose, "OP: slurp, error\n");
@@ -247,12 +247,13 @@ int fuzz_handle_bufq(FuzzedDataProvider *fuzz)
247247
}
248248

249249
case OP_TYPE_SIPN: {
250-
ssize_t op_size = fuzz->ConsumeIntegralInRange(0, FUZZ_MAX_RW_SIZE);
250+
size_t op_size = fuzz->ConsumeIntegralInRange(0, FUZZ_MAX_RW_SIZE);
251251
FV_PRINTF(verbose, "OP: sipn, size %zd\n", op_size);
252252
struct reader_cb_ctx ctx = { .verbose = verbose, .template_buf = template_buf, .write_len = op_size, .next_byte_write = next_byte_write };
253-
ssize_t write = Curl_bufq_sipn(&q, op_size, bufq_reader_cb, &ctx, &err);
254-
if (write != -1) {
255-
FV_PRINTF(verbose, "OP: sipn, success, wrote %zd, expect begins with %x\n", write, ctx.next_byte_write);
253+
size_t write;
254+
CURLcode result = Curl_bufq_sipn(&q, op_size, bufq_reader_cb, &ctx, &write);
255+
if (!result) {
256+
FV_PRINTF(verbose, "OP: sipn, success, wrote %zu, expect begins with %x\n", write, ctx.next_byte_write);
256257
buffer_bytes += write;
257258
assert(buffer_bytes <= chunk_size * max_chunks);
258259
next_byte_write = ctx.next_byte_write;
@@ -263,13 +264,14 @@ int fuzz_handle_bufq(FuzzedDataProvider *fuzz)
263264
}
264265

265266
case OP_TYPE_PASS: {
266-
ssize_t op_size = fuzz->ConsumeIntegralInRange(0, FUZZ_MAX_RW_SIZE);
267+
size_t op_size = fuzz->ConsumeIntegralInRange(0, FUZZ_MAX_RW_SIZE);
267268
FV_PRINTF(verbose, "OP: pass, size %zd\n", op_size);
268269
struct writer_cb_ctx ctx = { .verbose = verbose, .template_buf = template_buf, .read_len = op_size, .next_byte_read = next_byte_read };
269-
ssize_t read = Curl_bufq_pass(&q, bufq_writer_cb, &ctx, &err);
270-
if (read != -1) {
271-
FV_PRINTF(verbose, "OP: pass, success, read %zd, expect begins with %x\n", read, ctx.next_byte_read);
272-
buffer_bytes -= read;
270+
size_t nread;
271+
CURLcode result = Curl_bufq_pass(&q, bufq_writer_cb, &ctx, &nread);
272+
if (!result) {
273+
FV_PRINTF(verbose, "OP: pass, success, read %zu, expect begins with %x\n", nread, ctx.next_byte_read);
274+
buffer_bytes -= nread;
273275
} else {
274276
FV_PRINTF(verbose, "OP: pass, error\n");
275277
/* in case of -1, it may still have read something, adjust for that */
@@ -284,7 +286,7 @@ int fuzz_handle_bufq(FuzzedDataProvider *fuzz)
284286
size_t op_size = fuzz->ConsumeIntegralInRange(0, FUZZ_MAX_RW_SIZE);
285287
FV_PRINTF(verbose, "OP: skip, size %zu\n", op_size);
286288
Curl_bufq_skip(&q, op_size);
287-
ssize_t old_buffer_bytes = buffer_bytes;
289+
size_t old_buffer_bytes = buffer_bytes;
288290
buffer_bytes = old_buffer_bytes > op_size ? old_buffer_bytes - op_size : 0;
289291
next_byte_read += old_buffer_bytes > op_size ? op_size : old_buffer_bytes;
290292
break;
@@ -294,9 +296,10 @@ int fuzz_handle_bufq(FuzzedDataProvider *fuzz)
294296
size_t op_size = fuzz->ConsumeIntegralInRange(0, FUZZ_MAX_RW_SIZE);
295297
FV_PRINTF(verbose, "OP: write, size %zu, begins with %x\n", op_size, next_byte_write);
296298
unsigned char *buf = compute_buffer(next_byte_write, template_buf);
297-
ssize_t written = Curl_bufq_write(&q, buf, op_size, &err);
298-
if (written != -1) {
299-
FV_PRINTF(verbose, "OP: write, success, written %zd\n", written);
299+
size_t written;
300+
CURLcode result = Curl_bufq_write(&q, buf, op_size, &written);
301+
if (!result) {
302+
FV_PRINTF(verbose, "OP: write, success, written %zu\n", written);
300303
next_byte_write += written;
301304
buffer_bytes += written;
302305
assert(buffer_bytes <= chunk_size * max_chunks);

scripts/fuzz_targets

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
#!/bin/bash
22

3-
# export FUZZ_TARGETS="curl_fuzzer_dict curl_fuzzer_file curl_fuzzer_ftp curl_fuzzer_gopher curl_fuzzer_http curl_fuzzer_https curl_fuzzer_imap curl_fuzzer_mqtt curl_fuzzer_pop3 curl_fuzzer_rtsp curl_fuzzer_smb curl_fuzzer_smtp curl_fuzzer_tftp curl_fuzzer_ws curl_fuzzer fuzz_url curl_fuzzer_bufq"
4-
export FUZZ_TARGETS="curl_fuzzer_dict curl_fuzzer_file curl_fuzzer_ftp curl_fuzzer_gopher curl_fuzzer_http curl_fuzzer_https curl_fuzzer_imap curl_fuzzer_mqtt curl_fuzzer_pop3 curl_fuzzer_rtsp curl_fuzzer_smb curl_fuzzer_smtp curl_fuzzer_tftp curl_fuzzer_ws curl_fuzzer fuzz_url"
3+
export FUZZ_TARGETS="curl_fuzzer_dict curl_fuzzer_file curl_fuzzer_ftp curl_fuzzer_gopher curl_fuzzer_http curl_fuzzer_https curl_fuzzer_imap curl_fuzzer_mqtt curl_fuzzer_pop3 curl_fuzzer_rtsp curl_fuzzer_smb curl_fuzzer_smtp curl_fuzzer_tftp curl_fuzzer_ws curl_fuzzer fuzz_url curl_fuzzer_bufq"

0 commit comments

Comments
 (0)