Skip to content
Snippets Groups Projects
Commit 5abe38bb authored by Craig Tiller's avatar Craig Tiller
Browse files

Merge branch 'fuzz-it' into error

parents 95b9064d 7987d793
No related branches found
No related tags found
No related merge requests found
Showing
with 63 additions and 11 deletions
...@@ -345,6 +345,8 @@ static void free_non_null(void *p) { ...@@ -345,6 +345,8 @@ static void free_non_null(void *p) {
typedef enum { ROOT, CLIENT, SERVER, PENDING_SERVER } call_state_type; typedef enum { ROOT, CLIENT, SERVER, PENDING_SERVER } call_state_type;
#define DONE_FLAG_CALL_CLOSED ((uint64_t)(1 << 0))
typedef struct call_state { typedef struct call_state {
call_state_type type; call_state_type type;
grpc_call *call; grpc_call *call;
...@@ -357,6 +359,10 @@ typedef struct call_state { ...@@ -357,6 +359,10 @@ typedef struct call_state {
int cancelled; int cancelled;
int pending_ops; int pending_ops;
grpc_call_details call_details; grpc_call_details call_details;
grpc_byte_buffer *send_message;
// starts at 0, individual flags from DONE_FLAG_xxx are set
// as different operations are completed
uint64_t done_flags;
// array of pointers to free later // array of pointers to free later
size_t num_to_free; size_t num_to_free;
...@@ -454,10 +460,41 @@ static void finished_request_call(void *csp, bool success) { ...@@ -454,10 +460,41 @@ static void finished_request_call(void *csp, bool success) {
} }
} }
static void finished_batch(void *csp, bool success) { typedef struct {
call_state *cs = csp; call_state *cs;
--cs->pending_ops; uint8_t has_ops;
maybe_delete_call_state(cs); } batch_info;
static void finished_batch(void *p, bool success) {
batch_info *bi = p;
--bi->cs->pending_ops;
if ((bi->has_ops & (1u << GRPC_OP_RECV_MESSAGE)) &&
(bi->cs->done_flags & DONE_FLAG_CALL_CLOSED)) {
GPR_ASSERT(bi->cs->recv_message == NULL);
}
if ((bi->has_ops & (1u << GRPC_OP_RECV_MESSAGE) &&
bi->cs->recv_message != NULL)) {
grpc_byte_buffer_destroy(bi->cs->recv_message);
bi->cs->recv_message = NULL;
}
if ((bi->has_ops & (1u << GRPC_OP_SEND_MESSAGE))) {
grpc_byte_buffer_destroy(bi->cs->send_message);
bi->cs->send_message = NULL;
}
if ((bi->has_ops & (1u << GRPC_OP_RECV_STATUS_ON_CLIENT)) ||
(bi->has_ops & (1u << GRPC_OP_RECV_CLOSE_ON_SERVER))) {
bi->cs->done_flags |= DONE_FLAG_CALL_CLOSED;
}
maybe_delete_call_state(bi->cs);
gpr_free(bi);
}
static validator *make_finished_batch_validator(call_state *cs,
uint8_t has_ops) {
batch_info *bi = gpr_malloc(sizeof(*bi));
bi->cs = cs;
bi->has_ops = has_ops;
return create_validator(finished_batch, bi);
} }
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
...@@ -584,6 +621,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ...@@ -584,6 +621,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
} else { } else {
end(&inp); end(&inp);
} }
break;
} }
// begin server shutdown // begin server shutdown
case 5: { case 5: {
...@@ -705,6 +743,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ...@@ -705,6 +743,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
bool ok = true; bool ok = true;
size_t i; size_t i;
grpc_op *op; grpc_op *op;
uint8_t has_ops = 0;
for (i = 0; i < num_ops; i++) { for (i = 0; i < num_ops; i++) {
op = &ops[i]; op = &ops[i];
switch (next_byte(&inp)) { switch (next_byte(&inp)) {
...@@ -715,19 +754,28 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ...@@ -715,19 +754,28 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
break; break;
case GRPC_OP_SEND_INITIAL_METADATA: case GRPC_OP_SEND_INITIAL_METADATA:
op->op = GRPC_OP_SEND_INITIAL_METADATA; op->op = GRPC_OP_SEND_INITIAL_METADATA;
has_ops |= 1 << GRPC_OP_SEND_INITIAL_METADATA;
read_metadata(&inp, &op->data.send_initial_metadata.count, read_metadata(&inp, &op->data.send_initial_metadata.count,
&op->data.send_initial_metadata.metadata, &op->data.send_initial_metadata.metadata,
g_active_call); g_active_call);
break; break;
case GRPC_OP_SEND_MESSAGE: case GRPC_OP_SEND_MESSAGE:
op->op = GRPC_OP_SEND_MESSAGE; op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message = read_message(&inp); if (g_active_call->send_message != NULL) {
ok = false;
} else {
has_ops |= 1 << GRPC_OP_SEND_MESSAGE;
g_active_call->send_message = op->data.send_message =
read_message(&inp);
}
break; break;
case GRPC_OP_SEND_CLOSE_FROM_CLIENT: case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
has_ops |= 1 << GRPC_OP_SEND_CLOSE_FROM_CLIENT;
break; break;
case GRPC_OP_SEND_STATUS_FROM_SERVER: case GRPC_OP_SEND_STATUS_FROM_SERVER:
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
has_ops |= 1 << GRPC_OP_SEND_STATUS_FROM_SERVER;
read_metadata( read_metadata(
&inp, &inp,
&op->data.send_status_from_server.trailing_metadata_count, &op->data.send_status_from_server.trailing_metadata_count,
...@@ -739,11 +787,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ...@@ -739,11 +787,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
break; break;
case GRPC_OP_RECV_INITIAL_METADATA: case GRPC_OP_RECV_INITIAL_METADATA:
op->op = GRPC_OP_RECV_INITIAL_METADATA; op->op = GRPC_OP_RECV_INITIAL_METADATA;
has_ops |= 1 << GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = op->data.recv_initial_metadata =
&g_active_call->recv_initial_metadata; &g_active_call->recv_initial_metadata;
break; break;
case GRPC_OP_RECV_MESSAGE: case GRPC_OP_RECV_MESSAGE:
op->op = GRPC_OP_RECV_MESSAGE; op->op = GRPC_OP_RECV_MESSAGE;
has_ops |= 1 << GRPC_OP_RECV_MESSAGE;
op->data.recv_message = &g_active_call->recv_message; op->data.recv_message = &g_active_call->recv_message;
break; break;
case GRPC_OP_RECV_STATUS_ON_CLIENT: case GRPC_OP_RECV_STATUS_ON_CLIENT:
...@@ -758,6 +808,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ...@@ -758,6 +808,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
break; break;
case GRPC_OP_RECV_CLOSE_ON_SERVER: case GRPC_OP_RECV_CLOSE_ON_SERVER:
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
has_ops |= 1 << GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = op->data.recv_close_on_server.cancelled =
&g_active_call->cancelled; &g_active_call->cancelled;
break; break;
...@@ -766,7 +817,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ...@@ -766,7 +817,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
op->flags = read_uint32(&inp); op->flags = read_uint32(&inp);
} }
if (ok) { if (ok) {
validator *v = create_validator(finished_batch, g_active_call); validator *v = make_finished_batch_validator(g_active_call, has_ops);
g_active_call->pending_ops++; g_active_call->pending_ops++;
grpc_call_error error = grpc_call_error error =
grpc_call_start_batch(g_active_call->call, ops, num_ops, v, NULL); grpc_call_start_batch(g_active_call->call, ops, num_ops, v, NULL);
...@@ -777,17 +828,18 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ...@@ -777,17 +828,18 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
} else { } else {
end(&inp); end(&inp);
} }
if (!ok && (has_ops & (1 << GRPC_OP_SEND_MESSAGE))) {
grpc_byte_buffer_destroy(g_active_call->send_message);
g_active_call->send_message = NULL;
}
for (i = 0; i < num_ops; i++) { for (i = 0; i < num_ops; i++) {
op = &ops[i]; op = &ops[i];
switch (op->op) { switch (op->op) {
case GRPC_OP_SEND_INITIAL_METADATA:
break;
case GRPC_OP_SEND_MESSAGE:
grpc_byte_buffer_destroy(op->data.send_message);
break;
case GRPC_OP_SEND_STATUS_FROM_SERVER: case GRPC_OP_SEND_STATUS_FROM_SERVER:
gpr_free((void *)op->data.send_status_from_server.status_details); gpr_free((void *)op->data.send_status_from_server.status_details);
break; break;
case GRPC_OP_SEND_MESSAGE:
case GRPC_OP_SEND_INITIAL_METADATA:
case GRPC_OP_SEND_CLOSE_FROM_CLIENT: case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
case GRPC_OP_RECV_INITIAL_METADATA: case GRPC_OP_RECV_INITIAL_METADATA:
case GRPC_OP_RECV_MESSAGE: case GRPC_OP_RECV_MESSAGE:
......
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
File added
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment