summaryrefslogtreecommitdiff
path: root/Userland/DevTools
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2021-09-06 03:29:52 +0430
committerAndreas Kling <kling@serenityos.org>2021-09-06 01:53:26 +0200
commit97e97bccab085823d1365cb54142fd8c41dbcd8c (patch)
tree9008687dbcdfb6f36f6dc6372aa382b15b9d36c8 /Userland/DevTools
parent3a9f00c59bad7735970c72cb940d08161fda09b0 (diff)
downloadserenity-97e97bccab085823d1365cb54142fd8c41dbcd8c.zip
Everywhere: Make ByteBuffer::{create_*,copy}() OOM-safe
Diffstat (limited to 'Userland/DevTools')
-rw-r--r--Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp87
-rw-r--r--Userland/DevTools/UserspaceEmulator/SoftMMU.cpp12
2 files changed, 73 insertions, 26 deletions
diff --git a/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp b/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp
index 56a452bbb1..682a823347 100644
--- a/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp
+++ b/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp
@@ -413,7 +413,10 @@ int Emulator::virt$setsockopt(FlatPtr params_addr)
mmu().copy_from_vm(&params, params_addr, sizeof(params));
if (params.option == SO_RCVTIMEO || params.option == SO_TIMESTAMP) {
- auto host_value_buffer = ByteBuffer::create_zeroed(params.value_size);
+ auto host_value_buffer_result = ByteBuffer::create_zeroed(params.value_size);
+ if (!host_value_buffer_result.has_value())
+ return -ENOMEM;
+ auto& host_value_buffer = host_value_buffer_result.value();
mmu().copy_from_vm(host_value_buffer.data(), (FlatPtr)params.value, params.value_size);
int rc = setsockopt(params.sockfd, params.level, params.option, host_value_buffer.data(), host_value_buffer.size());
if (rc < 0)
@@ -542,7 +545,10 @@ int Emulator::virt$get_process_name(FlatPtr buffer, int size)
{
if (size < 0)
return -EINVAL;
- auto host_buffer = ByteBuffer::create_zeroed((size_t)size);
+ auto host_buffer_result = ByteBuffer::create_zeroed((size_t)size);
+ if (!host_buffer_result.has_value())
+ return -ENOMEM;
+ auto& host_buffer = host_buffer_result.value();
int rc = syscall(SC_get_process_name, host_buffer.data(), host_buffer.size());
mmu().copy_to_vm(buffer, host_buffer.data(), host_buffer.size());
return rc;
@@ -582,13 +588,20 @@ int Emulator::virt$recvmsg(int sockfd, FlatPtr msg_addr, int flags)
Vector<ByteBuffer, 1> buffers;
Vector<iovec, 1> iovs;
for (const auto& iov : mmu_iovs) {
- buffers.append(ByteBuffer::create_uninitialized(iov.iov_len));
+ auto buffer_result = ByteBuffer::create_uninitialized(iov.iov_len);
+ if (!buffer_result.has_value())
+ return -ENOMEM;
+ buffers.append(buffer_result.release_value());
iovs.append({ buffers.last().data(), buffers.last().size() });
}
ByteBuffer control_buffer;
- if (mmu_msg.msg_control)
- control_buffer = ByteBuffer::create_uninitialized(mmu_msg.msg_controllen);
+ if (mmu_msg.msg_control) {
+ auto buffer_result = ByteBuffer::create_uninitialized(mmu_msg.msg_controllen);
+ if (!buffer_result.has_value())
+ return -ENOMEM;
+ control_buffer = buffer_result.release_value();
+ }
sockaddr_storage addr;
msghdr msg = { &addr, sizeof(addr), iovs.data(), (int)iovs.size(), mmu_msg.msg_control ? control_buffer.data() : nullptr, mmu_msg.msg_controllen, mmu_msg.msg_flags };
@@ -625,8 +638,12 @@ int Emulator::virt$sendmsg(int sockfd, FlatPtr msg_addr, int flags)
}
ByteBuffer control_buffer;
- if (mmu_msg.msg_control)
- control_buffer = ByteBuffer::create_uninitialized(mmu_msg.msg_controllen);
+ if (mmu_msg.msg_control) {
+ auto buffer_result = ByteBuffer::create_uninitialized(mmu_msg.msg_controllen);
+ if (!buffer_result.has_value())
+ return -ENOMEM;
+ control_buffer = buffer_result.release_value();
+ }
sockaddr_storage address;
socklen_t address_length = 0;
@@ -733,7 +750,10 @@ int Emulator::virt$getgroups(ssize_t count, FlatPtr groups)
if (!count)
return syscall(SC_getgroups, 0, nullptr);
- auto buffer = ByteBuffer::create_uninitialized(count * sizeof(gid_t));
+ auto buffer_result = ByteBuffer::create_uninitialized(count * sizeof(gid_t));
+ if (!buffer_result.has_value())
+ return -ENOMEM;
+ auto& buffer = buffer_result.value();
int rc = syscall(SC_getgroups, count, buffer.data());
if (rc < 0)
return rc;
@@ -858,7 +878,10 @@ u32 Emulator::virt$mmap(u32 params_addr)
String name_str;
if (params.name.characters) {
- auto name = ByteBuffer::create_uninitialized(params.name.length);
+ auto buffer_result = ByteBuffer::create_uninitialized(params.name.length);
+ if (!buffer_result.has_value())
+ return -ENOMEM;
+ auto& name = buffer_result.value();
mmu().copy_from_vm(name.data(), (FlatPtr)params.name.characters, params.name.length);
name_str = { name.data(), name.size() };
}
@@ -1002,7 +1025,10 @@ u32 Emulator::virt$read(int fd, FlatPtr buffer, ssize_t size)
{
if (size < 0)
return -EINVAL;
- auto local_buffer = ByteBuffer::create_uninitialized(size);
+ auto buffer_result = ByteBuffer::create_uninitialized(size);
+ if (!buffer_result.has_value())
+ return -ENOMEM;
+ auto& local_buffer = buffer_result.value();
int nread = syscall(SC_read, fd, local_buffer.data(), local_buffer.size());
if (nread < 0) {
if (nread == -EPERM) {
@@ -1029,7 +1055,10 @@ void Emulator::virt$exit(int status)
ssize_t Emulator::virt$getrandom(FlatPtr buffer, size_t buffer_size, unsigned int flags)
{
- auto host_buffer = ByteBuffer::create_uninitialized(buffer_size);
+ auto buffer_result = ByteBuffer::create_uninitialized(buffer_size);
+ if (!buffer_result.has_value())
+ return -ENOMEM;
+ auto& host_buffer = buffer_result.value();
int rc = syscall(SC_getrandom, host_buffer.data(), host_buffer.size(), flags);
if (rc < 0)
return rc;
@@ -1039,7 +1068,10 @@ ssize_t Emulator::virt$getrandom(FlatPtr buffer, size_t buffer_size, unsigned in
int Emulator::virt$get_dir_entries(int fd, FlatPtr buffer, ssize_t size)
{
- auto host_buffer = ByteBuffer::create_uninitialized(size);
+ auto buffer_result = ByteBuffer::create_uninitialized(size);
+ if (!buffer_result.has_value())
+ return -ENOMEM;
+ auto& host_buffer = buffer_result.value();
int rc = syscall(SC_get_dir_entries, fd, host_buffer.data(), host_buffer.size());
if (rc < 0)
return rc;
@@ -1215,7 +1247,10 @@ int Emulator::virt$realpath(FlatPtr params_addr)
mmu().copy_from_vm(&params, params_addr, sizeof(params));
auto path = mmu().copy_buffer_from_vm((FlatPtr)params.path.characters, params.path.length);
- auto host_buffer = ByteBuffer::create_zeroed(params.buffer.size);
+ auto buffer_result = ByteBuffer::create_zeroed(params.buffer.size);
+ if (!buffer_result.has_value())
+ return -ENOMEM;
+ auto& host_buffer = buffer_result.value();
Syscall::SC_realpath_params host_params;
host_params.path = { (const char*)path.data(), path.size() };
@@ -1231,7 +1266,10 @@ int Emulator::virt$gethostname(FlatPtr buffer, ssize_t buffer_size)
{
if (buffer_size < 0)
return -EINVAL;
- auto host_buffer = ByteBuffer::create_zeroed(buffer_size);
+ auto buffer_result = ByteBuffer::create_zeroed(buffer_size);
+ if (!buffer_result.has_value())
+ return -ENOMEM;
+ auto& host_buffer = buffer_result.value();
int rc = syscall(SC_gethostname, host_buffer.data(), host_buffer.size());
if (rc < 0)
return rc;
@@ -1316,7 +1354,10 @@ int Emulator::virt$setpgid(pid_t pid, pid_t pgid)
int Emulator::virt$ttyname(int fd, FlatPtr buffer, size_t buffer_size)
{
- auto host_buffer = ByteBuffer::create_zeroed(buffer_size);
+ auto buffer_result = ByteBuffer::create_zeroed(buffer_size);
+ if (!buffer_result.has_value())
+ return -ENOMEM;
+ auto& host_buffer = buffer_result.value();
int rc = syscall(SC_ttyname, fd, host_buffer.data(), host_buffer.size());
if (rc < 0)
return rc;
@@ -1326,7 +1367,10 @@ int Emulator::virt$ttyname(int fd, FlatPtr buffer, size_t buffer_size)
int Emulator::virt$getcwd(FlatPtr buffer, size_t buffer_size)
{
- auto host_buffer = ByteBuffer::create_zeroed(buffer_size);
+ auto buffer_result = ByteBuffer::create_zeroed(buffer_size);
+ if (!buffer_result.has_value())
+ return -ENOMEM;
+ auto& host_buffer = buffer_result.value();
int rc = syscall(SC_getcwd, host_buffer.data(), host_buffer.size());
if (rc < 0)
return rc;
@@ -1436,12 +1480,12 @@ int Emulator::virt$clock_nanosleep(FlatPtr params_addr)
params.requested_sleep = &requested_sleep;
auto remaining_vm_addr = params.remaining_sleep;
- auto remaining = ByteBuffer::create_zeroed(sizeof(timespec));
- params.remaining_sleep = (timespec*)remaining.data();
+ timespec remaining { 0, 0 };
+ params.remaining_sleep = &remaining;
int rc = syscall(SC_clock_nanosleep, &params);
if (remaining_vm_addr)
- mmu().copy_to_vm((FlatPtr)remaining_vm_addr, remaining.data(), sizeof(timespec));
+ mmu().copy_to_vm((FlatPtr)remaining_vm_addr, &remaining, sizeof(timespec));
return rc;
}
@@ -1452,7 +1496,10 @@ int Emulator::virt$readlink(FlatPtr params_addr)
mmu().copy_from_vm(&params, params_addr, sizeof(params));
auto path = mmu().copy_buffer_from_vm((FlatPtr)params.path.characters, params.path.length);
- auto host_buffer = ByteBuffer::create_zeroed(params.buffer.size);
+ auto buffer_result = ByteBuffer::create_zeroed(params.buffer.size);
+ if (!buffer_result.has_value())
+ return -ENOMEM;
+ auto& host_buffer = buffer_result.value();
Syscall::SC_readlink_params host_params;
host_params.path = { (const char*)path.data(), path.size() };
diff --git a/Userland/DevTools/UserspaceEmulator/SoftMMU.cpp b/Userland/DevTools/UserspaceEmulator/SoftMMU.cpp
index c2442028ac..62009396d4 100644
--- a/Userland/DevTools/UserspaceEmulator/SoftMMU.cpp
+++ b/Userland/DevTools/UserspaceEmulator/SoftMMU.cpp
@@ -63,17 +63,17 @@ void SoftMMU::ensure_split_at(X86::LogicalAddress address)
// a previous page, and that it belongs to the same region.
auto* old_region = verify_cast<MmapRegion>(m_page_to_region_map[page_index]);
- //dbgln("splitting at {:p}", address.offset());
- //dbgln(" old region: {:p}-{:p}", old_region->base(), old_region->end() - 1);
+ // dbgln("splitting at {:p}", address.offset());
+ // dbgln(" old region: {:p}-{:p}", old_region->base(), old_region->end() - 1);
NonnullOwnPtr<MmapRegion> new_region = old_region->split_at(VirtualAddress(offset));
- //dbgln(" new region: {:p}-{:p}", new_region->base(), new_region->end() - 1);
- //dbgln(" up old region: {:p}-{:p}", old_region->base(), old_region->end() - 1);
+ // dbgln(" new region: {:p}-{:p}", new_region->base(), new_region->end() - 1);
+ // dbgln(" up old region: {:p}-{:p}", old_region->base(), old_region->end() - 1);
size_t first_page_in_region = new_region->base() / PAGE_SIZE;
size_t last_page_in_region = (new_region->base() + new_region->size() - 1) / PAGE_SIZE;
- //dbgln(" @ remapping pages {} thru {}", first_page_in_region, last_page_in_region);
+ // dbgln(" @ remapping pages {} thru {}", first_page_in_region, last_page_in_region);
for (size_t page = first_page_in_region; page <= last_page_in_region; ++page) {
VERIFY(m_page_to_region_map[page] == old_region);
@@ -321,7 +321,7 @@ void SoftMMU::copy_from_vm(void* destination, const FlatPtr source, size_t size)
ByteBuffer SoftMMU::copy_buffer_from_vm(const FlatPtr source, size_t size)
{
- auto buffer = ByteBuffer::create_uninitialized(size);
+ auto buffer = ByteBuffer::create_uninitialized(size).release_value(); // FIXME: Handle possible OOM situation.
copy_from_vm(buffer.data(), source, size);
return buffer;
}