aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--contrib/epee/src/mlog.cpp13
-rw-r--r--contrib/epee/src/readline_buffer.cpp4
-rw-r--r--contrib/gitian/gitian-linux.yml11
-rw-r--r--external/easylogging++/easylogging++.cc5
-rw-r--r--src/crypto/jh.c17
-rw-r--r--src/cryptonote_config.h1
-rw-r--r--src/multisig/multisig_kex_msg.cpp9
-rw-r--r--src/ringct/rctTypes.h12
-rw-r--r--src/wallet/wallet2.cpp26
9 files changed, 86 insertions, 12 deletions
diff --git a/contrib/epee/src/mlog.cpp b/contrib/epee/src/mlog.cpp
index 092d41777..4ca1a3632 100644
--- a/contrib/epee/src/mlog.cpp
+++ b/contrib/epee/src/mlog.cpp
@@ -338,11 +338,21 @@ bool is_stdout_a_tty()
return is_a_tty.load(std::memory_order_relaxed);
}
+static bool is_nocolor()
+{
+ static const char *no_color_var = getenv("NO_COLOR");
+ static const bool no_color = no_color_var && *no_color_var; // apparently, NO_COLOR=0 means no color too (as per no-color.org)
+ return no_color;
+}
+
void set_console_color(int color, bool bright)
{
if (!is_stdout_a_tty())
return;
+ if (is_nocolor())
+ return;
+
switch(color)
{
case console_color_default:
@@ -461,6 +471,9 @@ void reset_console_color() {
if (!is_stdout_a_tty())
return;
+ if (is_nocolor())
+ return;
+
#ifdef WIN32
HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(h_stdout, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
diff --git a/contrib/epee/src/readline_buffer.cpp b/contrib/epee/src/readline_buffer.cpp
index 1047d1696..ac68d1fdb 100644
--- a/contrib/epee/src/readline_buffer.cpp
+++ b/contrib/epee/src/readline_buffer.cpp
@@ -238,6 +238,10 @@ static char** attempted_completion(const char* text, int start, int end)
static void install_line_handler()
{
+#if RL_READLINE_VERSION >= 0x0801
+ rl_variable_bind("enable-bracketed-paste", "off");
+#endif
+
rl_attempted_completion_function = attempted_completion;
rl_callback_handler_install("", handle_line);
stifle_history(500);
diff --git a/contrib/gitian/gitian-linux.yml b/contrib/gitian/gitian-linux.yml
index 63d2bc5d2..41915deb9 100644
--- a/contrib/gitian/gitian-linux.yml
+++ b/contrib/gitian/gitian-linux.yml
@@ -21,6 +21,7 @@ packages:
- "g++-7-arm-linux-gnueabihf"
- "gcc-arm-linux-gnueabihf"
- "g++-arm-linux-gnueabihf"
+- "g++-riscv64-linux-gnu"
- "g++-7-multilib"
- "gcc-7-multilib"
- "binutils-arm-linux-gnueabihf"
@@ -43,7 +44,7 @@ files: []
script: |
WRAP_DIR=$HOME/wrapped
- HOSTS="x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu i686-linux-gnu"
+ HOSTS="x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu i686-linux-gnu riscv64-linux-gnu"
FAKETIME_HOST_PROGS=""
FAKETIME_PROGS="date"
HOST_CFLAGS="-O2 -g"
@@ -159,7 +160,13 @@ script: |
fi
export C_INCLUDE_PATH="$EXTRA_INCLUDES"
export CPLUS_INCLUDE_PATH="$EXTRA_INCLUDES"
- cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake -DBACKCOMPAT=ON -DCMAKE_SKIP_RPATH=ON
+ # glibc only added riscv support in 2.27, disable backwards compatibility
+ if [ "$i" == "riscv64-linux-gnu" ]; then
+ BACKCOMPAT_OPTION=OFF
+ else
+ BACKCOMPAT_OPTION=ON
+ fi
+ cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake -DBACKCOMPAT=${BACKCOMPAT_OPTION} -DCMAKE_SKIP_RPATH=ON
make ${MAKEOPTS}
chmod 755 bin/*
cp ../LICENSE ../README.md ../docs/ANONYMITY_NETWORKS.md bin
diff --git a/external/easylogging++/easylogging++.cc b/external/easylogging++/easylogging++.cc
index a765ee8cc..891936b6b 100644
--- a/external/easylogging++/easylogging++.cc
+++ b/external/easylogging++/easylogging++.cc
@@ -149,6 +149,11 @@ static el::Color colorFromLevel(el::Level level)
static void setConsoleColor(el::Color color, bool bright)
{
+ static const char *no_color_var = getenv("NO_COLOR");
+ static const bool no_color = no_color_var && *no_color_var; // apparently, NO_COLOR=0 means no color too (as per no-color.org)
+ if (no_color)
+ return;
+
#if ELPP_OS_WINDOWS
HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
switch (color)
diff --git a/src/crypto/jh.c b/src/crypto/jh.c
index 12d536375..738c681f8 100644
--- a/src/crypto/jh.c
+++ b/src/crypto/jh.c
@@ -34,7 +34,7 @@ typedef struct {
unsigned long long databitlen; /*the message size in bits*/
unsigned long long datasize_in_buffer; /*the size of the message remained in buffer; assumed to be multiple of 8bits except for the last partial block at the end of the message*/
DATA_ALIGN16(uint64 x[8][2]); /*the 1024-bit state, ( x[i][0] || x[i][1] ) is the ith row of the state in the pseudocode*/
- unsigned char buffer[64]; /*the 512-bit message block to be hashed;*/
+ DATA_ALIGN16(unsigned char buffer[64]); /*the 512-bit message block to be hashed;*/
} hashState;
@@ -213,16 +213,24 @@ static void E8(hashState *state)
/*The compression function F8 */
static void F8(hashState *state)
{
- uint64 i;
+ uint64_t* x = (uint64_t*)state->x;
/*xor the 512-bit message with the fist half of the 1024-bit hash state*/
- for (i = 0; i < 8; i++) state->x[i >> 1][i & 1] ^= ((uint64*)state->buffer)[i];
+ for (int i = 0; i < 8; ++i) {
+ uint64 b;
+ memcpy(&b, &state->buffer[i << 3], sizeof(b));
+ x[i] ^= b;
+ }
/*the bijective function E8 */
E8(state);
/*xor the 512-bit message with the second half of the 1024-bit hash state*/
- for (i = 0; i < 8; i++) state->x[(8+i) >> 1][(8+i) & 1] ^= ((uint64*)state->buffer)[i];
+ for (int i = 0; i < 8; ++i) {
+ uint64 b;
+ memcpy(&b, &state->buffer[i << 3], sizeof(b));
+ x[i + 8] ^= b;
+ }
}
/*before hashing a message, initialize the hash state as H0 */
@@ -240,6 +248,7 @@ static HashReturn Init(hashState *state, int hashbitlen)
case 224: memcpy(state->x,JH224_H0,128); break;
case 256: memcpy(state->x,JH256_H0,128); break;
case 384: memcpy(state->x,JH384_H0,128); break;
+ default:
case 512: memcpy(state->x,JH512_H0,128); break;
}
diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h
index bac49aa94..61146a114 100644
--- a/src/cryptonote_config.h
+++ b/src/cryptonote_config.h
@@ -30,6 +30,7 @@
#pragma once
+#include <cstdint>
#include <stdexcept>
#include <string>
#include <boost/uuid/uuid.hpp>
diff --git a/src/multisig/multisig_kex_msg.cpp b/src/multisig/multisig_kex_msg.cpp
index c717e23ad..024d71df7 100644
--- a/src/multisig/multisig_kex_msg.cpp
+++ b/src/multisig/multisig_kex_msg.cpp
@@ -206,8 +206,13 @@ namespace multisig
//----------------------------------------------------------------------------------------------------------------------
void multisig_kex_msg::parse_and_validate_msg()
{
+ CHECK_AND_ASSERT_THROW_MES(MULTISIG_KEX_MSG_V2_MAGIC_1.size() == MULTISIG_KEX_MSG_V2_MAGIC_N.size(),
+ "Multisig kex msg magic inconsistency.");
+ CHECK_AND_ASSERT_THROW_MES(MULTISIG_KEX_MSG_V2_MAGIC_1.size() >= MULTISIG_KEX_V1_MAGIC.size(),
+ "Multisig kex msg magic inconsistency.");
+
// check message type
- CHECK_AND_ASSERT_THROW_MES(m_msg.size() > 0, "Kex message unexpectedly empty.");
+ CHECK_AND_ASSERT_THROW_MES(m_msg.size() >= MULTISIG_KEX_MSG_V2_MAGIC_1.size(), "Kex message unexpectedly small.");
CHECK_AND_ASSERT_THROW_MES(m_msg.substr(0, MULTISIG_KEX_V1_MAGIC.size()) != MULTISIG_KEX_V1_MAGIC,
"V1 multisig kex messages are deprecated (unsafe).");
CHECK_AND_ASSERT_THROW_MES(m_msg.substr(0, MULTISIG_KEX_MSG_V1_MAGIC.size()) != MULTISIG_KEX_MSG_V1_MAGIC,
@@ -215,8 +220,6 @@ namespace multisig
// deserialize the message
std::string msg_no_magic;
- CHECK_AND_ASSERT_THROW_MES(MULTISIG_KEX_MSG_V2_MAGIC_1.size() == MULTISIG_KEX_MSG_V2_MAGIC_N.size(),
- "Multisig kex msg magic inconsistency.");
CHECK_AND_ASSERT_THROW_MES(tools::base58::decode(m_msg.substr(MULTISIG_KEX_MSG_V2_MAGIC_1.size()), msg_no_magic),
"Multisig kex msg decoding error.");
binary_archive<false> b_archive{epee::strspan<std::uint8_t>(msg_no_magic)};
diff --git a/src/ringct/rctTypes.h b/src/ringct/rctTypes.h
index ab1a26b26..32cd8dc6f 100644
--- a/src/ringct/rctTypes.h
+++ b/src/ringct/rctTypes.h
@@ -362,11 +362,17 @@ namespace rct {
{
if (type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeBulletproofPlus)
{
+ // Since RCTTypeBulletproof2 enote types, we don't serialize the blinding factor, and only serialize the
+ // first 8 bytes of ecdhInfo[i].amount
ar.begin_object();
- if (!typename Archive<W>::is_saving())
+ crypto::hash8 trunc_amount; // placeholder variable needed to maintain "strict aliasing"
+ if (!typename Archive<W>::is_saving()) // loading
memset(ecdhInfo[i].amount.bytes, 0, sizeof(ecdhInfo[i].amount.bytes));
- crypto::hash8 &amount = (crypto::hash8&)ecdhInfo[i].amount;
- FIELD(amount);
+ else // saving
+ memcpy(trunc_amount.data, ecdhInfo[i].amount.bytes, sizeof(trunc_amount));
+ FIELD(trunc_amount);
+ if (!typename Archive<W>::is_saving()) // loading
+ memcpy(ecdhInfo[i].amount.bytes, trunc_amount.data, sizeof(trunc_amount));
ar.end_object();
}
else
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index d99ebc386..0218c8292 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -6244,6 +6244,20 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
if (!m_persistent_rpc_client_id)
set_rpc_client_secret_key(rct::rct2sk(rct::skGen()));
+ // Wallets used to wipe, but not erase, old unused multisig key info, which lead to huge memory leaks.
+ // Here we erase these multisig keys if they're zero'd out to free up space.
+ for (auto &td : m_transfers)
+ {
+ auto mk_it = td.m_multisig_k.begin();
+ while (mk_it != td.m_multisig_k.end())
+ {
+ if (*mk_it == rct::zero())
+ mk_it = td.m_multisig_k.erase(mk_it);
+ else
+ ++mk_it;
+ }
+ }
+
cryptonote::block genesis;
generate_genesis(genesis);
crypto::hash genesis_hash = get_block_hash(genesis);
@@ -7123,7 +7137,10 @@ void wallet2::commit_tx(pending_tx& ptx)
// tx generated, get rid of used k values
for (size_t idx: ptx.selected_transfers)
+ {
memwipe(m_transfers[idx].m_multisig_k.data(), m_transfers[idx].m_multisig_k.size() * sizeof(m_transfers[idx].m_multisig_k[0]));
+ m_transfers[idx].m_multisig_k.clear();
+ }
//fee includes dust if dust policy specified it.
LOG_PRINT_L1("Transaction successfully sent. <" << txid << ">" << ENDL
@@ -7627,7 +7644,10 @@ std::string wallet2::save_multisig_tx(multisig_tx_set txs)
// txes generated, get rid of used k values
for (size_t n = 0; n < txs.m_ptx.size(); ++n)
for (size_t idx: txs.m_ptx[n].construction_data.selected_transfers)
+ {
memwipe(m_transfers[idx].m_multisig_k.data(), m_transfers[idx].m_multisig_k.size() * sizeof(m_transfers[idx].m_multisig_k[0]));
+ m_transfers[idx].m_multisig_k.clear();
+ }
// zero out some data we don't want to share
for (auto &ptx: txs.m_ptx)
@@ -7951,7 +7971,10 @@ bool wallet2::sign_multisig_tx(multisig_tx_set &exported_txs, std::vector<crypto
// inputs in the transactions worked on here)
for (size_t n = 0; n < exported_txs.m_ptx.size(); ++n)
for (size_t idx: exported_txs.m_ptx[n].construction_data.selected_transfers)
+ {
memwipe(m_transfers[idx].m_multisig_k.data(), m_transfers[idx].m_multisig_k.size() * sizeof(m_transfers[idx].m_multisig_k[0]));
+ m_transfers[idx].m_multisig_k.clear();
+ }
exported_txs.m_signers.insert(get_multisig_signer_public_key());
@@ -14266,7 +14289,10 @@ cryptonote::blobdata wallet2::export_multisig()
transfer_details &td = m_transfers[n];
crypto::key_image ki;
if (td.m_multisig_k.size())
+ {
memwipe(td.m_multisig_k.data(), td.m_multisig_k.size() * sizeof(td.m_multisig_k[0]));
+ td.m_multisig_k.clear();
+ }
info[n].m_LR.clear();
info[n].m_partial_key_images.clear();