[core] Reduce maximum number of validation errors to track (#36537)

Fuzzers were OOMing while trying to create 10k errors. This sets a sane default.

Closes #36537

COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36537 from drfloob:less-validation-noise db835d948a
PiperOrigin-RevId: 631158900
pull/36530/head
AJ Heller 10 months ago committed by Copybara-Service
parent 32e03171e7
commit 24c86247ac
  1. 2
      src/core/BUILD
  2. 12
      src/core/lib/gprpp/validation_errors.cc
  3. 11
      src/core/lib/gprpp/validation_errors.h
  4. 19209
      test/core/ext/filters/event_engine_client_channel_resolver/resolver_fuzzer_corpus/oom-5ba31fb3-0ea9-4ec7-b1f1-ae071d66b928

@ -399,7 +399,7 @@ grpc_cc_library(
"absl/strings", "absl/strings",
], ],
language = "c++", language = "c++",
deps = ["//:gpr_platform"], deps = ["//:gpr"],
) )
grpc_cc_library( grpc_cc_library(

@ -14,6 +14,8 @@
#include "src/core/lib/gprpp/validation_errors.h" #include "src/core/lib/gprpp/validation_errors.h"
#include <inttypes.h>
#include <utility> #include <utility>
#include "absl/status/status.h" #include "absl/status/status.h"
@ -21,6 +23,7 @@
#include "absl/strings/str_join.h" #include "absl/strings/str_join.h"
#include "absl/strings/strip.h" #include "absl/strings/strip.h"
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h> #include <grpc/support/port_platform.h>
namespace grpc_core { namespace grpc_core {
@ -34,7 +37,14 @@ void ValidationErrors::PushField(absl::string_view ext) {
void ValidationErrors::PopField() { fields_.pop_back(); } void ValidationErrors::PopField() { fields_.pop_back(); }
void ValidationErrors::AddError(absl::string_view error) { void ValidationErrors::AddError(absl::string_view error) {
field_errors_[absl::StrJoin(fields_, "")].emplace_back(error); auto key = absl::StrJoin(fields_, "");
if (field_errors_[key].size() >= max_error_count_) {
gpr_log(GPR_DEBUG,
"Ignoring validation error: too many errors found (%" PRIuPTR ")",
max_error_count_);
return;
}
field_errors_[key].emplace_back(error);
} }
bool ValidationErrors::FieldHasErrors() const { bool ValidationErrors::FieldHasErrors() const {

@ -63,6 +63,9 @@ namespace grpc_core {
// } // }
class ValidationErrors { class ValidationErrors {
public: public:
// Default maximum number of errors to track per scope.
static constexpr size_t kMaxErrorCount = 20;
// Pushes a field name onto the stack at construction and pops it off // Pushes a field name onto the stack at construction and pops it off
// of the stack at destruction. // of the stack at destruction.
class ScopedField { class ScopedField {
@ -93,6 +96,12 @@ class ValidationErrors {
ValidationErrors* errors_; ValidationErrors* errors_;
}; };
ValidationErrors() : ValidationErrors(kMaxErrorCount) {}
// Creates a tracker that collects at most `max_error_count` errors per field.
explicit ValidationErrors(size_t max_error_count)
: max_error_count_(max_error_count) {}
// Records that we've encountered an error associated with the current // Records that we've encountered an error associated with the current
// field. // field.
void AddError(absl::string_view error) GPR_ATTRIBUTE_NOINLINE; void AddError(absl::string_view error) GPR_ATTRIBUTE_NOINLINE;
@ -127,6 +136,8 @@ class ValidationErrors {
// Stack of field names indicating the field that we are currently // Stack of field names indicating the field that we are currently
// validating. // validating.
std::vector<std::string> fields_; std::vector<std::string> fields_;
size_t max_error_count_;
}; };
} // namespace grpc_core } // namespace grpc_core

Loading…
Cancel
Save