Freeze bvar dump path flags and cap pprof duration by FLAGS_max_profiling_seconds - #3523
Open
chenBright wants to merge 1 commit into
Open
Freeze bvar dump path flags and cap pprof duration by FLAGS_max_profiling_seconds#3523chenBright wants to merge 1 commit into
chenBright wants to merge 1 commit into
Conversation
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The new /pprof duration clamp can produce misleading errors in edge cases (e.g., max_profiling_seconds=0), and the security-relevant behavior changes would benefit from targeted unit test coverage to prevent regressions.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR hardens brpc builtin endpoints by preventing runtime repointing of bvar dump output paths via /flags, and by ensuring /pprof respects the same profiling-duration cap as /hotspots.
Changes:
- Removed gflags validators for
bvar_dump_file,bvar_dump_tabs, andmbvar_dump_fileso/flags/...?...setvalue=can no longer modify these path-like flags at runtime. - Added clamping in
/pprof’sReadSeconds()toFLAGS_max_profiling_seconds(consistent with/hotspots). - Centralized
max_profiling_secondsflag definition inbuiltin/common.{h,cpp}for shared use.
File summaries
| File | Description |
|---|---|
| src/bvar/variable.cpp | Stops making dump path-related flags reloadable via /flags by removing their validator registration; updates flag descriptions accordingly. |
| src/brpc/builtin/pprof_service.cpp | Clamps requested profiling duration to FLAGS_max_profiling_seconds. |
| src/brpc/builtin/hotspots_service.cpp | Removes local definition/validation of max_profiling_seconds (now shared). |
| src/brpc/builtin/common.h | Declares max_profiling_seconds for builtin services. |
| src/brpc/builtin/common.cpp | Defines and validates max_profiling_seconds in a shared location. |
Review details
- Files reviewed: 5/5 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
57
to
72
| static int ReadSeconds(Controller* cntl) { | ||
| int seconds = 0; | ||
| const std::string* param = | ||
| cntl->http_request().uri().GetQuery("seconds"); | ||
| if (param != nullptr) { | ||
| char* endptr = nullptr; | ||
| const long sec = strtol(param->c_str(), &endptr, 10); | ||
| if (endptr == param->c_str() + param->length()) { | ||
| seconds = sec; | ||
| } else { | ||
| cntl->SetFailed(EINVAL, "Invalid seconds=%s", param->c_str()); | ||
| } | ||
| } | ||
|
|
||
| return seconds; | ||
| return std::min(seconds, FLAGS_max_profiling_seconds); | ||
| } |
chenBright
force-pushed
the
fix_flags
branch
from
September 4, 2026 18:15
fba40cc to
d14fedf
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What problem does this PR solve?
Issue Number: resolve
Problem Summary:
Two builtin services let whoever reaches them do more than the surrounding
configuration intends.
/flagscan repoint the bvar dump files.The bvar dump flags carry an accept-anything validator whose only job is to
wake the dumping thread:
The dumping thread re-reads those flags every round and ends up in
FileDumper::dump_impl():So two requests against a server with default options:
create a directory chain anywhere and truncate a file inside it, with the
privileges of the server.
setvalueis a GET, so this is reachable from abrowser as well.
The primitive is bounded but real.
bvar_dump_fileandbvar_dump_tabsget a.datasuffix forced on them byFilePath::AddExtension(), and the byteswritten are bvar names and values, not attacker input.
mbvar_dump_fileisused verbatim with no suffix.
bvar_dump_tabsnames files too: its tab namesgo through the same
AddExtension(), which appends them to the path with nosanitization, so
../in a tab name escapes the configured directory. Therecursive mkdir and the truncation are unrestricted in every case.
/pprofignoresFLAGS_max_profiling_seconds, which/hotspotsenforces.// src/brpc/builtin/hotspots_service.cpp:233 seconds = std::min(seconds, FLAGS_max_profiling_seconds);?seconds=2147483647reachesbthread_usleep(sleep_sec * 1000000L), roughly68 years. The profilers are process wide -- gperftools'
ProfilerStartandbthread's
g_cpare each a single global, so this is not merely one hungRPC: it holds the only CPU or contention profiler for as long as it asked for,
and
/hotspots/cpuand/hotspots/contentionanswer 503 the whole time. The300 second limit was enforced on only one of the two paths to the same
resource, so the path without it decides the limit for both.
What is changed and the side effects?
Changed:
,-bvar_dump_tabsandFLAGS_mbvar_dump_file`.ReadSeconds()toFLAGS_max_profiling_seconds.Side effects:
Performance effects:
Breaking backward compatibility:
Check List: