]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: spoe: check snprintf() return value in spoe_set_var/spoe_unset_var
authorWilliam Lallemand <wlallemand@haproxy.com>
Fri, 14 Aug 2026 09:39:12 +0000 (09:39 +0000)
committerWilliam Lallemand <wlallemand@haproxy.com>
Fri, 14 Aug 2026 09:44:00 +0000 (09:44 +0000)
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 <oalbrigt@redhat.com>
src/flt_spoe.c

index cc107d18a7bd5167de50f7e7f86cfdb65c8f958b..04afe6c14da7551641cacd799dd82c3159680a88 100644 (file)
@@ -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);
 }