26 lines
1.3 KiB
Diff
26 lines
1.3 KiB
Diff
# UNDF: UNDF-2026-000000176
|
|
--- a/sql/auth/sql_security_ctx.cc
|
|
+++ b/sql/auth/sql_security_ctx.cc
|
|
@@ -730,14 +730,20 @@ std::pair<bool, bool> Security_context::has_global_grant(const char *priv,
|
|
if (!acl_cache_lock.lock(false)) return std::make_pair(false, false);
|
|
const Role_id key(&m_priv_user[0], m_priv_user_length, &m_priv_host[0],
|
|
m_priv_host_length);
|
|
User_to_dynamic_privileges_map::iterator it, it_end;
|
|
std::tie(it, it_end) = get_dynamic_privileges_map()->equal_range(key);
|
|
- // CWE-407: std::find does O(P) linear scan over all P dynamic privileges
|
|
- // for this user in the multimap's equal range. Fix: local unordered_map.
|
|
- it = std::find(it, it_end, privilege);
|
|
- if (it != it_end) {
|
|
- return std::make_pair(true, it->second.second);
|
|
+ // CWE-407 fix (mysql-0002): build O(1) lookup map for this user's privileges
|
|
+ // instead of O(P) std::find linear scan over the equal_range result.
|
|
+ std::unordered_map<std::string, bool> local_priv_map;
|
|
+ for (auto jt = it; jt != it_end; ++jt) {
|
|
+ local_priv_map[jt->second.first] = jt->second.second;
|
|
+ }
|
|
+ auto found = local_priv_map.find(privilege);
|
|
+ if (found != local_priv_map.end()) {
|
|
+ return std::make_pair(true, found->second);
|
|
}
|
|
return std::make_pair(false, false);
|
|
}
|