80 lines
2.5 KiB
Diff
80 lines
2.5 KiB
Diff
# UNDF: UNDF-2026-000000185
|
|
--- a/src/http/ngx_http_upstream.c
|
|
+++ b/src/http/ngx_http_upstream.c
|
|
@@ -1036,30 +1036,55 @@ ngx_http_upstream_cache_get(ngx_http_request_t *r, ngx_http_upstream_t *u,
|
|
ngx_http_file_cache_t **cache)
|
|
{
|
|
- ngx_str_t *name, val;
|
|
- ngx_uint_t i;
|
|
- ngx_http_file_cache_t **caches;
|
|
+ ngx_str_t val;
|
|
+ ngx_uint_t key;
|
|
+ ngx_http_file_cache_t *fc;
|
|
|
|
if (u->conf->cache_zone) {
|
|
*cache = u->conf->cache_zone->data;
|
|
return NGX_OK;
|
|
}
|
|
|
|
if (ngx_http_complex_value(r, u->conf->cache_value, &val) != NGX_OK) {
|
|
return NGX_ERROR;
|
|
}
|
|
|
|
if (val.len == 0
|
|
|| (val.len == 3 && ngx_strncmp(val.data, "off", 3) == 0))
|
|
{
|
|
return NGX_DECLINED;
|
|
}
|
|
|
|
- caches = u->caches->elts;
|
|
-
|
|
- for (i = 0; i < u->caches->nelts; i++) {
|
|
- name = &caches[i]->shm_zone->shm.name;
|
|
-
|
|
- if (name->len == val.len
|
|
- && ngx_strncmp(name->data, val.data, val.len) == 0)
|
|
- {
|
|
- *cache = caches[i];
|
|
- return NGX_OK;
|
|
- }
|
|
+ /*
|
|
+ * CWE-407 fix: replace O(n) linear strncmp scan with O(1) hash lookup.
|
|
+ * u->conf->caches_hash is built at configuration time in
|
|
+ * ngx_http_upstream_conf_init() by inserting each cache zone's shm name.
|
|
+ */
|
|
+ key = ngx_hash_key_lc(val.data, val.len);
|
|
+ fc = ngx_hash_find(&u->conf->caches_hash, key, val.data, val.len);
|
|
+ if (fc != NULL) {
|
|
+ *cache = fc;
|
|
+ return NGX_OK;
|
|
}
|
|
|
|
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
|
"cache \"%V\" not found", &val);
|
|
|
|
return NGX_ERROR;
|
|
}
|
|
|
|
--- a/src/http/ngx_http_upstream.h
|
|
+++ b/src/http/ngx_http_upstream.h
|
|
@@ -121,6 +121,7 @@ struct ngx_http_upstream_conf_s {
|
|
ngx_array_t *caches; /* ngx_http_file_cache_t * */
|
|
+ ngx_hash_t caches_hash; /* name → ngx_http_file_cache_t * */
|
|
#endif
|
|
|
|
ngx_http_upstream_next_t *next_upstream_tries;
|
|
|
|
/* Configuration-time initialisation (add to ngx_http_upstream_conf_init or
|
|
* equivalent post-config hook):
|
|
*
|
|
* ngx_hash_init_t hash;
|
|
* hash.hash = &umcf->caches_hash;
|
|
* hash.key = ngx_hash_key_lc;
|
|
* hash.max_size = 64;
|
|
* hash.bucket_size = ngx_align(64, ngx_cacheline_size);
|
|
* hash.name = "upstream_caches_hash";
|
|
* hash.pool = cf->pool;
|
|
* hash.temp_pool = NULL;
|
|
* // populate keys from umcf->caches array, value = caches[i]
|
|
* ngx_hash_init(&hash, keys.keys.elts, keys.keys.nelts);
|
|
*/
|