diff options
author | John Hodge <tpg@ucc.asn.au> | 2019-08-04 17:22:04 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2019-08-04 17:22:04 +0800 |
commit | e88271aae2b141124f45879664afc3d839f4194e (patch) | |
tree | f22e9c81ee11e32a5723f2bd5568e6ad97fd8a1f | |
parent | e14473dcce910959a3f6a3c0c683456ab0f9dd1a (diff) | |
download | mrust-e88271aae2b141124f45879664afc3d839f4194e.tar.gz |
Standalone MIRI - Fix OOB write caused by storing too much in a value inline
-rw-r--r-- | tools/standalone_miri/value.cpp | 17 |
1 files changed, 7 insertions, 10 deletions
diff --git a/tools/standalone_miri/value.cpp b/tools/standalone_miri/value.cpp index 58ad7292..601c1d6c 100644 --- a/tools/standalone_miri/value.cpp +++ b/tools/standalone_miri/value.cpp @@ -613,8 +613,7 @@ void Allocation::set_reloc(size_t ofs, size_t len, RelocationPtr reloc) Value::Value() { this->direct_data.size = 0; - this->direct_data.mask[0] = 0; - this->direct_data.mask[1] = 0; + memset(this->direct_data.mask, 0, sizeof(this->direct_data.mask)); } Value::Value(::HIR::TypeRef ty) { @@ -642,15 +641,14 @@ Value::Value(::HIR::TypeRef ty) Value Value::with_size(size_t size, bool have_allocation) { Value rv; - if(have_allocation) + if(have_allocation || size > sizeof(rv.direct_data.data)) { rv.allocation = Allocation::new_alloc(size, FMT_STRING("with_size(" << size << ")")); } else { rv.direct_data.size = static_cast<uint8_t>(size); - rv.direct_data.mask[0] = 0; - rv.direct_data.mask[1] = 0; + memset(rv.direct_data.mask, 0, sizeof(rv.direct_data.mask)); } return rv; } @@ -768,7 +766,7 @@ Value Value::read_value(size_t ofs, size_t size) const } else { - // Inline can become inline. + // Inline always fits in inline. rv.direct_data.size = static_cast<uint8_t>(size); rv.write_bytes(0, this->direct_data.data+ofs, size); rv.direct_data.mask[0] = this->direct_data.mask[0]; @@ -1033,20 +1031,19 @@ Value ValueRef::read_value(size_t ofs, size_t size) const case RelocationPtr::Ty::Allocation: return m_alloc.alloc().read_value(m_offset + ofs, size); case RelocationPtr::Ty::StdString: { + LOG_ASSERT(in_bounds(m_offset + ofs, size, m_alloc.str().size()), ""); auto rv = Value::with_size(size, false); - LOG_ASSERT(in_bounds(ofs, size, m_alloc.str().size()), ""); rv.write_bytes(0, m_alloc.str().data() + m_offset + ofs, size); return rv; } case RelocationPtr::Ty::FfiPointer: { + LOG_ASSERT(in_bounds(m_offset + ofs, size, m_alloc.ffi().get_size()), ""); auto rv = Value::with_size(size, false); - LOG_ASSERT(in_bounds(ofs, size, m_alloc.ffi().get_size()), ""); rv.write_bytes(0, reinterpret_cast<const char*>(m_alloc.ffi().ptr_value) + m_offset + ofs, size); return rv; } - default: { + default: LOG_TODO("read_value from " << m_alloc); - } } } else { |