From 5f85cc7e3de03e87ac45567770e952f0779f7d34 Mon Sep 17 00:00:00 2001
From: moneromooo-monero <moneromooo-monero@users.noreply.github.com>
Date: Thu, 1 Mar 2018 14:16:34 +0000
Subject: [PATCH 1/2] wallet2: guard against overflowing of subaddress indices

---
 src/wallet/wallet2.cpp | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index d845dd896..e05a6318d 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -582,6 +582,14 @@ tools::wallet2::tx_construction_data get_construction_data_with_decrypted_short_
   return construction_data;
 }
 
+uint32_t get_subaddress_clamped_sum(uint32_t idx, uint32_t extra)
+{
+  static constexpr uint32_t uint32_max = std::numeric_limits<uint32_t>::max();
+  if (idx > uint32_max - extra)
+    return uint32_max;
+  return idx + extra;
+}
+
   //-----------------------------------------------------------------
 } //namespace
 
@@ -876,9 +884,10 @@ void wallet2::expand_subaddresses(const cryptonote::subaddress_index& index)
   {
     // add new accounts
     cryptonote::subaddress_index index2;
-    for (index2.major = m_subaddress_labels.size(); index2.major < index.major + m_subaddress_lookahead_major; ++index2.major)
+    const uint32_t major_end = get_subaddress_clamped_sum(index.major, m_subaddress_lookahead_major);
+    for (index2.major = m_subaddress_labels.size(); index2.major < major_end; ++index2.major)
     {
-      const uint32_t end = (index2.major == index.major ? index.minor : 0) + m_subaddress_lookahead_minor;
+      const uint32_t end = get_subaddress_clamped_sum((index2.major == index.major ? index.minor : 0), m_subaddress_lookahead_minor);
       const std::vector<crypto::public_key> pkeys = cryptonote::get_subaddress_spend_public_keys(m_account.get_keys(), index2.major, 0, end, hwdev);
       for (index2.minor = 0; index2.minor < end; ++index2.minor)
       {
@@ -892,7 +901,7 @@ void wallet2::expand_subaddresses(const cryptonote::subaddress_index& index)
   else if (m_subaddress_labels[index.major].size() <= index.minor)
   {
     // add new subaddresses
-    const uint32_t end = index.minor + m_subaddress_lookahead_minor;
+    const uint32_t end = get_subaddress_clamped_sum(index.minor, m_subaddress_lookahead_minor);
     const uint32_t begin = m_subaddress_labels[index.major].size();
     cryptonote::subaddress_index index2 = {index.major, begin};
     const std::vector<crypto::public_key> pkeys = cryptonote::get_subaddress_spend_public_keys(m_account.get_keys(), index2.major, index2.minor, end, hwdev);
@@ -924,6 +933,8 @@ void wallet2::set_subaddress_label(const cryptonote::subaddress_index& index, co
 //----------------------------------------------------------------------------------------------------
 void wallet2::set_subaddress_lookahead(size_t major, size_t minor)
 {
+  THROW_WALLET_EXCEPTION_IF(major > 0xffffffff, error::wallet_internal_error, "Subaddress major lookahead is too large");
+  THROW_WALLET_EXCEPTION_IF(minor > 0xffffffff, error::wallet_internal_error, "Subaddress minor lookahead is too large");
   m_subaddress_lookahead_major = major;
   m_subaddress_lookahead_minor = minor;
 }

From 91d97dd4abc5f155ec7a30b395eddc6fba1e2d32 Mon Sep 17 00:00:00 2001
From: moneromooo-monero <moneromooo-monero@users.noreply.github.com>
Date: Thu, 1 Mar 2018 14:16:51 +0000
Subject: [PATCH 2/2] fuzz_tests: set small subaddress lookahead for speed

---
 tests/fuzz/cold-outputs.cpp     | 1 +
 tests/fuzz/cold-transaction.cpp | 1 +
 tests/fuzz/signature.cpp        | 1 +
 3 files changed, 3 insertions(+)

diff --git a/tests/fuzz/cold-outputs.cpp b/tests/fuzz/cold-outputs.cpp
index 9aa9460d5..59b59810c 100644
--- a/tests/fuzz/cold-outputs.cpp
+++ b/tests/fuzz/cold-outputs.cpp
@@ -54,6 +54,7 @@ int ColdOutputsFuzzer::init()
   try
   {
     wallet.init("");
+    wallet.set_subaddress_lookahead(1, 1);
     wallet.generate("", "", spendkey, true, false);
   }
   catch (const std::exception &e)
diff --git a/tests/fuzz/cold-transaction.cpp b/tests/fuzz/cold-transaction.cpp
index d81092c82..da33dc318 100644
--- a/tests/fuzz/cold-transaction.cpp
+++ b/tests/fuzz/cold-transaction.cpp
@@ -55,6 +55,7 @@ int ColdTransactionFuzzer::init()
   try
   {
     wallet.init("");
+    wallet.set_subaddress_lookahead(1, 1);
     wallet.generate("", "", spendkey, true, false);
   }
   catch (const std::exception &e)
diff --git a/tests/fuzz/signature.cpp b/tests/fuzz/signature.cpp
index 2b8ffe465..7f22757b2 100644
--- a/tests/fuzz/signature.cpp
+++ b/tests/fuzz/signature.cpp
@@ -55,6 +55,7 @@ int SignatureFuzzer::init()
   try
   {
     wallet.init("");
+    wallet.set_subaddress_lookahead(1, 1);
     wallet.generate("", "", spendkey, true, false);
 
     cryptonote::address_parse_info info;