mirror of
https://github.com/RGBCube/serenity
synced 2025-05-24 01:05:08 +00:00
Kernel: Make copy_time_from_user() helpers use KResultOr<Time>
...and use TRY() for smooth error propagation everywhere.
This commit is contained in:
parent
ef94c73a01
commit
e6929835d2
6 changed files with 29 additions and 54 deletions
|
@ -90,22 +90,12 @@ KResult Socket::setsockopt(int level, int option, Userspace<const void*> user_va
|
||||||
case SO_SNDTIMEO:
|
case SO_SNDTIMEO:
|
||||||
if (user_value_size != sizeof(timeval))
|
if (user_value_size != sizeof(timeval))
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
{
|
m_send_timeout = TRY(copy_time_from_user(static_ptr_cast<timeval const*>(user_value)));
|
||||||
auto timeout = copy_time_from_user(static_ptr_cast<const timeval*>(user_value));
|
|
||||||
if (!timeout.has_value())
|
|
||||||
return EFAULT;
|
|
||||||
m_send_timeout = timeout.value();
|
|
||||||
}
|
|
||||||
return KSuccess;
|
return KSuccess;
|
||||||
case SO_RCVTIMEO:
|
case SO_RCVTIMEO:
|
||||||
if (user_value_size != sizeof(timeval))
|
if (user_value_size != sizeof(timeval))
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
{
|
m_receive_timeout = TRY(copy_time_from_user(static_ptr_cast<timeval const*>(user_value)));
|
||||||
auto timeout = copy_time_from_user(static_ptr_cast<const timeval*>(user_value));
|
|
||||||
if (!timeout.has_value())
|
|
||||||
return EFAULT;
|
|
||||||
m_receive_timeout = timeout.value();
|
|
||||||
}
|
|
||||||
return KSuccess;
|
return KSuccess;
|
||||||
case SO_BINDTODEVICE: {
|
case SO_BINDTODEVICE: {
|
||||||
if (user_value_size != IFNAMSIZ)
|
if (user_value_size != IFNAMSIZ)
|
||||||
|
|
|
@ -40,31 +40,28 @@ Kernel::KResultOr<NonnullOwnPtr<Kernel::KString>> try_copy_kstring_from_user(Use
|
||||||
return new_string;
|
return new_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] Optional<Time> copy_time_from_user(const timespec* ts_user)
|
KResultOr<Time> copy_time_from_user(timespec const* ts_user)
|
||||||
{
|
{
|
||||||
timespec ts;
|
timespec ts {};
|
||||||
if (copy_from_user(&ts, ts_user, sizeof(timespec)).is_error()) {
|
TRY(copy_from_user(&ts, ts_user, sizeof(timespec)));
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return Time::from_timespec(ts);
|
return Time::from_timespec(ts);
|
||||||
}
|
}
|
||||||
[[nodiscard]] Optional<Time> copy_time_from_user(const timeval* tv_user)
|
|
||||||
|
KResultOr<Time> copy_time_from_user(timeval const* tv_user)
|
||||||
{
|
{
|
||||||
timeval tv;
|
timeval tv {};
|
||||||
if (copy_from_user(&tv, tv_user, sizeof(timeval)).is_error()) {
|
TRY(copy_from_user(&tv, tv_user, sizeof(timeval)));
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return Time::from_timeval(tv);
|
return Time::from_timeval(tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
[[nodiscard]] Optional<Time> copy_time_from_user<const timeval>(Userspace<const timeval*> src) { return copy_time_from_user(src.unsafe_userspace_ptr()); }
|
KResultOr<Time> copy_time_from_user<const timeval>(Userspace<timeval const*> src) { return copy_time_from_user(src.unsafe_userspace_ptr()); }
|
||||||
template<>
|
template<>
|
||||||
[[nodiscard]] Optional<Time> copy_time_from_user<timeval>(Userspace<timeval*> src) { return copy_time_from_user(src.unsafe_userspace_ptr()); }
|
KResultOr<Time> copy_time_from_user<timeval>(Userspace<timeval*> src) { return copy_time_from_user(src.unsafe_userspace_ptr()); }
|
||||||
template<>
|
template<>
|
||||||
[[nodiscard]] Optional<Time> copy_time_from_user<const timespec>(Userspace<const timespec*> src) { return copy_time_from_user(src.unsafe_userspace_ptr()); }
|
KResultOr<Time> copy_time_from_user<const timespec>(Userspace<timespec const*> src) { return copy_time_from_user(src.unsafe_userspace_ptr()); }
|
||||||
template<>
|
template<>
|
||||||
[[nodiscard]] Optional<Time> copy_time_from_user<timespec>(Userspace<timespec*> src) { return copy_time_from_user(src.unsafe_userspace_ptr()); }
|
KResultOr<Time> copy_time_from_user<timespec>(Userspace<timespec*> src) { return copy_time_from_user(src.unsafe_userspace_ptr()); }
|
||||||
|
|
||||||
Optional<u32> user_atomic_fetch_add_relaxed(volatile u32* var, u32 val)
|
Optional<u32> user_atomic_fetch_add_relaxed(volatile u32* var, u32 val)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,10 +19,10 @@ struct StringArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] Kernel::KResultOr<NonnullOwnPtr<Kernel::KString>> try_copy_kstring_from_user(Userspace<const char*>, size_t);
|
[[nodiscard]] Kernel::KResultOr<NonnullOwnPtr<Kernel::KString>> try_copy_kstring_from_user(Userspace<const char*>, size_t);
|
||||||
[[nodiscard]] Optional<Time> copy_time_from_user(const timespec*);
|
KResultOr<Time> copy_time_from_user(timespec const*);
|
||||||
[[nodiscard]] Optional<Time> copy_time_from_user(const timeval*);
|
KResultOr<Time> copy_time_from_user(timeval const*);
|
||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] Optional<Time> copy_time_from_user(Userspace<T*> src);
|
KResultOr<Time> copy_time_from_user(Userspace<T*>);
|
||||||
|
|
||||||
[[nodiscard]] Optional<u32> user_atomic_fetch_add_relaxed(volatile u32* var, u32 val);
|
[[nodiscard]] Optional<u32> user_atomic_fetch_add_relaxed(volatile u32* var, u32 val);
|
||||||
[[nodiscard]] Optional<u32> user_atomic_exchange_relaxed(volatile u32* var, u32 val);
|
[[nodiscard]] Optional<u32> user_atomic_exchange_relaxed(volatile u32* var, u32 val);
|
||||||
|
|
|
@ -42,13 +42,11 @@ KResultOr<FlatPtr> Process::sys$clock_settime(clockid_t clock_id, Userspace<cons
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
return EPERM;
|
return EPERM;
|
||||||
|
|
||||||
auto ts = copy_time_from_user(user_ts);
|
auto time = TRY(copy_time_from_user(user_ts));
|
||||||
if (!ts.has_value())
|
|
||||||
return EFAULT;
|
|
||||||
|
|
||||||
switch (clock_id) {
|
switch (clock_id) {
|
||||||
case CLOCK_REALTIME:
|
case CLOCK_REALTIME:
|
||||||
TimeManagement::the().set_epoch_time(ts.value());
|
TimeManagement::the().set_epoch_time(time);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
@ -62,9 +60,7 @@ KResultOr<FlatPtr> Process::sys$clock_nanosleep(Userspace<const Syscall::SC_cloc
|
||||||
REQUIRE_PROMISE(stdio);
|
REQUIRE_PROMISE(stdio);
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
|
|
||||||
Optional<Time> requested_sleep = copy_time_from_user(params.requested_sleep);
|
auto requested_sleep = TRY(copy_time_from_user(params.requested_sleep));
|
||||||
if (!requested_sleep.has_value())
|
|
||||||
return EFAULT;
|
|
||||||
|
|
||||||
bool is_absolute;
|
bool is_absolute;
|
||||||
switch (params.flags) {
|
switch (params.flags) {
|
||||||
|
@ -83,10 +79,10 @@ KResultOr<FlatPtr> Process::sys$clock_nanosleep(Userspace<const Syscall::SC_cloc
|
||||||
|
|
||||||
bool was_interrupted;
|
bool was_interrupted;
|
||||||
if (is_absolute) {
|
if (is_absolute) {
|
||||||
was_interrupted = Thread::current()->sleep_until(params.clock_id, requested_sleep.value()).was_interrupted();
|
was_interrupted = Thread::current()->sleep_until(params.clock_id, requested_sleep).was_interrupted();
|
||||||
} else {
|
} else {
|
||||||
Time remaining_sleep;
|
Time remaining_sleep;
|
||||||
was_interrupted = Thread::current()->sleep(params.clock_id, requested_sleep.value(), &remaining_sleep).was_interrupted();
|
was_interrupted = Thread::current()->sleep(params.clock_id, requested_sleep, &remaining_sleep).was_interrupted();
|
||||||
timespec remaining_sleep_ts = remaining_sleep.to_timespec();
|
timespec remaining_sleep_ts = remaining_sleep.to_timespec();
|
||||||
if (was_interrupted && params.remaining_sleep) {
|
if (was_interrupted && params.remaining_sleep) {
|
||||||
TRY(copy_to_user(params.remaining_sleep, &remaining_sleep_ts));
|
TRY(copy_to_user(params.remaining_sleep, &remaining_sleep_ts));
|
||||||
|
@ -111,12 +107,10 @@ KResultOr<FlatPtr> Process::sys$adjtime(Userspace<const timeval*> user_delta, Us
|
||||||
REQUIRE_PROMISE(settime);
|
REQUIRE_PROMISE(settime);
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
return EPERM;
|
return EPERM;
|
||||||
auto delta = copy_time_from_user(user_delta);
|
auto delta = TRY(copy_time_from_user(user_delta));
|
||||||
if (!delta.has_value())
|
|
||||||
return EFAULT;
|
|
||||||
|
|
||||||
// FIXME: Should use AK::Time internally
|
// FIXME: Should use AK::Time internally
|
||||||
TimeManagement::the().set_remaining_epoch_time_adjustment(delta->to_timespec());
|
TimeManagement::the().set_remaining_epoch_time_adjustment(delta.to_timespec());
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -41,12 +41,10 @@ KResultOr<FlatPtr> Process::sys$futex(Userspace<const Syscall::SC_futex_params*>
|
||||||
case FUTEX_REQUEUE:
|
case FUTEX_REQUEUE:
|
||||||
case FUTEX_CMP_REQUEUE: {
|
case FUTEX_CMP_REQUEUE: {
|
||||||
if (params.timeout) {
|
if (params.timeout) {
|
||||||
auto timeout_time = copy_time_from_user(params.timeout);
|
auto timeout_time = TRY(copy_time_from_user(params.timeout));
|
||||||
if (!timeout_time.has_value())
|
|
||||||
return EFAULT;
|
|
||||||
bool is_absolute = cmd != FUTEX_WAIT;
|
bool is_absolute = cmd != FUTEX_WAIT;
|
||||||
clockid_t clock_id = use_realtime_clock ? CLOCK_REALTIME_COARSE : CLOCK_MONOTONIC_COARSE;
|
clockid_t clock_id = use_realtime_clock ? CLOCK_REALTIME_COARSE : CLOCK_MONOTONIC_COARSE;
|
||||||
timeout = Thread::BlockTimeout(is_absolute, &timeout_time.value(), nullptr, clock_id);
|
timeout = Thread::BlockTimeout(is_absolute, &timeout_time, nullptr, clock_id);
|
||||||
}
|
}
|
||||||
if (cmd == FUTEX_WAIT_BITSET && params.val3 == FUTEX_BITSET_MATCH_ANY)
|
if (cmd == FUTEX_WAIT_BITSET && params.val3 == FUTEX_BITSET_MATCH_ANY)
|
||||||
cmd = FUTEX_WAIT;
|
cmd = FUTEX_WAIT;
|
||||||
|
|
|
@ -26,10 +26,8 @@ KResultOr<FlatPtr> Process::sys$select(Userspace<const Syscall::SC_select_params
|
||||||
|
|
||||||
Thread::BlockTimeout timeout;
|
Thread::BlockTimeout timeout;
|
||||||
if (params.timeout) {
|
if (params.timeout) {
|
||||||
Optional<Time> timeout_time = copy_time_from_user(params.timeout);
|
auto timeout_time = TRY(copy_time_from_user(params.timeout));
|
||||||
if (!timeout_time.has_value())
|
timeout = Thread::BlockTimeout(false, &timeout_time);
|
||||||
return EFAULT;
|
|
||||||
timeout = Thread::BlockTimeout(false, &timeout_time.value());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto current_thread = Thread::current();
|
auto current_thread = Thread::current();
|
||||||
|
@ -134,10 +132,8 @@ KResultOr<FlatPtr> Process::sys$poll(Userspace<const Syscall::SC_poll_params*> u
|
||||||
|
|
||||||
Thread::BlockTimeout timeout;
|
Thread::BlockTimeout timeout;
|
||||||
if (params.timeout) {
|
if (params.timeout) {
|
||||||
auto timeout_time = copy_time_from_user(params.timeout);
|
auto timeout_time = TRY(copy_time_from_user(params.timeout));
|
||||||
if (!timeout_time.has_value())
|
timeout = Thread::BlockTimeout(false, &timeout_time);
|
||||||
return EFAULT;
|
|
||||||
timeout = Thread::BlockTimeout(false, &timeout_time.value());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sigset_t sigmask = {};
|
sigset_t sigmask = {};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue