1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 21:37:35 +00:00

Kernel: Modify TimeManagement::current_time(..) API so it can't fail. (#6869)

The fact that current_time can "fail" makes its use a bit awkward.
All callers in the Kernel are trusted besides syscalls, so assert
that they never get there, and make sure all current callers perform
validation of the clock_id with TimeManagement::is_valid_clock_id().

I have fuzzed this change locally for a bit to make sure I didn't
miss any obvious regression.
This commit is contained in:
Brian Gianforcaro 2021-05-05 16:51:06 +00:00 committed by GitHub
parent 64b4e3f34b
commit 11306d7121
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 14 additions and 13 deletions

View file

@ -25,7 +25,7 @@ KResultOr<unsigned> Process::sys$alarm(unsigned seconds)
} }
if (seconds > 0) { if (seconds > 0) {
auto deadline = TimeManagement::the().current_time(CLOCK_REALTIME_COARSE).value(); auto deadline = TimeManagement::the().current_time(CLOCK_REALTIME_COARSE);
deadline = deadline + Time::from_seconds(seconds); deadline = deadline + Time::from_seconds(seconds);
m_alarm_timer = TimerQueue::the().add_timer_without_id(CLOCK_REALTIME_COARSE, deadline, [this]() { m_alarm_timer = TimerQueue::the().add_timer_without_id(CLOCK_REALTIME_COARSE, deadline, [this]() {
[[maybe_unused]] auto rc = send_signal(SIGALRM, nullptr); [[maybe_unused]] auto rc = send_signal(SIGALRM, nullptr);

View file

@ -14,13 +14,13 @@ KResultOr<int> Process::sys$clock_gettime(clockid_t clock_id, Userspace<timespec
{ {
REQUIRE_PROMISE(stdio); REQUIRE_PROMISE(stdio);
auto time = TimeManagement::the().current_time(clock_id); if (!TimeManagement::is_valid_clock_id(clock_id))
if (time.is_error()) return EINVAL;
return time.error();
auto ts = time.value().to_timespec(); auto ts = TimeManagement::the().current_time(clock_id).to_timespec();
if (!copy_to_user(user_ts, &ts)) if (!copy_to_user(user_ts, &ts))
return EFAULT; return EFAULT;
return 0; return 0;
} }

View file

@ -23,7 +23,7 @@ Thread::BlockTimeout::BlockTimeout(bool is_absolute, const Time* time, const Tim
m_time = *time; m_time = *time;
m_should_block = true; m_should_block = true;
} }
m_start_time = start_time ? *start_time : TimeManagement::the().current_time(clock_id).value(); m_start_time = start_time ? *start_time : TimeManagement::the().current_time(clock_id);
if (!is_absolute) if (!is_absolute)
m_time += m_start_time; m_time += m_start_time;
} }
@ -326,7 +326,7 @@ void Thread::SleepBlocker::calculate_remaining()
{ {
if (!m_remaining) if (!m_remaining)
return; return;
auto time_now = TimeManagement::the().current_time(m_deadline.clock_id()).value(); auto time_now = TimeManagement::the().current_time(m_deadline.clock_id());
if (time_now < m_deadline.absolute_time()) if (time_now < m_deadline.absolute_time())
*m_remaining = m_deadline.absolute_time() - time_now; *m_remaining = m_deadline.absolute_time() - time_now;
else else

View file

@ -44,7 +44,7 @@ bool TimeManagement::is_valid_clock_id(clockid_t clock_id)
}; };
} }
KResultOr<Time> TimeManagement::current_time(clockid_t clock_id) const Time TimeManagement::current_time(clockid_t clock_id) const
{ {
switch (clock_id) { switch (clock_id) {
case CLOCK_MONOTONIC: case CLOCK_MONOTONIC:
@ -58,7 +58,8 @@ KResultOr<Time> TimeManagement::current_time(clockid_t clock_id) const
case CLOCK_REALTIME_COARSE: case CLOCK_REALTIME_COARSE:
return epoch_time(TimePrecision::Coarse); return epoch_time(TimePrecision::Coarse);
default: default:
return KResult(EINVAL); // Syscall entrypoint is missing a is_valid_clock_id(..) check?
VERIFY_NOT_REACHED();
} }
} }

View file

@ -34,7 +34,7 @@ public:
static TimeManagement& the(); static TimeManagement& the();
static bool is_valid_clock_id(clockid_t); static bool is_valid_clock_id(clockid_t);
KResultOr<Time> current_time(clockid_t) const; Time current_time(clockid_t) const;
Time monotonic_time(TimePrecision = TimePrecision::Coarse) const; Time monotonic_time(TimePrecision = TimePrecision::Coarse) const;
Time monotonic_time_raw() const Time monotonic_time_raw() const
{ {

View file

@ -44,7 +44,7 @@ Time Timer::now(bool is_firing) const
break; break;
} }
} }
return TimeManagement::the().current_time(clock_id).value(); return TimeManagement::the().current_time(clock_id);
} }
TimerQueue& TimerQueue::the() TimerQueue& TimerQueue::the()
@ -59,7 +59,7 @@ UNMAP_AFTER_INIT TimerQueue::TimerQueue()
RefPtr<Timer> TimerQueue::add_timer_without_id(clockid_t clock_id, const Time& deadline, Function<void()>&& callback) RefPtr<Timer> TimerQueue::add_timer_without_id(clockid_t clock_id, const Time& deadline, Function<void()>&& callback)
{ {
if (deadline <= TimeManagement::the().current_time(clock_id).value()) if (deadline <= TimeManagement::the().current_time(clock_id))
return {}; return {};
// Because timer handlers can execute on any processor and there is // Because timer handlers can execute on any processor and there is
@ -117,7 +117,7 @@ void TimerQueue::add_timer_locked(NonnullRefPtr<Timer> timer)
TimerId TimerQueue::add_timer(clockid_t clock_id, const Time& deadline, Function<void()>&& callback) TimerId TimerQueue::add_timer(clockid_t clock_id, const Time& deadline, Function<void()>&& callback)
{ {
auto expires = TimeManagement::the().current_time(clock_id).value(); auto expires = TimeManagement::the().current_time(clock_id);
expires = expires + deadline; expires = expires + deadline;
return add_timer(adopt_ref(*new Timer(clock_id, expires, move(callback)))); return add_timer(adopt_ref(*new Timer(clock_id, expires, move(callback))));
} }