int serialize_msgheader(struct buff *buf, const btc_msg_header *h) { int res; res = serialize_uint32(buf, h->magic); res |= serialize_bytes(buf, h->message, ARRAYSIZE(h->message)); res |= serialize_uint32(buf, h->payloadLength); res |= serialize_bytes(buf, h->checksum, ARRAYSIZE(h->checksum)); ASSERT_NOT_TESTED(res == 0); return res; }
int deserialize_tx(struct buff *buf, btc_msg_tx *tx) { uint64 i; int res; res = deserialize_uint32(buf, &tx->version); res |= deserialize_varint(buf, &tx->in_count); tx->tx_in = safe_malloc(tx->in_count * sizeof *tx->tx_in); for (i = 0; i < tx->in_count; i++) { res |= deserialize_uint256(buf, &tx->tx_in[i].prevTxHash); res |= deserialize_uint32(buf, &tx->tx_in[i].prevTxOutIdx); res |= deserialize_varint(buf, &tx->tx_in[i].scriptLength); tx->tx_in[i].scriptSig = safe_malloc(tx->tx_in[i].scriptLength); res |= deserialize_bytes(buf, tx->tx_in[i].scriptSig, tx->tx_in[i].scriptLength); res |= deserialize_uint32(buf, &tx->tx_in[i].sequence); } res |= deserialize_varint(buf, &tx->out_count); tx->tx_out = safe_malloc(tx->out_count * sizeof *tx->tx_out); for (i = 0; i < tx->out_count; i++) { res |= deserialize_uint64(buf, &tx->tx_out[i].value); res |= deserialize_varint(buf, &tx->tx_out[i].scriptLength); tx->tx_out[i].scriptPubKey = safe_malloc(tx->tx_out[i].scriptLength); res |= deserialize_bytes(buf, tx->tx_out[i].scriptPubKey, tx->tx_out[i].scriptLength); } res |= deserialize_uint32(buf, &tx->lock_time); ASSERT_NOT_TESTED(buff_space_left(buf) == 0); return res; }
/* This is the actual nudge handler * Notes: This function returns a boolean mainly to fix case 5130; it is not * really necessary. */ bool generic_nudge_handler(nudge_arg_t *arg_dont_use) { dcontext_t *dcontext = get_thread_private_dcontext(); nudge_arg_t safe_arg = {0}; uint nudge_action_mask = 0; #ifdef WINDOWS /* this routine is run natively via leave_call_native() so there's no * cxt switch that swapped for us */ if (dcontext != NULL) swap_peb_pointer(dcontext, true/*to priv*/); #endif /* To be extra safe we use safe_read() to access the nudge argument, though once * we get past the checks below we are trusting its content. */ ASSERT(arg_dont_use != NULL && "invalid nudge argument"); if (!safe_read(arg_dont_use, sizeof(nudge_arg_t), &safe_arg)) { ASSERT(false && "invalid nudge argument"); goto nudge_finished; } nudge_action_mask = safe_arg.nudge_action_mask; /* if needed tell thread exit to free the application stack */ if (!TEST(NUDGE_NUDGER_FREE_STACK, safe_arg.flags)) { dcontext->free_app_stack = true; } else { ASSERT_NOT_TESTED(); } /* FIXME - would be nice to inform nudge creator if we need to nop the nudge. */ /* Fix for case 5702. If a nudge thread comes in during process exit, * don't process it, i.e., nop it. FIXME - this leaks the app stack and nudge arg * if the nudge was supposed to free them. */ if (dynamo_exited) goto nudge_finished; /* Node manager will not be able to nudge before reading the drmarker and * the dr_marker isn't available before callback_interception_init(). * Since after callback_interception_init() new threads won't be allowed * to progress till dynamo_initialized is set, by the time a nudge thread * reaches here dynamo_initialized should be set. */ ASSERT(dynamo_initialized); if (!dynamo_initialized) goto nudge_finished; /* We should always have a dcontext. */ ASSERT(dcontext != NULL); if (dcontext == NULL) goto nudge_finished; ENTERING_DR(); /* Xref case 552, the nudge_target value provides a reasonable measure * of security against an attacker leveraging this routine. */ if (dcontext->nudge_target != (void *)generic_nudge_target) { /* FIXME - should we report this likely attempt to attack us? need * a unit test for this (though will then have to tone this down). */ ASSERT(false && "unauthorized thread tried to nudge"); /* If we really are under attack we should terminate immediately and * proceed no further. Note we are leaking the app stack and nudge arg if we * were supposed to free them. */ os_terminate(dcontext, TERMINATE_THREAD); ASSERT_NOT_REACHED(); } /* Free the arg if requested. */ if (TEST(NUDGE_FREE_ARG, safe_arg.flags)) { ASSERT_NOT_TESTED(); nt_free_virtual_memory(arg_dont_use); } handle_nudge(dcontext, &safe_arg); nudge_finished: return nudge_thread_cleanup(dcontext, false/*just thread*/, 0/*unused*/); }