Use subprocess API in the Centipede adaptor to replace popen, which is unsafe. PiperOrigin-RevId: 764368879
diff --git a/fuzztest/BUILD b/fuzztest/BUILD index d7a6eeb..933f539 100644 --- a/fuzztest/BUILD +++ b/fuzztest/BUILD
@@ -221,6 +221,7 @@ ":io", ":logging", ":runtime", + ":subprocess", ":table_of_recent_compares", "@abseil-cpp//absl/algorithm:container", "@abseil-cpp//absl/base:no_destructor",
diff --git a/fuzztest/internal/centipede_adaptor.cc b/fuzztest/internal/centipede_adaptor.cc index 273afa5..7eb0e87 100644 --- a/fuzztest/internal/centipede_adaptor.cc +++ b/fuzztest/internal/centipede_adaptor.cc
@@ -84,6 +84,7 @@ #include "./fuzztest/internal/io.h" #include "./fuzztest/internal/logging.h" #include "./fuzztest/internal/runtime.h" +#include "./fuzztest/internal/subprocess.h" #include "./fuzztest/internal/table_of_recent_compares.h" namespace fuzztest::internal { @@ -339,14 +340,26 @@ absl::StrAppend(&cmdline, ShellEscape(flag)); } absl::FPrintF(GetStderr(), "[.] Running Centipede command %s\n", cmdline); - FILE* pipe = popen(cmdline.c_str(), "r"); - FUZZTEST_INTERNAL_CHECK(pipe != nullptr, "popen failed with errno %d", - errno); - char buf[1024]; - while (std::fgets(buf, sizeof(buf), pipe)) { - std::fputs(buf, GetStderr()); + const std::vector<std::string> shell_cmd = {"/bin/sh", "-c", + std::move(cmdline)}; + const TerminationStatus status = RunCommandWithOutputCallbacks( + shell_cmd, + [](absl::string_view stdout_output) { + std::fwrite(stdout_output.data(), 1, stdout_output.size(), + GetStderr()); + }, + [](absl::string_view stderr_output) { + std::fwrite(stderr_output.data(), 1, stderr_output.size(), + GetStderr()); + }, + /*environment=*/std::nullopt); + if (status.Signaled()) { + // Encoding signaled exit similarly as Bash. + return 128 + static_cast<int>(std::get<SignalT>(status.Status())); } - return pclose(pipe); + FUZZTEST_INTERNAL_CHECK( + status.Exited(), "Termination status must be Exited if not Signaled"); + return static_cast<int>(std::get<ExitCodeT>(status.Status())); } static absl::NoDestructor<DefaultCallbacksFactory<CentipedeDefaultCallbacks>> factory;