From: Thierry Fournier Date: Wed, 1 Jun 2016 11:35:36 +0000 (+0200) Subject: BUG/MEDIUM: http: add-header: buffer overwritten X-Git-Tag: v1.7-dev4~78 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4b788f7d349ddde3f70f063b7394529eac6ab678;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: http: add-header: buffer overwritten If we use the action "http-request add-header" with a Lua sample-fetch or converter, and the Lua function calls one of the Lua log function, the header name is corrupted, it contains an extract of the last loggued data. This is due to an overwrite of the trash buffer, because his scope is not respected in the "add-header" function. The scope of the trash buffer must be limited to the function using it. The build_logline() function can execute a lot of other function which can use the trash buffer. This patch fix the usage of the trash buffer. It limits the scope of this global buffer to the local function, we build first the header value using build_logline, and after we store the header name. Thanks Michael Ezzell for the repporting. This patch must be backported in 1.6 version --- diff --git a/src/proto_http.c b/src/proto_http.c index d32acb0e1f..3ca456e824 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -3290,6 +3290,7 @@ http_req_get_intercept_rule(struct proxy *px, struct list *rules, struct stream struct hdr_ctx ctx; const char *auth_realm; int act_flags = 0; + int len; /* If "the current_rule_list" match the executed rule list, we are in * resume condition. If a resume is needed it is always in the action @@ -3401,11 +3402,18 @@ resume_execution: case ACT_HTTP_SET_HDR: case ACT_HTTP_ADD_HDR: + /* The scope of the trash buffer must be limited to this function. The + * build_logline() function can execute a lot of other function which + * can use the trash buffer. So for limiting the scope of this global + * buffer, we build first the header value using build_logline, and + * after we store the header name. + */ + len = rule->arg.hdr_add.name_len + 2, + len += build_logline(s, trash.str + len, trash.size - len, &rule->arg.hdr_add.fmt); memcpy(trash.str, rule->arg.hdr_add.name, rule->arg.hdr_add.name_len); - trash.len = rule->arg.hdr_add.name_len; - trash.str[trash.len++] = ':'; - trash.str[trash.len++] = ' '; - trash.len += build_logline(s, trash.str + trash.len, trash.size - trash.len, &rule->arg.hdr_add.fmt); + trash.str[rule->arg.hdr_add.name_len] = ':'; + trash.str[rule->arg.hdr_add.name_len + 1] = ' '; + trash.len = len; if (rule->action == ACT_HTTP_SET_HDR) { /* remove all occurrences of the header */