summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Gianforcaro <b.gianfo@gmail.com>2020-08-17 23:49:35 -0700
committerAndreas Kling <kling@serenityos.org>2020-08-19 21:05:28 +0200
commit9f9b05ba0f8d907ab3190b127ef4500c1ad08156 (patch)
treedfd1a1ea0111b3211c474db84cb0a26f248faafa
parentd4dae49dcd1e0bbaabf47f5ed221e617426c6e3f (diff)
downloadserenity-9f9b05ba0f8d907ab3190b127ef4500c1ad08156.zip
Kernel: Use Userspace<T> for the sendto syscall, and Socket implementation
Note that the data member is of type ImmutableBufferArgument, which has no Userspace<T> usage. I left it alone for now, to be fixed in a future change holistically for all usages.
-rw-r--r--Kernel/API/Syscall.h2
-rw-r--r--Kernel/Net/IPv4Socket.cpp11
-rw-r--r--Kernel/Net/IPv4Socket.h2
-rw-r--r--Kernel/Net/LocalSocket.cpp2
-rw-r--r--Kernel/Net/LocalSocket.h2
-rw-r--r--Kernel/Net/Socket.cpp2
-rw-r--r--Kernel/Net/Socket.h2
-rw-r--r--Kernel/Process.h2
-rw-r--r--Kernel/Syscalls/socket.cpp4
9 files changed, 16 insertions, 13 deletions
diff --git a/Kernel/API/Syscall.h b/Kernel/API/Syscall.h
index 6a4595fc42..bdfcba412e 100644
--- a/Kernel/API/Syscall.h
+++ b/Kernel/API/Syscall.h
@@ -290,7 +290,7 @@ struct SC_sendto_params {
int sockfd;
ImmutableBufferArgument<void, size_t> data;
int flags;
- const sockaddr* addr;
+ Userspace<const sockaddr*> addr;
socklen_t addr_length;
};
diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp
index 47f1589c55..e46e84e850 100644
--- a/Kernel/Net/IPv4Socket.cpp
+++ b/Kernel/Net/IPv4Socket.cpp
@@ -193,19 +193,22 @@ int IPv4Socket::allocate_local_port_if_needed()
return port;
}
-KResultOr<size_t> IPv4Socket::sendto(FileDescription&, const void* data, size_t data_length, int flags, const sockaddr* addr, socklen_t addr_length)
+KResultOr<size_t> IPv4Socket::sendto(FileDescription&, const void* data, size_t data_length, int flags, Userspace<const sockaddr*> addr, socklen_t addr_length)
{
(void)flags;
if (addr && addr_length != sizeof(sockaddr_in))
return KResult(-EINVAL);
if (addr) {
- if (addr->sa_family != AF_INET) {
- klog() << "sendto: Bad address family: " << addr->sa_family << " is not AF_INET!";
+ sockaddr_in ia;
+ if (!Process::current()->validate_read_and_copy_typed(&ia, Userspace<const sockaddr_in*>(addr.ptr())))
+ return KResult(-EFAULT);
+
+ if (ia.sin_family != AF_INET) {
+ klog() << "sendto: Bad address family: " << ia.sin_family << " is not AF_INET!";
return KResult(-EAFNOSUPPORT);
}
- auto& ia = *(const sockaddr_in*)addr;
m_peer_address = IPv4Address((const u8*)&ia.sin_addr.s_addr);
m_peer_port = ntohs(ia.sin_port);
}
diff --git a/Kernel/Net/IPv4Socket.h b/Kernel/Net/IPv4Socket.h
index 0f7f278ab6..6b7180831b 100644
--- a/Kernel/Net/IPv4Socket.h
+++ b/Kernel/Net/IPv4Socket.h
@@ -58,7 +58,7 @@ public:
virtual void detach(FileDescription&) override;
virtual bool can_read(const FileDescription&, size_t) const override;
virtual bool can_write(const FileDescription&, size_t) const override;
- virtual KResultOr<size_t> sendto(FileDescription&, const void*, size_t, int, const sockaddr*, socklen_t) override;
+ virtual KResultOr<size_t> sendto(FileDescription&, const void*, size_t, int, Userspace<const sockaddr*>, socklen_t) override;
virtual KResultOr<size_t> recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) override;
virtual KResult setsockopt(int level, int option, Userspace<const void*>, socklen_t) override;
virtual KResult getsockopt(FileDescription&, int level, int option, Userspace<void*>, Userspace<socklen_t*>) override;
diff --git a/Kernel/Net/LocalSocket.cpp b/Kernel/Net/LocalSocket.cpp
index fb7d311753..81178f9f51 100644
--- a/Kernel/Net/LocalSocket.cpp
+++ b/Kernel/Net/LocalSocket.cpp
@@ -260,7 +260,7 @@ bool LocalSocket::can_write(const FileDescription& description, size_t) const
return false;
}
-KResultOr<size_t> LocalSocket::sendto(FileDescription& description, const void* data, size_t data_size, int, const sockaddr*, socklen_t)
+KResultOr<size_t> LocalSocket::sendto(FileDescription& description, const void* data, size_t data_size, int, Userspace<const sockaddr*>, socklen_t)
{
if (!has_attached_peer(description))
return KResult(-EPIPE);
diff --git a/Kernel/Net/LocalSocket.h b/Kernel/Net/LocalSocket.h
index 63821d2962..47cb525d2d 100644
--- a/Kernel/Net/LocalSocket.h
+++ b/Kernel/Net/LocalSocket.h
@@ -60,7 +60,7 @@ public:
virtual void detach(FileDescription&) override;
virtual bool can_read(const FileDescription&, size_t) const override;
virtual bool can_write(const FileDescription&, size_t) const override;
- virtual KResultOr<size_t> sendto(FileDescription&, const void*, size_t, int, const sockaddr*, socklen_t) override;
+ virtual KResultOr<size_t> sendto(FileDescription&, const void*, size_t, int, Userspace<const sockaddr*>, socklen_t) override;
virtual KResultOr<size_t> recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) override;
virtual KResult getsockopt(FileDescription&, int level, int option, Userspace<void*>, Userspace<socklen_t*>) override;
virtual KResult chown(FileDescription&, uid_t, gid_t) override;
diff --git a/Kernel/Net/Socket.cpp b/Kernel/Net/Socket.cpp
index 9114b8eb4a..62b76bd775 100644
--- a/Kernel/Net/Socket.cpp
+++ b/Kernel/Net/Socket.cpp
@@ -202,7 +202,7 @@ KResultOr<size_t> Socket::write(FileDescription& description, size_t, const u8*
{
if (is_shut_down_for_writing())
return -EPIPE;
- return sendto(description, data, size, 0, nullptr, 0);
+ return sendto(description, data, size, 0, {}, 0);
}
KResult Socket::shutdown(int how)
diff --git a/Kernel/Net/Socket.h b/Kernel/Net/Socket.h
index 8d043fc614..77155fcc2b 100644
--- a/Kernel/Net/Socket.h
+++ b/Kernel/Net/Socket.h
@@ -107,7 +107,7 @@ public:
virtual bool is_ipv4() const { return false; }
virtual void attach(FileDescription&) = 0;
virtual void detach(FileDescription&) = 0;
- virtual KResultOr<size_t> sendto(FileDescription&, const void*, size_t, int flags, const sockaddr*, socklen_t) = 0;
+ virtual KResultOr<size_t> sendto(FileDescription&, const void*, size_t, int flags, Userspace<const sockaddr*>, socklen_t) = 0;
virtual KResultOr<size_t> recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) = 0;
virtual KResult setsockopt(int level, int option, Userspace<const void*>, socklen_t);
diff --git a/Kernel/Process.h b/Kernel/Process.h
index 8ec4a59f8c..47887ae844 100644
--- a/Kernel/Process.h
+++ b/Kernel/Process.h
@@ -295,7 +295,7 @@ public:
int sys$accept(int sockfd, Userspace<sockaddr*>, Userspace<socklen_t*>);
int sys$connect(int sockfd, Userspace<const sockaddr*>, socklen_t);
int sys$shutdown(int sockfd, int how);
- ssize_t sys$sendto(const Syscall::SC_sendto_params*);
+ ssize_t sys$sendto(Userspace<const Syscall::SC_sendto_params*>);
ssize_t sys$recvfrom(const Syscall::SC_recvfrom_params*);
int sys$getsockopt(Userspace<const Syscall::SC_getsockopt_params*>);
int sys$setsockopt(Userspace<const Syscall::SC_setsockopt_params*>);
diff --git a/Kernel/Syscalls/socket.cpp b/Kernel/Syscalls/socket.cpp
index 2068f3bdc3..ba0ead835c 100644
--- a/Kernel/Syscalls/socket.cpp
+++ b/Kernel/Syscalls/socket.cpp
@@ -188,7 +188,7 @@ int Process::sys$shutdown(int sockfd, int how)
return socket.shutdown(how);
}
-ssize_t Process::sys$sendto(const Syscall::SC_sendto_params* user_params)
+ssize_t Process::sys$sendto(Userspace<const Syscall::SC_sendto_params*> user_params)
{
REQUIRE_PROMISE(stdio);
Syscall::SC_sendto_params params;
@@ -196,7 +196,7 @@ ssize_t Process::sys$sendto(const Syscall::SC_sendto_params* user_params)
return -EFAULT;
int flags = params.flags;
- const sockaddr* addr = params.addr;
+ Userspace<const sockaddr*> addr = params.addr;
socklen_t addr_length = params.addr_length;
if (!validate(params.data))