Skip to content

Commit

Permalink
Merge pull request #1966 from AntelopeIO/dec2023_security_50
Browse files Browse the repository at this point in the history
[4.0 -> 5.0] consolidated security fixes for 5.0.0-rc3
  • Loading branch information
spoonincode authored Dec 7, 2023
2 parents 1a029ea + 3a61aa4 commit 52523d6
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 2 deletions.
31 changes: 31 additions & 0 deletions libraries/chain/include/eosio/chain/contract_table_objects.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <eosio/chain/database_utils.hpp>
#include <eosio/chain/contract_types.hpp>
#include <eosio/chain/multi_index_includes.hpp>
#include <eosio/chain/snapshot.hpp>
#include <eosio/chain/database_utils.hpp>

#include <array>
#include <type_traits>
Expand Down Expand Up @@ -282,6 +284,35 @@ namespace config {

} // namespace config

namespace detail {
template<>
struct snapshot_row_traits<key_value_object> {
using value_type = key_value_object;
using snapshot_type = snapshot_key_value_object;

static snapshot_key_value_object to_snapshot_row(const key_value_object& value, const chainbase::database&) {
snapshot_key_value_object ret;

ret.primary_key = value.primary_key;
ret.payer = value.payer;
if(value.value.size()) {
ret.value.resize(value.value.size());
memcpy(ret.value.data(), value.value.data(), value.value.size());
}
return ret;
};

static void from_snapshot_row(snapshot_key_value_object&& row, key_value_object& value, chainbase::database&) {
value.primary_key = row.primary_key;
value.payer = row.payer;
if(row.value.size())
value.value.resize_and_fill(row.value.size(), [&](char* data, std::size_t size) {
memcpy(data, row.value.data(), size);
});
}
};
}

} } // namespace eosio::chain

CHAINBASE_SET_INDEX_TYPE(eosio::chain::table_id_object, eosio::chain::table_id_multi_index)
Expand Down
50 changes: 50 additions & 0 deletions libraries/chain/include/eosio/chain/database_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,42 @@ namespace eosio { namespace chain {
fc::raw::unpack(ds, static_cast<shared_string &>(b));
return ds;
}

namespace detail {
struct snapshot_key_value_object {
template<typename Stream>
friend Stream& operator>>(Stream& ds, snapshot_key_value_object& o) {
fc::raw::unpack(ds, o.primary_key);
fc::raw::unpack(ds, o.payer);

fc::unsigned_int sz;
fc::raw::unpack(ds, sz);
if(sz) {
o.value.resize(sz);
ds.read(o.value.data(), sz);
}

return ds;
}

template<typename Stream>
friend Stream& operator<<(Stream& ds, const snapshot_key_value_object& o) {
fc::raw::pack(ds, o.primary_key);
fc::raw::pack(ds, o.payer);

fc::raw::pack(ds, fc::unsigned_int(o.value.size()));
if(o.value.size())
ds.write(o.value.data(), o.value.size());

return ds;
}

uint64_t primary_key;
account_name payer;
std::vector<char> value;
};
}

} }

namespace fc {
Expand Down Expand Up @@ -197,6 +233,20 @@ namespace fc {
from_variant(v, _v);
sv = eosio::chain::shared_vector<T>(_v.begin(), _v.end(), sv.get_allocator());
}

inline
void to_variant(const eosio::chain::detail::snapshot_key_value_object& a, fc::variant& v) {
v = fc::mutable_variant_object("primary_key", a.primary_key)
("payer", a.payer)
("value", base64_encode(a.value.data(), a.value.size()));
}

inline
void from_variant(const fc::variant& v, eosio::chain::detail::snapshot_key_value_object& a) {
from_variant(v["primary_key"], a.primary_key);
from_variant(v["payer"], a.payer);
a.value = base64_decode(v["value"].as_string());
}
}

namespace chainbase {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ datastream<ST>& operator<<(datastream<ST>& ds, const eosio::state_history::big_v
return ds;
}

template <typename ST>
datastream<ST>& operator<<(datastream<ST>& ds, const eosio::state_history::row_pair& rp) {
fc::raw::pack(ds, rp.first);
history_pack_big_bytes(ds, rp.second);
return ds;
}

template <typename ST>
inline void history_pack_varuint64(datastream<ST>& ds, uint64_t val) {
do {
Expand All @@ -136,6 +143,12 @@ void history_pack_big_bytes(datastream<ST>& ds, const eosio::chain::bytes& v) {
ds.write(&v.front(), v.size());
}

template <typename ST>
void history_pack_big_bytes(datastream<ST>& ds, const eosio::chain::shared_blob& b) {
fc::raw::pack(ds, unsigned_int((uint32_t)b.size()));
ds.write(b.data(), b.size());
}

template <typename ST>
void history_pack_big_bytes(datastream<ST>& ds, const std::optional<eosio::chain::bytes>& v) {
fc::raw::pack(ds, v.has_value());
Expand Down Expand Up @@ -223,7 +236,7 @@ datastream<ST>& operator<<(datastream<ST>& ds, const history_context_wrapper_sta
fc::raw::pack(ds, as_type<uint64_t>(obj.context.table.to_uint64_t()));
fc::raw::pack(ds, as_type<uint64_t>(obj.obj.primary_key));
fc::raw::pack(ds, as_type<uint64_t>(obj.obj.payer.to_uint64_t()));
fc::raw::pack(ds, as_type<eosio::chain::shared_string>(obj.obj.value));
history_pack_big_bytes(ds, obj.obj.value);
return ds;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ struct big_vector_wrapper {
T obj;
};

struct row_pair {
row_pair() {}
row_pair(const bool f, const bytes& s) : first(f), second(s){}
bool first = false;
bytes second;
};

struct partial_transaction {
fc::time_point_sec expiration = {};
uint16_t ref_block_num = {};
Expand Down Expand Up @@ -66,7 +73,7 @@ struct augmented_transaction_trace {
struct table_delta {
fc::unsigned_int struct_version = 0;
std::string name{};
state_history::big_vector_wrapper<std::vector<std::pair<bool, bytes>>> rows{};
state_history::big_vector_wrapper<std::vector<row_pair>> rows{};
};

struct block_position {
Expand Down
12 changes: 12 additions & 0 deletions unittests/state_history_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ bool operator==(const eosio::checksum256& lhs, const transaction_id_type& rhs) {

namespace eosio::state_history {

template <typename ST>
datastream<ST>& operator>>(datastream<ST>& ds, row_pair& rp) {
fc::raw::unpack(ds, rp.first);
fc::unsigned_int sz;
fc::raw::unpack(ds, sz);
if(sz) {
rp.second.resize(sz);
ds.read(rp.second.data(), sz);
}
return ds;
}

template <typename ST, typename T>
datastream<ST>& operator>>(datastream<ST>& ds, eosio::state_history::big_vector_wrapper<T>& obj) {
fc::unsigned_int sz;
Expand Down

0 comments on commit 52523d6

Please sign in to comment.