From 834dc3747c34bfff6e7025ec6479bad1f3c65ec4 Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Fri, 26 May 2023 06:14:06 +0100 Subject: [PATCH] ping: Avoid overflow for large interval values Previously `usleep()` was being used, which takes a 32-bit integer number of microseconds as a parameter. This caused an overflow for intervals larger than 4294 seconds. We now use `clock_nanosleep()` instead and ensure the user cannot specify a value larger than `UINT32_MAX` seconds. --- Userland/Utilities/ping.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Userland/Utilities/ping.cpp b/Userland/Utilities/ping.cpp index 2af9ca952a..f543094e0c 100644 --- a/Userland/Utilities/ping.cpp +++ b/Userland/Utilities/ping.cpp @@ -33,7 +33,7 @@ static int max_ms; static DeprecatedString host; static int payload_size = -1; static bool quiet = false; -static u64 interval_in_microseconds = 1'000'000; +static timespec interval_timespec { .tv_sec = 1, .tv_nsec = 0 }; // variable part of header can be 0 to 40 bytes // https://datatracker.ietf.org/doc/html/rfc791#section-3.1 static constexpr int max_optional_header_size_in_bytes = 40; @@ -78,10 +78,15 @@ ErrorOr serenity_main(Main::Arguments arguments) return false; auto interval_in_seconds = interval_in_seconds_string.to_double(); - if (!interval_in_seconds.has_value() || interval_in_seconds.value() <= 0) + if (!interval_in_seconds.has_value() || interval_in_seconds.value() <= 0 || interval_in_seconds.value() > UINT32_MAX) return false; - interval_in_microseconds = static_cast(interval_in_seconds.value() * 1'000'000); + auto whole_seconds = static_cast(interval_in_seconds.value()); + auto fractional_seconds = interval_in_seconds.value() - static_cast(whole_seconds); + interval_timespec = { + .tv_sec = whole_seconds, + .tv_nsec = static_cast(fractional_seconds * 1'000'000'000) + }; return true; }, }); @@ -234,6 +239,6 @@ ErrorOr serenity_main(Main::Arguments arguments) break; } - usleep(interval_in_microseconds); + clock_nanosleep(CLOCK_MONOTONIC, 0, &interval_timespec, nullptr); } }