Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
/* 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*/);
}