BUG/MEDIUM: server: fix misuse of format string in load-server-state's warnings

Commit e11cfcd ("MINOR: config: new backend directives:
load-server-state-from-file and server-state-file-name") introduced a bug
which can cause haproxy to crash upon startup by sending user-controlled
data in a format string when emitting a warning. Fix the way the warning
message is built to avoid this.

No backport is needed, this was introduced in 1.6-dev6 only.
This commit is contained in:
Willy Tarreau 2015-09-29 18:38:47 +02:00
parent e1aebb2994
commit 31138fae9f

View File

@ -1897,9 +1897,8 @@ struct server *server_find_best_match(struct proxy *bk, char *name, int id, int
/* Update a server state using the parameters available in the params list */ /* Update a server state using the parameters available in the params list */
static void srv_update_state(struct server *srv, int version, char **params) static void srv_update_state(struct server *srv, int version, char **params)
{ {
int msg_default_len;
char *p; char *p;
struct chunk *msg = get_trash_chunk(); struct chunk *msg;
/* fields since version 1 /* fields since version 1
* and common to all other upcoming versions * and common to all other upcoming versions
@ -1916,8 +1915,7 @@ static void srv_update_state(struct server *srv, int version, char **params)
int bk_f_forced_id; int bk_f_forced_id;
int srv_f_forced_id; int srv_f_forced_id;
chunk_printf(msg, "server-state application failed for server '%s/%s'", srv->proxy->id, srv->id); msg = get_trash_chunk();
msg_default_len = msg->len;
switch (version) { switch (version) {
case 1: case 1:
/* /*
@ -2045,7 +2043,7 @@ static void srv_update_state(struct server *srv, int version, char **params)
/* don't apply anything if one error has been detected */ /* don't apply anything if one error has been detected */
if (msg->len > msg_default_len) if (msg->len)
goto out; goto out;
/* recover operational state and apply it to this server /* recover operational state and apply it to this server
@ -2151,11 +2149,9 @@ static void srv_update_state(struct server *srv, int version, char **params)
} }
out: out:
if (msg->len > msg_default_len) { if (msg->len)
chunk_appendf(msg, "\n"); Warning("server-state application failed for server '%s/%s'%s",
Warning(msg->str); srv->proxy->id, srv->id, msg->str);
}
} }
/* This function parses all the proxies and only take care of the backends (since we're looking for server) /* This function parses all the proxies and only take care of the backends (since we're looking for server)