diff options
| author | John Hodge <tpg@ucc.asn.au> | 2019-08-04 15:08:30 +0800 |
|---|---|---|
| committer | John Hodge <tpg@ucc.asn.au> | 2019-08-04 15:08:30 +0800 |
| commit | e14473dcce910959a3f6a3c0c683456ab0f9dd1a (patch) | |
| tree | 9463451f3f755bee4bcd2e652c3b04a8daa88dc5 /tools/standalone_miri/value.cpp | |
| parent | 982826e4b309979bee8fe10f6ff537b4922e6316 (diff) | |
| download | mrust-e14473dcce910959a3f6a3c0c683456ab0f9dd1a.tar.gz | |
Standalone MIRI - Restructure so `0` is never a valid pointer value
Diffstat (limited to 'tools/standalone_miri/value.cpp')
| -rw-r--r-- | tools/standalone_miri/value.cpp | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/tools/standalone_miri/value.cpp b/tools/standalone_miri/value.cpp index 232613b7..58ad7292 100644 --- a/tools/standalone_miri/value.cpp +++ b/tools/standalone_miri/value.cpp @@ -241,6 +241,8 @@ void ValueCommonWrite::write_usize(size_t ofs, uint64_t v) void* ValueCommonRead::read_pointer_unsafe(size_t rd_ofs, size_t req_valid, size_t& out_size, bool& out_is_mut) const { auto ofs = read_usize(rd_ofs); + LOG_ASSERT(ofs >= Allocation::PTR_BASE, "Deref of invalid pointer"); + ofs -= Allocation::PTR_BASE; auto reloc = get_relocation(rd_ofs); if( !reloc ) { @@ -260,10 +262,7 @@ void* ValueCommonRead::read_pointer_unsafe(size_t rd_ofs, size_t req_valid, size { case RelocationPtr::Ty::Allocation: { auto& a = reloc.alloc(); - if( ofs > a.size() ) - LOG_FATAL("Out-of-bounds pointer"); - if( ofs + req_valid > a.size() ) - LOG_FATAL("Out-of-bounds pointer (" << ofs << " + " << req_valid << " > " << a.size()); + LOG_ASSERT(in_bounds(ofs, req_valid, a.size()), "Out-of-bounds pointer (" << ofs << " + " << req_valid << " > " << a.size() << ")"); a.check_bytes_valid( ofs, req_valid ); out_size = a.size() - ofs; out_is_mut = true; @@ -271,10 +270,7 @@ void* ValueCommonRead::read_pointer_unsafe(size_t rd_ofs, size_t req_valid, size } case RelocationPtr::Ty::StdString: { const auto& s = reloc.str(); - if( ofs > s.size() ) - LOG_FATAL("Out-of-bounds pointer"); - if( ofs + req_valid > s.size() ) - LOG_FATAL("Out-of-bounds pointer (" << ofs << " + " << req_valid << " > " << s.size()); + LOG_ASSERT(in_bounds(ofs, req_valid, s.size()), "Out-of-bounds pointer (" << ofs << " + " << req_valid << " > " << s.size() << ")"); out_size = s.size() - ofs; out_is_mut = false; return const_cast<void*>( static_cast<const void*>(s.data() + ofs) ); @@ -283,11 +279,13 @@ void* ValueCommonRead::read_pointer_unsafe(size_t rd_ofs, size_t req_valid, size LOG_FATAL("read_pointer w/ function"); case RelocationPtr::Ty::FfiPointer: { const auto& f = reloc.ffi(); + size_t size = f.get_size(); + LOG_ASSERT(in_bounds(ofs, req_valid, size), "Out-of-bounds pointer (" << ofs << " + " << req_valid << " > " << size << ")"); // TODO: Validity? //if( req_valid ) // LOG_FATAL("Can't request valid data from a FFI pointer"); // TODO: Have an idea of mutability and available size from FFI - out_size = f.get_size() - ofs; + out_size = size - ofs; out_is_mut = false; return reinterpret_cast<char*>(reloc.ffi().ptr_value) + ofs; } @@ -298,6 +296,8 @@ void* ValueCommonRead::read_pointer_unsafe(size_t rd_ofs, size_t req_valid, size ValueRef ValueCommonRead::read_pointer_valref_mut(size_t rd_ofs, size_t size) { auto ofs = read_usize(rd_ofs); + LOG_ASSERT(ofs >= Allocation::PTR_BASE, "Invalid pointer read"); + ofs -= Allocation::PTR_BASE; auto reloc = get_relocation(rd_ofs); if( !reloc ) { @@ -305,7 +305,21 @@ ValueRef ValueCommonRead::read_pointer_valref_mut(size_t rd_ofs, size_t size) } else { - // TODO: Validate size + // Validate size and offset are in bounds + switch(reloc.get_ty()) + { + case RelocationPtr::Ty::Allocation: + LOG_ASSERT( in_bounds(ofs, size, reloc.alloc().size()), "Deref with OOB size - " << ofs << "+" << size << " > " << reloc.alloc().size() ); + break; + case RelocationPtr::Ty::StdString: + LOG_ASSERT( in_bounds(ofs, size, reloc.str().size()), "Deref with OOB size - " << ofs << "+" << size << " > " << reloc.str().size() ); + break; + case RelocationPtr::Ty::Function: + LOG_FATAL("read_pointer_valref_mut w/ function"); + case RelocationPtr::Ty::FfiPointer: + LOG_ASSERT( in_bounds(ofs, size, reloc.ffi().get_size()), "Deref with OOB size - " << ofs << "+" << size << " > " << reloc.ffi().get_size() ); + break; + } return ValueRef(reloc, ofs, size); } } @@ -355,6 +369,7 @@ Value Allocation::read_value(size_t ofs, size_t size) const if( this->is_freed ) LOG_ERROR("Use of freed memory " << this); LOG_DEBUG(*this); + LOG_ASSERT( in_bounds(ofs, size, this->size()), "Read out of bounds (" << ofs << "+" << size << " > " << this->size() << ")" ); // Determine if this can become an inline allocation. bool has_reloc = false; @@ -539,6 +554,7 @@ void Allocation::write_bytes(size_t ofs, const void* src, size_t count) } void Allocation::write_ptr(size_t ofs, size_t ptr_ofs, RelocationPtr reloc) { + LOG_ASSERT(ptr_ofs >= Allocation::PTR_BASE, "Invalid pointer being written"); this->write_usize(ofs, ptr_ofs); this->set_reloc(ofs, POINTER_SIZE, ::std::move(reloc)); } @@ -643,7 +659,7 @@ Value Value::new_fnptr(const ::HIR::Path& fn_path) Value rv( ::HIR::TypeRef(::HIR::CoreType { RawType::Function }) ); assert(rv.allocation); rv.allocation->relocations.push_back(Relocation { 0, RelocationPtr::new_fcn(fn_path) }); - rv.allocation->data.at(0) = 0; + rv.allocation->data.at(0) = Allocation::PTR_BASE; rv.allocation->mask.at(0) = 0xFF; // TODO: Get pointer size and make that much valid instead of 8 bytes return rv; } |
