From 62f615f0f40b08d44efc25f727298ef7cefd2216 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Tue, 15 Sep 2020 15:44:53 -0400 Subject: [PATCH] UsespaceEmulator: Fix minor bugs in recvfrom() interception * Pass the correct source address for copying tine addr_length. Previously, this was broken when addr_length was non-nullptr. * Copy min(sizeof(address), address_length) bytes into address, instead of sizeof(address), which might be larger than the user buffer. * Use sockaddr_storage instead of sockaddr_un. In practice they're both the same size, but this is what sockaddr_storage is for. With this (in particular, the first fix), `ue /bin/ntpquery` actually gets past the recvfrom() call :^) --- DevTools/UserspaceEmulator/Emulator.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/DevTools/UserspaceEmulator/Emulator.cpp b/DevTools/UserspaceEmulator/Emulator.cpp index db6c46689a..657a8fa390 100644 --- a/DevTools/UserspaceEmulator/Emulator.cpp +++ b/DevTools/UserspaceEmulator/Emulator.cpp @@ -599,13 +599,16 @@ int Emulator::virt$recvfrom(FlatPtr params_addr) mmu().copy_from_vm(¶ms, params_addr, sizeof(params)); auto buffer = ByteBuffer::create_uninitialized(params.buffer.size); - sockaddr_un address; - if (params.addr) - mmu().copy_from_vm(&address, (FlatPtr)params.addr, sizeof(address)); + if (!params.addr_length && params.addr) + return -EINVAL; socklen_t address_length = 0; if (params.addr_length) - mmu().copy_from_vm(&address_length, (FlatPtr)address_length, sizeof(address_length)); + mmu().copy_from_vm(&address_length, (FlatPtr)params.addr_length, sizeof(address_length)); + + sockaddr_storage address; + if (params.addr) + mmu().copy_from_vm(&address, (FlatPtr)params.addr, min(sizeof(address), (size_t)address_length)); int rc = recvfrom(params.sockfd, buffer.data(), buffer.size(), params.flags, params.addr ? (struct sockaddr*)&address : nullptr, params.addr_length ? &address_length : nullptr); if (rc < 0)