Skip to content

Commit

Permalink
Kernel: Truncate addresses stored by getsockname() and getpeername()
Browse files Browse the repository at this point in the history
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.. :^)
  • Loading branch information
awesomekling committed Feb 7, 2020
1 parent d34ad44 commit d04fccc
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 38 deletions.
24 changes: 6 additions & 18 deletions Kernel/Net/IPv4Socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions Kernel/Net/IPv4Socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ class IPv4Socket : public Socket {
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;
Expand Down
13 changes: 5 additions & 8 deletions Kernel/Net/LocalSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions Kernel/Net/LocalSocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ class LocalSocket final : public Socket, public InlineLinkedListNode<LocalSocket
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;
Expand Down
4 changes: 2 additions & 2 deletions Kernel/Net/Socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ class Socket : public File {
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;
Expand Down
12 changes: 6 additions & 6 deletions Kernel/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit d04fccc

Please sign in to comment.