From: William Lallemand Date: Fri, 14 Aug 2026 09:39:12 +0000 (+0000) Subject: BUG/MINOR: spoe: check snprintf() return value in spoe_set_var/spoe_unset_var X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=23a2811b672b06103b1185ee3a49d6c157478097;p=thirdparty%2Fhaproxy.git BUG/MINOR: spoe: check snprintf() return value in spoe_set_var/spoe_unset_var snprintf() returns the length it would have written, not what actually fit in varname[64]. A SET-VAR/UNSET-VAR name long enough to overflow that buffer left len oversized, causing an out-of-bounds stack read in the variable-name validation and hashing in vars_fill_desc(). Reject the action instead of proceeding on truncation: an oversized name would otherwise be silently used under a different, truncated name, which could let two distinct long names collide on the same 63-byte prefix. This should be backported to all stable branches. Reported-by: Aisle Research Reported-by: Oyvind Albrigtsen --- diff --git a/src/flt_spoe.c b/src/flt_spoe.c index cc107d18a..04afe6c14 100644 --- a/src/flt_spoe.c +++ b/src/flt_spoe.c @@ -717,6 +717,9 @@ static void spoe_set_var(struct spoe_context *ctx, char *scope, char *name, int memset(varname, 0, sizeof(varname)); len = snprintf(varname, sizeof(varname), "%s.%s.%.*s", scope, agent->var_pfx, len, name); + /* reject truncated (thus different) names instead of using them */ + if (len < 0 || len >= (int)sizeof(varname)) + return; if (agent->flags & SPOE_FL_FORCE_SET_VAR) vars_set_by_name(varname, len, smp); else @@ -734,6 +737,9 @@ static void spoe_unset_var(struct spoe_context *ctx, char *scope, char *name, in memset(varname, 0, sizeof(varname)); len = snprintf(varname, sizeof(varname), "%s.%s.%.*s", scope, agent->var_pfx, len, name); + /* reject truncated (thus different) names instead of using them */ + if (len < 0 || len >= (int)sizeof(varname)) + return; vars_unset_by_name_ifexist(varname, len, smp); }