Skip to content

Commit

Permalink
[fuzzing] Fix fuzzer found bug (#33291)
Browse files Browse the repository at this point in the history
We had an infinite recursion in our tracer parsing code... probably not
a biggy, but it was blocking the fuzzers so fixing.

<!--

If you know who should review your pull request, please assign it to
that
person, otherwise the pull request would get assigned randomly.

If your pull request is for a specific language, please add the
appropriate
lang label.

-->
  • Loading branch information
ctiller committed May 31, 2023
1 parent bde9952 commit 2892b24
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 56 deletions.
79 changes: 24 additions & 55 deletions src/core/lib/debug/trace.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@

#include "src/core/lib/debug/trace.h"

#include <string.h>

#include <string>
#include <type_traits>
#include <utility>

#include "absl/strings/ascii.h"
#include "absl/strings/match.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"

#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>

#include "src/core/lib/config/config_vars.h"
Expand All @@ -40,31 +40,31 @@ namespace grpc_core {

TraceFlag* TraceFlagList::root_tracer_ = nullptr;

bool TraceFlagList::Set(const char* name, bool enabled) {
bool TraceFlagList::Set(absl::string_view name, bool enabled) {
TraceFlag* t;
if (0 == strcmp(name, "all")) {
if (name == "all") {
for (t = root_tracer_; t; t = t->next_tracer_) {
t->set_enabled(enabled);
}
} else if (0 == strcmp(name, "list_tracers")) {
} else if (name == "list_tracers") {
LogAllTracers();
} else if (0 == strcmp(name, "refcount")) {
} else if (name == "refcount") {
for (t = root_tracer_; t; t = t->next_tracer_) {
if (strstr(t->name_, "refcount") != nullptr) {
if (absl::StrContains(t->name_, "refcount")) {
t->set_enabled(enabled);
}
}
} else {
bool found = false;
for (t = root_tracer_; t; t = t->next_tracer_) {
if (0 == strcmp(name, t->name_)) {
if (name == t->name_) {
t->set_enabled(enabled);
found = true;
}
}
// check for unknowns, but ignore "", to allow to GRPC_TRACE=
if (!found && 0 != strcmp(name, "")) {
gpr_log(GPR_ERROR, "Unknown trace var: '%s'", name);
if (!found && !name.empty()) {
gpr_log(GPR_ERROR, "Unknown trace var: '%s'", std::string(name).c_str());
return false; // early return
}
}
Expand Down Expand Up @@ -101,59 +101,28 @@ SavedTraceFlags::SavedTraceFlags() { TraceFlagList::SaveTo(values_); }

void SavedTraceFlags::Restore() {
for (const auto& flag : values_) {
TraceFlagList::Set(flag.first.c_str(), flag.second);
}
}

} // namespace grpc_core

static void add(const char* beg, const char* end, char*** ss, size_t* ns) {
size_t n = *ns;
size_t np = n + 1;
char* s;
size_t len;
GPR_ASSERT(end >= beg);
len = static_cast<size_t>(end - beg);
s = static_cast<char*>(gpr_malloc(len + 1));
memcpy(s, beg, len);
s[len] = 0;
*ss = static_cast<char**>(gpr_realloc(*ss, sizeof(char**) * np));
(*ss)[n] = s;
*ns = np;
}

static void split(const char* s, char*** ss, size_t* ns) {
const char* c = strchr(s, ',');
if (c == nullptr) {
add(s, s + strlen(s), ss, ns);
} else {
add(s, c, ss, ns);
split(c + 1, ss, ns);
TraceFlagList::Set(flag.first, flag.second);
}
}

static void parse(const char* s) {
char** strings = nullptr;
size_t nstrings = 0;
size_t i;
split(s, &strings, &nstrings);

for (i = 0; i < nstrings; i++) {
if (strings[i][0] == '-') {
grpc_core::TraceFlagList::Set(strings[i] + 1, false);
namespace {
void ParseTracers(absl::string_view tracers) {
for (auto s : absl::StrSplit(tracers, ',')) {
s = absl::StripAsciiWhitespace(s);
if (s.empty()) continue;
if (s[0] == '-') {
TraceFlagList::Set(s.substr(1), false);
} else {
grpc_core::TraceFlagList::Set(strings[i], true);
TraceFlagList::Set(s, true);
}
}

for (i = 0; i < nstrings; i++) {
gpr_free(strings[i]);
}
gpr_free(strings);
}
} // namespace

} // namespace grpc_core

void grpc_tracer_init() {
parse(std::string(grpc_core::ConfigVars::Get().Trace()).c_str());
grpc_core::ParseTracers(grpc_core::ConfigVars::Get().Trace());
}

int grpc_tracer_set_enabled(const char* name, int enabled) {
Expand Down
4 changes: 3 additions & 1 deletion src/core/lib/debug/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include <map>
#include <string>

#include "absl/strings/string_view.h"

void grpc_tracer_init();
void grpc_tracer_shutdown(void);

Expand All @@ -33,7 +35,7 @@ namespace grpc_core {
class TraceFlag;
class TraceFlagList {
public:
static bool Set(const char* name, bool enabled);
static bool Set(absl::string_view name, bool enabled);
static void Add(TraceFlag* flag);
static void SaveTo(std::map<std::string, bool>& values);

Expand Down

Large diffs are not rendered by default.

0 comments on commit 2892b24

Please sign in to comment.