diff options
author | Idan Horowitz <idan.horowitz@gmail.com> | 2022-07-10 02:00:59 +0300 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-07-10 14:24:34 +0200 |
commit | b700d1a474634840da86aeefd2a67b2e8a364cd6 (patch) | |
tree | 42d64b8a61930992ee9257ac78a5f4a5548ea575 /Kernel | |
parent | 68980bf71175a47bbf8b22b8cea04a84527ae531 (diff) | |
download | serenity-b700d1a474634840da86aeefd2a67b2e8a364cd6.zip |
Kernel: Support sys$connect to LocalSockets with short sockaddr_uns
This is not explicitly specified by POSIX, but is supported by other
*nixes, already supported by our sys$bind, and expected by various
programs. While were here, also clean up the user memory copies a bit.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/Net/LocalSocket.cpp | 26 |
1 files changed, 10 insertions, 16 deletions
diff --git a/Kernel/Net/LocalSocket.cpp b/Kernel/Net/LocalSocket.cpp index 1bae224909..ab19a790ea 100644 --- a/Kernel/Net/LocalSocket.cpp +++ b/Kernel/Net/LocalSocket.cpp @@ -159,29 +159,23 @@ ErrorOr<void> LocalSocket::bind(Userspace<sockaddr const*> user_address, socklen return {}; } -ErrorOr<void> LocalSocket::connect(OpenFileDescription& description, Userspace<sockaddr const*> address, socklen_t address_size, ShouldBlock) +ErrorOr<void> LocalSocket::connect(OpenFileDescription& description, Userspace<sockaddr const*> user_address, socklen_t address_size, ShouldBlock) { VERIFY(!m_bound); - if (address_size != sizeof(sockaddr_un)) + + if (address_size > sizeof(sockaddr_un)) return set_so_error(EINVAL); - u16 sa_family_copy; - auto* user_address = reinterpret_cast<sockaddr const*>(address.unsafe_userspace_ptr()); - SOCKET_TRY(copy_from_user(&sa_family_copy, &user_address->sa_family, sizeof(u16))); - if (sa_family_copy != AF_LOCAL) + + sockaddr_un address = {}; + SOCKET_TRY(copy_from_user(&address, user_address, address_size)); + + if (address.sun_family != AF_LOCAL) return set_so_error(EINVAL); + if (is_connected()) return set_so_error(EISCONN); - OwnPtr<KString> maybe_path; - { - auto const& local_address = *reinterpret_cast<sockaddr_un const*>(user_address); - char safe_address[sizeof(local_address.sun_path) + 1] = { 0 }; - SOCKET_TRY(copy_from_user(&safe_address[0], &local_address.sun_path[0], sizeof(safe_address) - 1)); - safe_address[sizeof(safe_address) - 1] = '\0'; - maybe_path = SOCKET_TRY(KString::try_create(safe_address)); - } - - auto path = maybe_path.release_nonnull(); + auto path = SOCKET_TRY(KString::try_create(StringView { address.sun_path, strnlen(address.sun_path, sizeof(address.sun_path)) })); dbgln_if(LOCAL_SOCKET_DEBUG, "LocalSocket({}) connect({})", this, *path); auto file = SOCKET_TRY(VirtualFileSystem::the().open(path->view(), O_RDWR, 0, Process::current().current_directory())); |