diff options
author | Andreas Kling <kling@serenityos.org> | 2020-02-07 23:42:28 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-02-07 23:43:32 +0100 |
commit | d04fcccc90dfa99031e5e16c2b2be7a31e613520 (patch) | |
tree | bdcc5a39f8150129303fe529cfa2481ffd4a5876 | |
parent | d34ad44f90fbfc9f4166d8326994aa86458a18d5 (diff) | |
download | serenity-d04fcccc90dfa99031e5e16c2b2be7a31e613520.zip |
Kernel: Truncate addresses stored by getsockname() and getpeername()
If there's not enough space in the output buffer for the whole sockaddr
we now simply truncate the address instead of returning EINVAL.
This patch also makes getpeername() actually return the peer address
rather than the local address.. :^)
-rw-r--r-- | Kernel/Net/IPv4Socket.cpp | 24 | ||||
-rw-r--r-- | Kernel/Net/IPv4Socket.h | 4 | ||||
-rw-r--r-- | Kernel/Net/LocalSocket.cpp | 13 | ||||
-rw-r--r-- | Kernel/Net/LocalSocket.h | 4 | ||||
-rw-r--r-- | Kernel/Net/Socket.h | 4 | ||||
-rw-r--r-- | Kernel/Process.cpp | 12 |
6 files changed, 23 insertions, 38 deletions
diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index 368557bb28..ad90567848 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -82,30 +82,18 @@ IPv4Socket::~IPv4Socket() all_sockets().resource().remove(this); } -bool IPv4Socket::get_local_address(sockaddr* address, socklen_t* address_size) +void IPv4Socket::get_local_address(sockaddr* address, socklen_t* address_size) { - // FIXME: Look into what fallback behavior we should have here. - if (*address_size < sizeof(sockaddr_in)) - return false; - auto& ia = (sockaddr_in&)*address; - ia.sin_family = AF_INET; - ia.sin_port = htons(m_local_port); - memcpy(&ia.sin_addr, &m_local_address, sizeof(IPv4Address)); + sockaddr_in local_address = { AF_INET, htons(m_local_port), { m_local_address.to_in_addr_t() }, { 0 } }; + memcpy(address, &local_address, min(static_cast<size_t>(*address_size), sizeof(sockaddr_in))); *address_size = sizeof(sockaddr_in); - return true; } -bool IPv4Socket::get_peer_address(sockaddr* address, socklen_t* address_size) +void IPv4Socket::get_peer_address(sockaddr* address, socklen_t* address_size) { - // FIXME: Look into what fallback behavior we should have here. - if (*address_size < sizeof(sockaddr_in)) - return false; - auto& ia = (sockaddr_in&)*address; - ia.sin_family = AF_INET; - ia.sin_port = htons(m_peer_port); - memcpy(&ia.sin_addr, &m_peer_address, sizeof(IPv4Address)); + sockaddr_in peer_address = { AF_INET, htons(m_peer_port), { m_peer_address.to_in_addr_t() }, { 0 } }; + memcpy(address, &peer_address, min(static_cast<size_t>(*address_size), sizeof(sockaddr_in))); *address_size = sizeof(sockaddr_in); - return true; } KResult IPv4Socket::bind(const sockaddr* user_address, socklen_t address_size) diff --git a/Kernel/Net/IPv4Socket.h b/Kernel/Net/IPv4Socket.h index f38f90799a..fbdfa1b375 100644 --- a/Kernel/Net/IPv4Socket.h +++ b/Kernel/Net/IPv4Socket.h @@ -49,8 +49,8 @@ public: virtual KResult bind(const sockaddr*, socklen_t) override; virtual KResult connect(FileDescription&, const sockaddr*, socklen_t, ShouldBlock = ShouldBlock::Yes) override; virtual KResult listen(int) override; - virtual bool get_local_address(sockaddr*, socklen_t*) override; - virtual bool get_peer_address(sockaddr*, socklen_t*) override; + virtual void get_local_address(sockaddr*, socklen_t*) override; + virtual void get_peer_address(sockaddr*, socklen_t*) override; virtual void attach(FileDescription&) override; virtual void detach(FileDescription&) override; virtual bool can_read(const FileDescription&) const override; diff --git a/Kernel/Net/LocalSocket.cpp b/Kernel/Net/LocalSocket.cpp index 68269a82a0..a364336799 100644 --- a/Kernel/Net/LocalSocket.cpp +++ b/Kernel/Net/LocalSocket.cpp @@ -76,19 +76,16 @@ LocalSocket::~LocalSocket() all_sockets().resource().remove(this); } -bool LocalSocket::get_local_address(sockaddr* address, socklen_t* address_size) +void LocalSocket::get_local_address(sockaddr* address, socklen_t* address_size) { - // FIXME: Look into what fallback behavior we should have here. - if (*address_size != sizeof(sockaddr_un)) - return false; - memcpy(address, &m_address, sizeof(sockaddr_un)); + size_t bytes_to_copy = min(static_cast<size_t>(*address_size), sizeof(sockaddr_un)); + memcpy(address, &m_address, bytes_to_copy); *address_size = sizeof(sockaddr_un); - return true; } -bool LocalSocket::get_peer_address(sockaddr* address, socklen_t* address_size) +void LocalSocket::get_peer_address(sockaddr* address, socklen_t* address_size) { - return get_local_address(address, address_size); + get_local_address(address, address_size); } KResult LocalSocket::bind(const sockaddr* user_address, socklen_t address_size) diff --git a/Kernel/Net/LocalSocket.h b/Kernel/Net/LocalSocket.h index 21b04f6463..e989884cc2 100644 --- a/Kernel/Net/LocalSocket.h +++ b/Kernel/Net/LocalSocket.h @@ -47,8 +47,8 @@ public: virtual KResult bind(const sockaddr*, socklen_t) override; virtual KResult connect(FileDescription&, const sockaddr*, socklen_t, ShouldBlock = ShouldBlock::Yes) override; virtual KResult listen(int) override; - virtual bool get_local_address(sockaddr*, socklen_t*) override; - virtual bool get_peer_address(sockaddr*, socklen_t*) override; + virtual void get_local_address(sockaddr*, socklen_t*) override; + virtual void get_peer_address(sockaddr*, socklen_t*) override; virtual void attach(FileDescription&) override; virtual void detach(FileDescription&) override; virtual bool can_read(const FileDescription&) const override; diff --git a/Kernel/Net/Socket.h b/Kernel/Net/Socket.h index aa794dadd2..7222d170f5 100644 --- a/Kernel/Net/Socket.h +++ b/Kernel/Net/Socket.h @@ -93,8 +93,8 @@ public: virtual KResult bind(const sockaddr*, socklen_t) = 0; virtual KResult connect(FileDescription&, const sockaddr*, socklen_t, ShouldBlock) = 0; virtual KResult listen(int) = 0; - virtual bool get_local_address(sockaddr*, socklen_t*) = 0; - virtual bool get_peer_address(sockaddr*, socklen_t*) = 0; + virtual void get_local_address(sockaddr*, socklen_t*) = 0; + virtual void get_peer_address(sockaddr*, socklen_t*) = 0; virtual bool is_local() const { return false; } virtual bool is_ipv4() const { return false; } virtual void attach(FileDescription&) = 0; diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 41162a3047..518b32b5f6 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -3190,8 +3190,7 @@ int Process::sys$accept(int accepting_socket_fd, sockaddr* address, socklen_t* a } auto accepted_socket = socket.accept(); ASSERT(accepted_socket); - bool success = accepted_socket->get_peer_address(address, address_size); - ASSERT(success); + accepted_socket->get_peer_address(address, address_size); auto accepted_socket_description = FileDescription::create(*accepted_socket); accepted_socket_description->set_readable(true); accepted_socket_description->set_writable(true); @@ -3318,11 +3317,12 @@ int Process::get_sock_or_peer_name(const Params& params) u8 address_buffer[sizeof(sockaddr_un)]; addrlen_value = min(sizeof(sockaddr_un), static_cast<size_t>(addrlen_value)); - - if (!socket.get_local_address((sockaddr*)address_buffer, &addrlen_value)) - return -EINVAL; - + if constexpr (sockname) + socket.get_local_address((sockaddr*)address_buffer, &addrlen_value); + else + socket.get_peer_address((sockaddr*)address_buffer, &addrlen_value); copy_to_user(params.addr, address_buffer, addrlen_value); + copy_to_user(params.addrlen, &addrlen_value); return 0; } |