From a084bb2160a2de6e7cb92ca67fe3830a90ac60ae Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 11 Apr 2016 16:36:29 +0930 Subject: [PATCH] bitcoin/tx: make sure we don't try to do a huge allocation on bad input tx. This could only happen via our RPC interface (bitcoind should not give us bad txs!) but it's better to be robust. Signed-off-by: Rusty Russell --- bitcoin/tx.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/bitcoin/tx.c b/bitcoin/tx.c index a2d8a5432..ed8e9b24a 100644 --- a/bitcoin/tx.c +++ b/bitcoin/tx.c @@ -240,12 +240,25 @@ static u64 pull_value(const u8 **cursor, size_t *max) return amount; } +/* Pulls a varint which specifies a data length: ensures basic sanity to + * avoid trivial OOM */ +static u64 pull_length(const u8 **cursor, size_t *max) +{ + u64 v = pull_varint(cursor, max); + if (v > *max) { + *cursor = NULL; + *max = 0; + return 0; + } + return v; +} + static void pull_input(const tal_t *ctx, const u8 **cursor, size_t *max, struct bitcoin_tx_input *input) { pull_sha256_double(cursor, max, &input->txid); input->index = pull_le32(cursor, max); - input->script_length = pull_varint(cursor, max); + input->script_length = pull_length(cursor, max); input->script = tal_arr(ctx, u8, input->script_length); pull(cursor, max, input->script, input->script_length); input->sequence_number = pull_le32(cursor, max); @@ -255,7 +268,7 @@ static void pull_output(const tal_t *ctx, const u8 **cursor, size_t *max, struct bitcoin_tx_output *output) { output->amount = pull_value(cursor, max); - output->script_length = pull_varint(cursor, max); + output->script_length = pull_length(cursor, max); output->script = tal_arr(ctx, u8, output->script_length); pull(cursor, max, output->script, output->script_length); } @@ -267,12 +280,12 @@ static struct bitcoin_tx *pull_bitcoin_tx(const tal_t *ctx, size_t i; tx->version = pull_le32(cursor, max); - tx->input_count = pull_varint(cursor, max); + tx->input_count = pull_length(cursor, max); tx->input = tal_arr(tx, struct bitcoin_tx_input, tx->input_count); for (i = 0; i < tx->input_count; i++) pull_input(tx, cursor, max, tx->input + i); - tx->output_count = pull_varint(cursor, max); + tx->output_count = pull_length(cursor, max); tx->output = tal_arr(tx, struct bitcoin_tx_output, tx->output_count); for (i = 0; i < tx->output_count; i++) pull_output(tx, cursor, max, tx->output + i);