3 KiB
gRPC — CWE-407 Disclosure Brief
2026-03-27 · Patch available — awaiting upstream merge
Finding
One O(n²) defect in gRPC's channelz property grid. GetIndex() in src/core/channelz/property_list.cc:28-36 uses std::find on std::vector<std::string> for column and row name lookup in PropertyGrid/PropertyTable, causing O(C²) + O(R²) overhead at high RPC rates. Patch ready for upstream review.
The Defects
grpc-0001 (PATCHED — HIGH): src/core/channelz/property_list.cc:28–36
// GetIndex() — per column/row name lookup:
size_t GetIndex(const std::vector<std::string>& names,
const std::string& name) {
auto it = std::find(names.begin(), names.end(), name);
// O(C) scan per column lookup; O(R) per row lookup
if (it == names.end()) { names.push_back(name); it = names.end() - 1; }
return std::distance(names.begin(), it);
}
// At 1000 RPC/s × 50 metrics: O(C²) + O(R²) = 2.5M scans/sec
std::find O(C) scan per column name and O(R) scan per row name. At 1000 RPC/s with 50 metrics: 2.5M scans/sec. Measured ratio: 25×.
Complexity Proof
For C=25 columns, R=25 rows per channelz update at 1000 RPC/s:
- Per update: O(C²) + O(R²) = 1,250 comparisons
- Fixed:
absl::flat_hash_map<std::string, size_t>shadow → O(C + R) per update - 25× measured ratio.
Impact
All gRPC deployments using channelz — the gRPC observability and debugging interface. Channelz is enabled by default and provides metrics on channels, subchannels, and servers. High-throughput gRPC services (microservices, service meshes) calling channelz at high RPC rates hit O(C²) + O(R²) per metric update. gRPC is used in virtually all cloud-native and microservice architectures; it powers internal service communication at major technology companies.
The Fix
Add absl::flat_hash_map<std::string, size_t> shadow alongside the ordered vector:
// Before
size_t GetIndex(std::vector<std::string>& names, const std::string& name) {
auto it = std::find(names.begin(), names.end(), name); // O(n)
...
}
// After
// CWE-407 fix: absl::flat_hash_map shadow for O(1) index lookup alongside ordered vector.
size_t GetIndex(std::vector<std::string>& names,
absl::flat_hash_map<std::string, size_t>& index,
const std::string& name) {
auto it = index.find(name);
if (it == index.end()) {
index[name] = names.size();
names.push_back(name);
return names.size() - 1;
}
return it->second;
}
Patch
defects/grpc/patch/grpc-0001-property-list-hashmap.patch
What We Ask
- Confirm receipt and assign a GitHub Security Advisory or issue reference.
- Validate the patch against your channelz and property grid test suite.
- Assess CVE eligibility — 2.5M scans/sec at 1000 RPC/s with 50 metrics.
- Coordinate a disclosure date — we are targeting 90 days from first contact.
Contact: see cover email. This brief is confidential until coordinated disclosure.