aboutsummaryrefslogtreecommitdiff
path: root/fesvr/device.cc
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2021-08-26 15:48:15 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2021-08-26 15:48:15 +0000
commitfc99a20295e86e4ce21d052e05fcabcc225dbbf0 (patch)
treef1830860afd9fc84e22c8416eef2f1b033e3f00c /fesvr/device.cc
parent719e929e638b884b99de2a90dad6c2b47a643969 (diff)
downloadspike-fc99a20295e86e4ce21d052e05fcabcc225dbbf0.zip
spike-fc99a20295e86e4ce21d052e05fcabcc225dbbf0.tar.gz
spike-fc99a20295e86e4ce21d052e05fcabcc225dbbf0.tar.bz2
fesvr: replace use of `std::vector::operator[0]`
This replaces multiple uses of `std::vector::operator[]` where the parameter is a constant `0` with the use of C++11's `std::vector::data` method. This fixes the root cause of invalid memory accesses. `std::vector::operator[]` is an unchecked memory access, and when the buffers are zero-sized (that is the buffer container is empty) either due to a 0 padding in the case of elfloader or NULL parameters to syscalls where permitted, the unchecked access may cause an invalid memory access. The use of `std::vector::data` is permitted even in such a case, though the returned memory may not be dereferenced. The general usage of the returned pointer is to pass to `memif_t`, which is careful about 0-sized buffer accesses, and so passing the result of `std::vector::data` is safe. This is theoretically a better access pattern as it also avoids having the compiler to re-materialize the pointer from the de-referenced location.
Diffstat (limited to 'fesvr/device.cc')
-rw-r--r--fesvr/device.cc8
1 files changed, 4 insertions, 4 deletions
diff --git a/fesvr/device.cc b/fesvr/device.cc
index 3a4cc95..3cd3cd4 100644
--- a/fesvr/device.cc
+++ b/fesvr/device.cc
@@ -110,10 +110,10 @@ void disk_t::handle_read(command_t cmd)
cmd.memif().read(cmd.payload(), sizeof(req), &req);
std::vector<uint8_t> buf(req.size);
- if ((size_t)::pread(fd, &buf[0], buf.size(), req.offset) != req.size)
+ if ((size_t)::pread(fd, buf.data(), buf.size(), req.offset) != req.size)
throw std::runtime_error("could not read " + id + " @ " + std::to_string(req.offset));
- cmd.memif().write(req.addr, buf.size(), &buf[0]);
+ cmd.memif().write(req.addr, buf.size(), buf.data());
cmd.respond(req.tag);
}
@@ -123,9 +123,9 @@ void disk_t::handle_write(command_t cmd)
cmd.memif().read(cmd.payload(), sizeof(req), &req);
std::vector<uint8_t> buf(req.size);
- cmd.memif().read(req.addr, buf.size(), &buf[0]);
+ cmd.memif().read(req.addr, buf.size(), buf.data());
- if ((size_t)::pwrite(fd, &buf[0], buf.size(), req.offset) != req.size)
+ if ((size_t)::pwrite(fd, buf.data(), buf.size(), req.offset) != req.size)
throw std::runtime_error("could not write " + id + " @ " + std::to_string(req.offset));
cmd.respond(req.tag);