From 861bd066feea6d8a4edbe66798d05f088ebfe168 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 26 Jul 2016 03:31:56 +0000 Subject: [PATCH 1/4] Bugfix: Restore calloc despite blktxn_init; if we fail before completing parsing the transaction, we need to avoid uncleared pointers --- blkmaker_jansson.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blkmaker_jansson.c b/blkmaker_jansson.c index 390b08a..097276c 100644 --- a/blkmaker_jansson.c +++ b/blkmaker_jansson.c @@ -281,7 +281,7 @@ const char *blktmpl_add_jansson(blktemplate_t *tmpl, const json_t *json, time_t v = json_object_get(json, "transactions"); size_t txns = tmpl->txncount = json_array_size(v); - tmpl->txns = malloc(txns * sizeof(*tmpl->txns)); + tmpl->txns = calloc(txns, sizeof(*tmpl->txns)); tmpl->txns_datasz = 0; for (size_t i = 0; i < txns; ++i) { @@ -294,7 +294,7 @@ const char *blktmpl_add_jansson(blktemplate_t *tmpl, const json_t *json, time_t if ((v = json_object_get(json, "coinbasetxn")) && json_is_object(v)) { - tmpl->cbtxn = malloc(sizeof(*tmpl->cbtxn)); + tmpl->cbtxn = calloc(1, sizeof(*tmpl->cbtxn)); if ((s = parse_txn(tmpl->cbtxn, v, 0))) return s; } From 2eb326525da96a5da0ea3977a862e185ffa05c44 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 26 Jul 2016 03:42:38 +0000 Subject: [PATCH 2/4] Bugfix: Reject invalid coinbaseaux data --- blkmaker_jansson.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/blkmaker_jansson.c b/blkmaker_jansson.c index 5ba24d6..f597bee 100644 --- a/blkmaker_jansson.c +++ b/blkmaker_jansson.c @@ -229,7 +229,7 @@ const char *blktmpl_add_jansson(blktemplate_t *tmpl, const json_t *json, time_t if ((v = json_object_get(json, "coinbaseaux")) && json_is_object(v)) { tmpl->aux_count = json_object_size(v); - tmpl->auxs = malloc(tmpl->aux_count * sizeof(*tmpl->auxs)); + tmpl->auxs = calloc(tmpl->aux_count, sizeof(*tmpl->auxs)); unsigned i = 0; for (void *iter = json_object_iter(v); iter; (iter = json_object_iter_next(v, iter)), ++i) { @@ -243,7 +243,9 @@ const char *blktmpl_add_jansson(blktemplate_t *tmpl, const json_t *json, time_t .data = malloc(sz), .datasz = sz, }; - my_hex2bin(tmpl->auxs[i].data, s, sz); + if (!my_hex2bin(tmpl->auxs[i].data, s, sz)) { + return "Error decoding 'coinbaseaux' data"; + } } } From 80c85d212ac440c0d236ca611b066e0dcf356f62 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 26 Jul 2016 04:07:09 +0000 Subject: [PATCH 3/4] When possible, check sigoplimit before appending to the coinbase --- blkmaker.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/blkmaker.c b/blkmaker.c index d51934d..7f113c4 100644 --- a/blkmaker.c +++ b/blkmaker.c @@ -180,8 +180,9 @@ uint64_t blkmk_init_generation3(blktemplate_t * const tmpl, const void * const s memset(&data[off], 0, 4); // lock time off += 4; + const int16_t sigops_counted = blkmk_count_sigops(script, scriptsz); if (tmpl->txns_datasz + off > tmpl->sizelimit - || (tmpl->txns_sigops >= 0 && tmpl->txns_sigops + blkmk_count_sigops(script, scriptsz) > tmpl->sigoplimit)) { + || (tmpl->txns_sigops >= 0 && tmpl->txns_sigops + sigops_counted > tmpl->sigoplimit)) { free(data); return 0; } @@ -196,6 +197,7 @@ uint64_t blkmk_init_generation3(blktemplate_t * const tmpl, const void * const s txn->data = data; txn->datasz = off; + txn->sigops_ = sigops_counted; if (tmpl->cbtxn) { @@ -318,7 +320,7 @@ bool build_merkle_root(unsigned char *mrklroot_out, blktemplate_t *tmpl, unsigne static const int cbScriptSigLen = 4 + 1 + 36; static -bool _blkmk_append_cb(blktemplate_t * const tmpl, void * const vout, const void * const append, const size_t appendsz, size_t * const appended_at_offset) { +bool _blkmk_append_cb(blktemplate_t * const tmpl, void * const vout, const void * const append, const size_t appendsz, size_t * const appended_at_offset, int16_t * const sigops_counted_p) { unsigned char *out = vout; unsigned char *in = tmpl->cbtxn->data; size_t insz = tmpl->cbtxn->datasz; @@ -330,6 +332,7 @@ bool _blkmk_append_cb(blktemplate_t * const tmpl, void * const vout, const void return false; } + const int16_t orig_scriptSig_sigops = blkmk_count_sigops(&in[cbScriptSigLen + 1], in[cbScriptSigLen]); int cbPostScriptSig = cbScriptSigLen + 1 + in[cbScriptSigLen]; if (appended_at_offset) *appended_at_offset = cbPostScriptSig; @@ -348,6 +351,21 @@ bool _blkmk_append_cb(blktemplate_t * const tmpl, void * const vout, const void out[cbScriptSigLen] += appendsz; memcpy(outExtranonce, append, appendsz); + const int16_t sigops_counted = (tmpl->cbtxn->sigops_ - orig_scriptSig_sigops) + blkmk_count_sigops(&out[cbScriptSigLen + 1], out[cbScriptSigLen]); + if (tmpl->txns_sigops >= 0 && tmpl->txns_sigops + sigops_counted > tmpl->sigoplimit) { + // Overflowed :( + if (out == in) { + // Revert it! + out[cbScriptSigLen] -= appendsz; + memmove(&out[cbPostScriptSig], outPostScriptSig, insz - cbPostScriptSig); + } + return false; + } + + if (sigops_counted_p) { + *sigops_counted_p = sigops_counted; + } + return true; } @@ -384,7 +402,7 @@ ssize_t blkmk_append_coinbase_safe2(blktemplate_t * const tmpl, const void * con return -2; tmpl->cbtxn->data = newp; - if (!_blkmk_append_cb(tmpl, newp, append, appendsz, NULL)) + if (!_blkmk_append_cb(tmpl, newp, append, appendsz, NULL, &tmpl->cbtxn->sigops_)) return -3; tmpl->cbtxn->datasz += appendsz; @@ -406,7 +424,7 @@ bool _blkmk_extranonce(blktemplate_t *tmpl, void *vout, unsigned int workid, siz return true; } - if (!_blkmk_append_cb(tmpl, vout, &workid, sizeof(workid), NULL)) + if (!_blkmk_append_cb(tmpl, vout, &workid, sizeof(workid), NULL, NULL)) return false; *offs += insz + sizeof(workid); @@ -496,7 +514,7 @@ bool blkmk_get_mdata(blktemplate_t * const tmpl, void * const buf, const size_t return false; unsigned char dummy[extranoncesz]; memset(dummy, 0, extranoncesz); - if (!_blkmk_append_cb(tmpl, *out_cbtxn, dummy, extranoncesz, cbextranonceoffset)) + if (!_blkmk_append_cb(tmpl, *out_cbtxn, dummy, extranoncesz, cbextranonceoffset, NULL)) { free(*out_cbtxn); return false; @@ -562,7 +580,7 @@ static char *blkmk_assemble_submission2_internal(blktemplate_t * const tmpl, con // Essentially _blkmk_extranonce if (extranoncesz) { - if (!_blkmk_append_cb(tmpl, &blk[offs], extranonce, extranoncesz, NULL)) { + if (!_blkmk_append_cb(tmpl, &blk[offs], extranonce, extranoncesz, NULL, NULL)) { free(blk); return NULL; } From 8f8110a7e4cc9c89f5cc4abac1c05b61d4b0a32c Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 26 Jul 2016 04:22:11 +0000 Subject: [PATCH 4/4] Bugfix: Remove duplicate sigop tallying --- blkmaker_jansson.c | 1 - 1 file changed, 1 deletion(-) diff --git a/blkmaker_jansson.c b/blkmaker_jansson.c index f2d4ad5..21b3741 100644 --- a/blkmaker_jansson.c +++ b/blkmaker_jansson.c @@ -298,7 +298,6 @@ const char *blktmpl_add_jansson(blktemplate_t *tmpl, const json_t *json, time_t } else { tmpl->txns_sigops += txn->sigops_; } - tmpl->txns_sigops += txn->sigops_; } if ((v = json_object_get(json, "coinbasetxn")) && json_is_object(v))