# 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); */