Description: Fix CVE-2012-2942
Bug-Debian: http://bugs.debian.org/674447
Forwarded: not-needed

--- haproxy-1.4.15.orig/include/types/global.h
+++ haproxy-1.4.15/include/types/global.h
@@ -104,7 +104,8 @@ extern int  pid;                /* curre
 extern int  relative_pid;       /* process id starting at 1 */
 extern int  actconn;            /* # of active sessions */
 extern int listeners;
-extern char trash[BUFSIZE];
+extern char *trash;
+extern int  trashlen;
 extern char *swap_buffer;
 extern int nb_oldpids;          /* contains the number of old pids found */
 extern const int zero;
--- haproxy-1.4.15.orig/tests/0000-debug-stats.diff
+++ haproxy-1.4.15/tests/0000-debug-stats.diff
@@ -35,12 +35,12 @@ index ddadddd..28bbfce 100644
 +
 +			if (1) {
 +				for (i=0; i<16096; i++)
-+					chunk_printf(&msg, sizeof(trash), "*");
++					chunk_printf(&msg, trashlen, "*");
 +
 +				chunk_printf(&msg, sizeof(trash), "\n");
 +#if 0
  			if (!(s->data_ctx.stats.flags & STAT_FMT_CSV)) {
- 				chunk_printf(&msg, sizeof(trash),
+				chunk_printf(&msg, trashlen,
  				     /* name, queue */
 @@ -694,6 +702,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
  				     px->failed_req,
@@ -48,7 +48,7 @@ index ddadddd..28bbfce 100644
  				     px->state == PR_STIDLE ? "FULL" : "STOP");
 +#endif
  			} else {
- 				chunk_printf(&msg, sizeof(trash),
+				 chunk_printf(&msg, trashlen,
  				     /* pxid, name, queue cur, queue max, */
 
 
--- haproxy-1.4.15.orig/src/checks.c
+++ haproxy-1.4.15/src/checks.c
@@ -235,7 +235,7 @@ static void set_server_check_status(stru
 
 		int health, rise, fall, state;
 
-		chunk_init(&msg, trash, sizeof(trash));
+		chunk_init(&msg, trash, trashlen);
 
 		/* FIXME begin: calculate local version of the health/rise/fall/state */
 		health = s->health;
@@ -385,7 +385,7 @@ void set_server_down(struct server *s)
 		 */
 		xferred = redistribute_pending(s);
 
-		chunk_init(&msg, trash, sizeof(trash));
+		chunk_init(&msg, trash, trashlen);
 
 		if (s->state & SRV_MAINTAIN) {
 			chunk_printf(&msg,
@@ -464,7 +464,7 @@ void set_server_up(struct server *s) {
 		 */
 		xferred = check_for_pending(s);
 
-		chunk_init(&msg, trash, sizeof(trash));
+		chunk_init(&msg, trash, trashlen);
 
 		if (s->state & SRV_MAINTAIN) {
 			chunk_printf(&msg,
@@ -512,7 +512,7 @@ static void set_server_disabled(struct s
 	 */
 	xferred = redistribute_pending(s);
 
-	chunk_init(&msg, trash, sizeof(trash));
+	chunk_init(&msg, trash, trashlen);
 
 	chunk_printf(&msg,
 		"Load-balancing on %sServer %s/%s is disabled",
@@ -548,7 +548,7 @@ static void set_server_enabled(struct se
 	 */
 	xferred = check_for_pending(s);
 
-	chunk_init(&msg, trash, sizeof(trash));
+	chunk_init(&msg, trash, trashlen);
 
 	chunk_printf(&msg,
 		"Load-balancing on %sServer %s/%s is enabled again",
--- haproxy-1.4.15.orig/src/proto_http.c
+++ haproxy-1.4.15/src/proto_http.c
@@ -379,14 +379,14 @@ const char http_is_ver_token[256] = {
 static void http_silent_debug(int line, struct session *s)
 {
 	int size = 0;
-	size += snprintf(trash + size, sizeof(trash) - size,
+	size += snprintf(trash + size, trashlen - size,
 			 "[%04d] req: p=%d(%d) s=%d bf=%08x an=%08x data=%p size=%d l=%d w=%p r=%p lr=%p sm=%d fw=%ld tf=%08x\n",
 			 line,
 			 s->si[0].state, s->si[0].fd, s->txn.req.msg_state, s->req->flags, s->req->analysers,
 			 s->req->data, s->req->size, s->req->l, s->req->w, s->req->r, s->req->lr, s->req->send_max, s->req->to_forward, s->txn.flags);
 	write(-1, trash, size);
 	size = 0;
-	size += snprintf(trash + size, sizeof(trash) - size,
+	size += snprintf(trash + size, trashlen - size,
 			 " %04d  rep: p=%d(%d) s=%d bf=%08x an=%08x data=%p size=%d l=%d w=%p r=%p lr=%p sm=%d fw=%ld\n",
 			 line,
 			 s->si[1].state, s->si[1].fd, s->txn.rsp.msg_state, s->rep->flags, s->rep->analysers,
@@ -751,7 +751,7 @@ void perform_http_redirect(struct sessio
 	/* 1: create the response header */
 	rdr.len = strlen(HTTP_302);
 	rdr.str = trash;
-	rdr.size = sizeof(trash);
+	rdr.size = trashlen;
 	memcpy(rdr.str, HTTP_302, rdr.len);
 
 	/* 2: add the server's prefix */
@@ -3129,7 +3129,7 @@ int http_process_req_common(struct sessi
 			realm = do_stats?STATS_DEFAULT_REALM:px->id;
 
 		sprintf(trash, (txn->flags & TX_USE_PX_CONN) ? HTTP_407_fmt : HTTP_401_fmt, realm);
-		chunk_initlen(&msg, trash, sizeof(trash), strlen(trash));
+		chunk_initlen(&msg, trash, trashlen, strlen(trash));
 		txn->status = 401;
 		stream_int_retnclose(req->prod, &msg);
 		goto return_prx_cond;
@@ -3216,7 +3216,7 @@ int http_process_req_common(struct sessi
 		}
 
 		if (ret) {
-			struct chunk rdr = { .str = trash, .size = sizeof(trash), .len = 0 };
+			struct chunk rdr = { .str = trash, .size = trashlen, .len = 0 };
 			const char *msg_fmt;
 
 			/* build redirect message */
@@ -7359,7 +7359,7 @@ void debug_hdr(const char *dir, struct s
 	len = sprintf(trash, "%08x:%s.%s[%04x:%04x]: ", t->uniq_id, t->be->id,
 		      dir, (unsigned  short)t->req->prod->fd, (unsigned short)t->req->cons->fd);
 	max = end - start;
-	UBOUND(max, sizeof(trash) - len - 1);
+	UBOUND(max, trashlen - len - 1);
 	len += strlcpy2(trash + len, start, max + 1);
 	trash[len++] = '\n';
 	write(1, trash, len);
--- haproxy-1.4.15.orig/src/dumpstats.c
+++ haproxy-1.4.15/src/dumpstats.c
@@ -441,7 +441,7 @@ int stats_sock_parse_request(struct stre
 			}
 
 			/* return server's effective weight at the moment */
-			snprintf(trash, sizeof(trash), "%d (initial %d)\n", sv->uweight, sv->iweight);
+			snprintf(trash, trashlen, "%d (initial %d)\n", sv->uweight, sv->iweight);
 			buffer_feed(si->ib, trash);
 			return 1;
 		}
@@ -721,7 +721,7 @@ void stats_io_handler(struct stream_inte
 			if (buffer_almost_full(si->ib))
 				break;
 
-			reql = buffer_si_peekline(si->ob, trash, sizeof(trash));
+			reql = buffer_si_peekline(si->ob, trash, trashlen);
 			if (reql <= 0) { /* closed or EOL not found */
 				if (reql == 0)
 					break;
@@ -890,7 +890,7 @@ int stats_dump_raw_to_buffer(struct sess
 	struct chunk msg;
 	unsigned int up;
 
-	chunk_init(&msg, trash, sizeof(trash));
+	chunk_init(&msg, trash, trashlen);
 
 	switch (s->data_state) {
 	case DATA_ST_INIT:
@@ -1002,7 +1002,7 @@ int stats_http_redir(struct session *s,
 {
 	struct chunk msg;
 
-	chunk_init(&msg, trash, sizeof(trash));
+	chunk_init(&msg, trash, trashlen);
 
 	switch (s->data_state) {
 	case DATA_ST_INIT:
@@ -1103,7 +1103,7 @@ int stats_dump_http(struct session *s, s
 	struct chunk msg;
 	unsigned int up;
 
-	chunk_init(&msg, trash, sizeof(trash));
+	chunk_init(&msg, trash, trashlen);
 
 	switch (s->data_state) {
 	case DATA_ST_INIT:
@@ -1451,7 +1451,7 @@ int stats_dump_proxy(struct session *s,
 	struct listener *l;
 	struct chunk msg;
 
-	chunk_init(&msg, trash, sizeof(trash));
+	chunk_init(&msg, trash, trashlen);
 
 	switch (s->data_ctx.stats.px_st) {
 	case DATA_ST_PX_INIT:
@@ -2502,7 +2502,7 @@ int stats_dump_full_sess_to_buffer(struc
 	extern const char *monthname[12];
 	char pn[INET6_ADDRSTRLEN];
 
-	chunk_init(&msg, trash, sizeof(trash));
+	chunk_init(&msg, trash, trashlen);
 	sess = s->data_ctx.sess.target;
 
 	if (s->data_ctx.sess.section > 0 && s->data_ctx.sess.uid != sess->uniq_id) {
@@ -2713,7 +2713,7 @@ int stats_dump_sess_to_buffer(struct ses
 		return 1;
 	}
 
-	chunk_init(&msg, trash, sizeof(trash));
+	chunk_init(&msg, trash, trashlen);
 
 	switch (s->data_state) {
 	case DATA_ST_INIT:
@@ -2983,7 +2983,7 @@ int stats_dump_errors_to_buffer(struct s
 	if (unlikely(rep->flags & (BF_WRITE_ERROR|BF_SHUTW)))
 		return 1;
 
-	chunk_init(&msg, trash, sizeof(trash));
+	chunk_init(&msg, trash, trashlen);
 
 	if (!s->data_ctx.errors.px) {
 		/* the function had not been called yet, let's prepare the
--- haproxy-1.4.15.orig/src/cfgparse.c
+++ haproxy-1.4.15/src/cfgparse.c
@@ -511,6 +511,8 @@ int cfg_parse_global(const char *file, i
 		global.tune.bufsize = atol(args[1]);
 		if (global.tune.maxrewrite >= global.tune.bufsize / 2)
 			global.tune.maxrewrite = global.tune.bufsize / 2;
+		trashlen = global.tune.bufsize;
+		trash = realloc(trash, trashlen);
 	}
 	else if (!strcmp(args[0], "tune.maxrewrite")) {
 		if (*(args[1]) == 0) {
@@ -904,9 +906,9 @@ int cfg_parse_global(const char *file, i
 					continue;
 				if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
 					/* prepare error message just in case */
-					snprintf(trash, sizeof(trash),
+					snprintf(trash, trashlen,
 						 "error near '%s' in '%s' section", args[0], "global");
-					rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, trash, sizeof(trash));
+					rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, trash, trashlen);
 					if (rc < 0) {
 						Alert("parsing [%s:%d] : %s\n", file, linenum, trash);
 						err_code |= ERR_ALERT | ERR_FATAL;
@@ -3302,7 +3304,7 @@ stats_error_parsing:
 			err_code |= ERR_WARN;
 
 		memcpy(trash, "error near 'balance'", 21);
-		if (backend_parse_balance((const char **)args + 1, trash, sizeof(trash), curproxy) < 0) {
+		if (backend_parse_balance((const char **)args + 1, trash, trashlen, curproxy) < 0) {
 			Alert("parsing [%s:%d] : %s\n", file, linenum, trash);
 			err_code |= ERR_ALERT | ERR_FATAL;
 			goto out;
@@ -4529,9 +4531,9 @@ stats_error_parsing:
 					continue;
 				if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
 					/* prepare error message just in case */
-					snprintf(trash, sizeof(trash),
+					snprintf(trash, trashlen,
 						 "error near '%s' in %s section", args[0], cursection);
-					rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, trash, sizeof(trash));
+					rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, trash, trashlen);
 					if (rc < 0) {
 						Alert("parsing [%s:%d] : %s\n", file, linenum, trash);
 						err_code |= ERR_ALERT | ERR_FATAL;
--- haproxy-1.4.15.orig/src/haproxy.c
+++ haproxy-1.4.15/src/haproxy.c
@@ -135,7 +135,8 @@ static int *oldpids = NULL;
 static int oldpids_sig; /* use USR1 or TERM */
 
 /* this is used to drain data, and as a temporary buffer for sprintf()... */
-char trash[BUFSIZE];
+char *trash = NULL;
+int trashlen = BUFSIZE;
 
 /* this buffer is always the same size as standard buffers and is used for
  * swapping data inside a buffer.
@@ -284,7 +285,7 @@ void sig_dump_state(int sig)
 
 		send_log(p, LOG_NOTICE, "SIGHUP received, dumping servers states for proxy %s.\n", p->id);
 		while (s) {
-			snprintf(trash, sizeof(trash),
+			snprintf(trash, trashlen,
 				 "SIGHUP: Server %s/%s is %s. Conn: %d act, %d pend, %lld tot.",
 				 p->id, s->id,
 				 (s->state & SRV_RUNNING) ? "UP" : "DOWN",
@@ -296,18 +297,18 @@ void sig_dump_state(int sig)
 
 		/* FIXME: those info are a bit outdated. We should be able to distinguish between FE and BE. */
 		if (!p->srv) {
-			snprintf(trash, sizeof(trash),
+			snprintf(trash, trashlen,
 				 "SIGHUP: Proxy %s has no servers. Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %lld+%lld.",
 				 p->id,
 				 p->feconn, p->beconn, p->totpend, p->nbpend, p->counters.cum_feconn, p->counters.cum_beconn);
 		} else if (p->srv_act == 0) {
-			snprintf(trash, sizeof(trash),
+			snprintf(trash, trashlen,
 				 "SIGHUP: Proxy %s %s ! Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %lld+%lld.",
 				 p->id,
 				 (p->srv_bck) ? "is running on backup servers" : "has no server available",
 				 p->feconn, p->beconn, p->totpend, p->nbpend, p->counters.cum_feconn, p->counters.cum_beconn);
 		} else {
-			snprintf(trash, sizeof(trash),
+			snprintf(trash, trashlen,
 				 "SIGHUP: Proxy %s has %d active servers and %d backup servers available."
 				 " Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %lld+%lld.",
 				 p->id, p->srv_act, p->srv_bck,
@@ -404,6 +405,7 @@ void init(int argc, char **argv)
 	 */
     
 	totalconn = actconn = maxfd = listeners = stopping = 0;
+	trash = malloc(trashlen);
     
 
 #ifdef HAPROXY_MEMMAX
--- haproxy-1.4.15.orig/src/acl.c
+++ haproxy-1.4.15/src/acl.c
@@ -776,8 +776,7 @@ static int acl_read_patterns_from_file(
 	opaque = 0;
 	pattern = NULL;
 	args[1] = "";
-	while (fgets(trash, sizeof(trash), file) != NULL) {
-
+	while (fgets(trash, trashlen, file) != NULL) {
 		c = trash;
 
 		/* ignore lines beginning with a dash */
