Kernel: Remove SmapDisablers in sys$getsockname() and sys$getpeername()
Instead use the user/kernel copy helpers to only copy the minimum stuff needed from to/from userspace. Based on work started by Brian Gianforcaro.
This commit is contained in:
parent
7454926765
commit
f4302b58fb
Notes:
sideshowbarker
2024-07-19 09:46:27 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/f4302b58fb0
3 changed files with 44 additions and 36 deletions
|
@ -3214,19 +3214,23 @@ ssize_t Process::sys$recvfrom(const Syscall::SC_recvfrom_params* user_params)
|
||||||
return nrecv;
|
return nrecv;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Process::sys$getsockname(int sockfd, sockaddr* addr, socklen_t* addrlen)
|
template<bool sockname, typename Params>
|
||||||
|
int Process::get_sock_or_peer_name(const Params& params)
|
||||||
{
|
{
|
||||||
if (!validate_read_typed(addrlen))
|
socklen_t addrlen_value;
|
||||||
|
if (!validate_read_and_copy_typed(&addrlen_value, params.addrlen))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
SmapDisabler disabler;
|
if (addrlen_value <= 0)
|
||||||
if (*addrlen <= 0)
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!validate_write(addr, *addrlen))
|
if (!validate_write(params.addr, addrlen_value))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
auto description = file_description(sockfd);
|
if (!validate_write_typed(params.addrlen))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
auto description = file_description(params.sockfd);
|
||||||
if (!description)
|
if (!description)
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
|
|
||||||
|
@ -3235,42 +3239,31 @@ int Process::sys$getsockname(int sockfd, sockaddr* addr, socklen_t* addrlen)
|
||||||
|
|
||||||
auto& socket = *description->socket();
|
auto& socket = *description->socket();
|
||||||
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
|
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
|
||||||
if (!socket.get_local_address(addr, addrlen))
|
|
||||||
return -EINVAL; // FIXME: Should this be another error? I'm not sure.
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
copy_to_user(params.addr, address_buffer, addrlen_value);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Process::sys$getpeername(int sockfd, sockaddr* addr, socklen_t* addrlen)
|
int Process::sys$getsockname(const Syscall::SC_getsockname_params* user_params)
|
||||||
{
|
{
|
||||||
if (!validate_read_typed(addrlen))
|
Syscall::SC_getsockname_params params;
|
||||||
|
if (!validate_read_and_copy_typed(¶ms, user_params))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
return get_sock_or_peer_name<true>(params);
|
||||||
|
}
|
||||||
|
|
||||||
SmapDisabler disabler;
|
int Process::sys$getpeername(const Syscall::SC_getpeername_params* user_params)
|
||||||
|
{
|
||||||
if (*addrlen <= 0)
|
Syscall::SC_getpeername_params params;
|
||||||
return -EINVAL;
|
if (!validate_read_and_copy_typed(¶ms, user_params))
|
||||||
|
|
||||||
if (!validate_write(addr, *addrlen))
|
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
return get_sock_or_peer_name<false>(params);
|
||||||
auto description = file_description(sockfd);
|
|
||||||
if (!description)
|
|
||||||
return -EBADF;
|
|
||||||
|
|
||||||
if (!description->is_socket())
|
|
||||||
return -ENOTSOCK;
|
|
||||||
|
|
||||||
auto& socket = *description->socket();
|
|
||||||
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
|
|
||||||
|
|
||||||
if (socket.setup_state() != Socket::SetupState::Completed)
|
|
||||||
return -ENOTCONN;
|
|
||||||
|
|
||||||
if (!socket.get_peer_address(addr, addrlen))
|
|
||||||
return -EINVAL; // FIXME: Should this be another error? I'm not sure.
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Process::sys$sched_setparam(int tid, const struct sched_param* param)
|
int Process::sys$sched_setparam(int tid, const struct sched_param* param)
|
||||||
|
|
|
@ -263,8 +263,8 @@ public:
|
||||||
ssize_t sys$recvfrom(const Syscall::SC_recvfrom_params*);
|
ssize_t sys$recvfrom(const Syscall::SC_recvfrom_params*);
|
||||||
int sys$getsockopt(const Syscall::SC_getsockopt_params*);
|
int sys$getsockopt(const Syscall::SC_getsockopt_params*);
|
||||||
int sys$setsockopt(const Syscall::SC_setsockopt_params*);
|
int sys$setsockopt(const Syscall::SC_setsockopt_params*);
|
||||||
int sys$getsockname(int sockfd, sockaddr* addr, socklen_t* addrlen);
|
int sys$getsockname(const Syscall::SC_getsockname_params*);
|
||||||
int sys$getpeername(int sockfd, sockaddr* addr, socklen_t* addrlen);
|
int sys$getpeername(const Syscall::SC_getpeername_params*);
|
||||||
int sys$sched_setparam(pid_t pid, const struct sched_param* param);
|
int sys$sched_setparam(pid_t pid, const struct sched_param* param);
|
||||||
int sys$sched_getparam(pid_t pid, struct sched_param* param);
|
int sys$sched_getparam(pid_t pid, struct sched_param* param);
|
||||||
int sys$create_thread(void* (*)(void*), void* argument, const Syscall::SC_create_thread_params*);
|
int sys$create_thread(void* (*)(void*), void* argument, const Syscall::SC_create_thread_params*);
|
||||||
|
@ -302,6 +302,9 @@ public:
|
||||||
int sys$pledge(const Syscall::SC_pledge_params*);
|
int sys$pledge(const Syscall::SC_pledge_params*);
|
||||||
int sys$unveil(const Syscall::SC_unveil_params*);
|
int sys$unveil(const Syscall::SC_unveil_params*);
|
||||||
|
|
||||||
|
template<bool sockname, typename Params>
|
||||||
|
int get_sock_or_peer_name(const Params&);
|
||||||
|
|
||||||
static void initialize();
|
static void initialize();
|
||||||
|
|
||||||
[[noreturn]] void crash(int signal, u32 eip);
|
[[noreturn]] void crash(int signal, u32 eip);
|
||||||
|
|
|
@ -297,6 +297,18 @@ struct SC_setsockopt_params {
|
||||||
socklen_t value_size;
|
socklen_t value_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SC_getsockname_params {
|
||||||
|
int sockfd;
|
||||||
|
sockaddr* addr;
|
||||||
|
socklen_t* addrlen;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SC_getpeername_params {
|
||||||
|
int sockfd;
|
||||||
|
sockaddr* addr;
|
||||||
|
socklen_t* addrlen;
|
||||||
|
};
|
||||||
|
|
||||||
struct SC_futex_params {
|
struct SC_futex_params {
|
||||||
i32* userspace_address;
|
i32* userspace_address;
|
||||||
int futex_op;
|
int futex_op;
|
||||||
|
|
Loading…
Add table
Reference in a new issue