Fix fuzzing detected error

reviewable/pr8008/r2
Craig Tiller 9 years ago
parent ce475062ad
commit a96f8cb179
  1. 32
      src/core/ext/transport/chttp2/transport/chttp2_transport.c
  2. 1
      src/core/ext/transport/chttp2/transport/internal.h

@ -1930,15 +1930,25 @@ static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx,
GPR_TIMER_END("incoming_byte_stream_destroy", 0); GPR_TIMER_END("incoming_byte_stream_destroy", 0);
} }
typedef struct { static void incoming_byte_stream_publish_error(
grpc_chttp2_incoming_byte_stream *byte_stream; grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
gpr_slice slice; grpc_error *error) {
} incoming_byte_stream_push_arg; GPR_ASSERT(error != GRPC_ERROR_NONE);
grpc_exec_ctx_sched(exec_ctx, bs->on_next, GRPC_ERROR_REF(error), NULL);
bs->on_next = NULL;
GRPC_ERROR_UNREF(bs->error);
bs->error = error;
}
void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx,
grpc_chttp2_incoming_byte_stream *bs, grpc_chttp2_incoming_byte_stream *bs,
gpr_slice slice) { gpr_slice slice) {
gpr_mu_lock(&bs->slice_mu); gpr_mu_lock(&bs->slice_mu);
if (bs->remaining_bytes < GPR_SLICE_LENGTH(slice)) {
incoming_byte_stream_publish_error(
exec_ctx, bs, GRPC_ERROR_CREATE("Too many bytes in stream"));
} else {
bs->remaining_bytes -= GPR_SLICE_LENGTH(slice);
if (bs->on_next != NULL) { if (bs->on_next != NULL) {
*bs->next = slice; *bs->next = slice;
grpc_exec_ctx_sched(exec_ctx, bs->on_next, GRPC_ERROR_NONE, NULL); grpc_exec_ctx_sched(exec_ctx, bs->on_next, GRPC_ERROR_NONE, NULL);
@ -1946,17 +1956,22 @@ void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx,
} else { } else {
gpr_slice_buffer_add(&bs->slices, slice); gpr_slice_buffer_add(&bs->slices, slice);
} }
}
gpr_mu_unlock(&bs->slice_mu); gpr_mu_unlock(&bs->slice_mu);
} }
void grpc_chttp2_incoming_byte_stream_finished( void grpc_chttp2_incoming_byte_stream_finished(
grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs, grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
grpc_error *error) { grpc_error *error) {
if (error == GRPC_ERROR_NONE) {
gpr_mu_lock(&bs->slice_mu);
if (bs->remaining_bytes != 0) {
error = GRPC_ERROR_CREATE("Truncated message");
}
gpr_mu_unlock(&bs->slice_mu);
}
if (error != GRPC_ERROR_NONE) { if (error != GRPC_ERROR_NONE) {
grpc_exec_ctx_sched(exec_ctx, bs->on_next, GRPC_ERROR_REF(error), NULL); incoming_byte_stream_publish_error(exec_ctx, bs, error);
bs->on_next = NULL;
GRPC_ERROR_UNREF(bs->error);
bs->error = error;
} }
incoming_byte_stream_unref(exec_ctx, bs); incoming_byte_stream_unref(exec_ctx, bs);
} }
@ -1967,6 +1982,7 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create(
grpc_chttp2_incoming_byte_stream *incoming_byte_stream = grpc_chttp2_incoming_byte_stream *incoming_byte_stream =
gpr_malloc(sizeof(*incoming_byte_stream)); gpr_malloc(sizeof(*incoming_byte_stream));
incoming_byte_stream->base.length = frame_size; incoming_byte_stream->base.length = frame_size;
incoming_byte_stream->remaining_bytes = frame_size;
incoming_byte_stream->base.flags = flags; incoming_byte_stream->base.flags = flags;
incoming_byte_stream->base.next = incoming_byte_stream_next; incoming_byte_stream->base.next = incoming_byte_stream_next;
incoming_byte_stream->base.destroy = incoming_byte_stream_destroy; incoming_byte_stream->base.destroy = incoming_byte_stream_destroy;

@ -167,6 +167,7 @@ struct grpc_chttp2_incoming_byte_stream {
gpr_slice_buffer slices; gpr_slice_buffer slices;
grpc_closure *on_next; grpc_closure *on_next;
gpr_slice *next; gpr_slice *next;
uint32_t remaining_bytes;
struct { struct {
grpc_closure closure; grpc_closure closure;

Loading…
Cancel
Save