From bdea76728b4b777b03e15f9e32f4f3fdb3346588 Mon Sep 17 00:00:00 2001 From: Yijie Ma Date: Tue, 21 Feb 2023 09:50:49 -0800 Subject: [PATCH] [fix] Prevent a signed integer overflow in timeout_encoding.cc (#32432) Return `Timeout(kMaxHours, Unit::kHours)` if the value is about to overflow in `DivideRoundingUp`. --- src/core/lib/transport/timeout_encoding.cc | 7 ++++++- test/core/end2end/fuzzers/client_fuzzer.cc | 6 +++++- .../testcase-5371891407519744 | Bin 0 -> 172 bytes 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/testcase-5371891407519744 diff --git a/src/core/lib/transport/timeout_encoding.cc b/src/core/lib/transport/timeout_encoding.cc index aa28eefc82e..97d0a6a7418 100644 --- a/src/core/lib/transport/timeout_encoding.cc +++ b/src/core/lib/transport/timeout_encoding.cc @@ -20,6 +20,8 @@ #include "src/core/lib/transport/timeout_encoding.h" +#include + #include "absl/base/attributes.h" #include @@ -30,7 +32,7 @@ namespace grpc_core { namespace { int64_t DivideRoundingUp(int64_t dividend, int64_t divisor) { - return (dividend + divisor - 1) / divisor; + return (dividend - 1 + divisor) / divisor; } constexpr int64_t kSecondsPerMinute = 60; @@ -173,6 +175,9 @@ Timeout Timeout::FromMillis(int64_t millis) { } else if (millis < 100000) { int64_t value = DivideRoundingUp(millis, 100); if (value % 10 != 0) return Timeout(value, Unit::kHundredMilliseconds); + } else if (millis > std::numeric_limits::max() - 999) { + // prevent signed integer overflow. + return Timeout(kMaxHours, Unit::kHours); } return Timeout::FromSeconds(DivideRoundingUp(millis, 1000)); } diff --git a/test/core/end2end/fuzzers/client_fuzzer.cc b/test/core/end2end/fuzzers/client_fuzzer.cc index 399a2a1c136..6d75d0b4936 100644 --- a/test/core/end2end/fuzzers/client_fuzzer.cc +++ b/test/core/end2end/fuzzers/client_fuzzer.cc @@ -25,6 +25,7 @@ #include "absl/status/statusor.h" #include "absl/strings/str_format.h" +#include "absl/types/optional.h" #include #include @@ -38,6 +39,7 @@ #include "src/core/lib/channel/channel_args_preconditioning.h" #include "src/core/lib/config/core_configuration.h" #include "src/core/lib/gprpp/crash.h" +#include "src/core/lib/gprpp/env.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/exec_ctx.h" @@ -59,7 +61,9 @@ static void* tag(intptr_t t) { return reinterpret_cast(t); } static void dont_log(gpr_log_func_args* /*args*/) {} extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - if (squelch) gpr_set_log_function(dont_log); + if (squelch && !grpc_core::GetEnv("GRPC_TRACE_FUZZER").has_value()) { + gpr_set_log_function(dont_log); + } grpc_init(); { grpc_core::ExecCtx exec_ctx; diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/testcase-5371891407519744 b/test/core/end2end/fuzzers/client_fuzzer_corpus/testcase-5371891407519744 new file mode 100644 index 0000000000000000000000000000000000000000..6889e6b717c464cad293b4682f92d6c1a11e34c8 GIT binary patch literal 172 zcmZQzU|?Zn009