From: Remi Tricot-Le Breton Date: Thu, 31 Aug 2023 13:58:08 +0000 (+0200) Subject: MINOR: cache: Change hash function in default normalizer used in case of "vary" X-Git-Tag: v2.9-dev5~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e03d060aa308e3ba51aeb60b677425eab3d195bd;p=thirdparty%2Fhaproxy.git MINOR: cache: Change hash function in default normalizer used in case of "vary" When building the secondary signature for cache entries when vary is enabled, the referer part of the signature was a simple crc32 of the first referer header. This patch changes it to a 64bits hash based of xxhash algorithm with a random seed built during init. This will prevent "malicious" hash collisions between entries of the cache. --- diff --git a/include/haproxy/http_ana-t.h b/include/haproxy/http_ana-t.h index 1d6ab58997..39ec989946 100644 --- a/include/haproxy/http_ana-t.h +++ b/include/haproxy/http_ana-t.h @@ -157,7 +157,7 @@ static forceinline char *hmsg_show_flags(char *buf, size_t len, const char *deli * request/response pairs, because they depend on the responses' optional Vary * header. The different sizes can be found in the vary_information object (see * cache.c).*/ -#define HTTP_CACHE_SEC_KEY_LEN (sizeof(uint32_t)+sizeof(int)) +#define HTTP_CACHE_SEC_KEY_LEN (sizeof(uint32_t)+sizeof(uint64_t)) /* Redirect flags */ diff --git a/src/cache.c b/src/cache.c index 8118387c9f..b9fd47e7ba 100644 --- a/src/cache.c +++ b/src/cache.c @@ -35,11 +35,14 @@ #include #include #include +#include #define CACHE_FLT_F_IMPLICIT_DECL 0x00000001 /* The cache filtre was implicitly declared (ie without * the filter keyword) */ #define CACHE_FLT_INIT 0x00000002 /* Whether the cache name was freed. */ +static uint64_t cache_hash_seed = 0; + const char *cache_store_flt_id = "cache store filter"; extern struct applet http_cache_applet; @@ -139,7 +142,7 @@ static int accept_encoding_bitmap_cmp(const void *ref, const void *new, unsigned * added to this array. */ const struct vary_hashing_information vary_information[] = { { IST("accept-encoding"), VARY_ACCEPT_ENCODING, sizeof(uint32_t), &accept_encoding_normalizer, &accept_encoding_bitmap_cmp }, - { IST("referer"), VARY_REFERER, sizeof(int), &default_normalizer, NULL }, + { IST("referer"), VARY_REFERER, sizeof(uint64_t), &default_normalizer, NULL }, }; @@ -2368,7 +2371,7 @@ static int accept_encoding_normalizer(struct htx *htx, struct ist hdr_name, /* * Normalizer used by default for the Referer header. It only - * calculates a simple crc of the whole value. + * calculates a hash of the whole value using xxhash algorithm. * Only the first occurrence of the header will be taken into account in the * hash. * Returns 0 in case of success, 1 if the hash buffer should be filled with 0s @@ -2382,8 +2385,8 @@ static int default_normalizer(struct htx *htx, struct ist hdr_name, if (http_find_header(htx, hdr_name, &ctx, 1)) { retval = 0; - write_u32(buf, hash_crc32(istptr(ctx.value), istlen(ctx.value))); - *buf_len = sizeof(int); + write_u64(buf, XXH3(istptr(ctx.value), istlen(ctx.value), cache_hash_seed)); + *buf_len = sizeof(uint64_t); } return retval; @@ -2702,6 +2705,15 @@ smp_fetch_res_cache_name(const struct arg *args, struct sample *smp, return 0; } + +/* early boot initialization */ +static void cache_init() +{ + cache_hash_seed = ha_random64(); +} + +INITCALL0(STG_PREPARE, cache_init); + /* Declare the filter parser for "cache" keyword */ static struct flt_kw_list filter_kws = { "CACHE", { }, { { "cache", parse_cache_flt, NULL },