BUG/MAJOR: log: possible segfault with logformat
Possible zero-pointer deference in sess_log().
Checks of return values in sess_log() fix the issue.
Fix bad computation in logformat_write_string().
This issue is 1.5-specific and was introduced just before 1.5-dev8.
No backport is needed.
diff --git a/src/log.c b/src/log.c
index 0b3be32..3b65c28 100644
--- a/src/log.c
+++ b/src/log.c
@@ -474,7 +474,7 @@
*/
char *logformat_write_string(char *dst, char *src, size_t size, struct logformat_node *node)
{
- char *orig = dst;
+ int n;
if (src == NULL || *src == '\0') {
if (node->options & LOG_OPT_QUOTE) {
@@ -505,8 +505,9 @@
dst = NULL;
return NULL;
}
- dst += strlcpy2(dst, src, size);
- size -= dst - orig + 1;
+ n = strlcpy2(dst, src, size);
+ size -= n;
+ dst += n;
if (size > 1) {
*(dst++) = '"';
*dst = '\0';
@@ -693,7 +694,7 @@
Set-cookie Updated, unknown, unknown */
#define LOGCHAR(x) do { \
- if (MAX_SYSLOG_LEN - (tmplog - logline) > 1) { \
+ if (tmplog < logline + MAX_SYSLOG_LEN - 1) { \
*(tmplog++) = (x); \
} else { \
goto out; \
@@ -785,7 +786,7 @@
case LOG_TEXT: // text
src = tmp->arg;
tmplog += strlcpy2(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline));
- if (!tmplog)
+ if (tmplog > logline + MAX_SYSLOG_LEN - 2)
goto out;
last_isspace = 0;
break;
@@ -793,7 +794,6 @@
case LOG_CLIENTIP: // %Ci
src = (s->req->prod->addr.from.ss_family == AF_UNIX) ? "unix" : pn;
tmplog = logformat_write_string(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline), tmp);
-
if (!tmplog)
goto out;
last_isspace = 0;
@@ -810,7 +810,6 @@
case LOG_SOURCEIP: // Bi
src = (s->req->cons->addr.from.ss_family == AF_UNIX) ? "unix" : sn;
tmplog = logformat_write_string(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline), tmp);
-
if (!tmplog)
goto out;
last_isspace = 0;
@@ -847,8 +846,9 @@
}
tmplog = utoa_pad((unsigned int)s->logs.accept_date.tv_usec/1000,
tmplog, 4);
+ if (!tmplog)
+ goto out;
last_isspace = 0;
-
break;
case LOG_FRONTEND: // %f
@@ -856,7 +856,7 @@
tmplog = logformat_write_string(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline), tmp);
if (!tmplog)
goto out;
- last_isspace = 0 ;
+ last_isspace = 0;
break;
case LOG_BACKEND: // %b
@@ -864,7 +864,7 @@
tmplog = logformat_write_string(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline), tmp);
if (!tmplog)
goto out;
- last_isspace = 0 ;
+ last_isspace = 0;
break;
case LOG_SERVER: // %s
@@ -931,12 +931,16 @@
case LOG_CCLIENT: // %cc
src = txn->cli_cookie;
tmplog = logformat_write_string(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline), tmp);
+ if (!tmplog)
+ goto out;
last_isspace = 0;
break;
case LOG_CSERVER: // %cs
src = txn->srv_cookie;
tmplog = logformat_write_string(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline), tmp);
+ if (!tmplog)
+ goto out;
last_isspace = 0;
break;
@@ -988,6 +992,8 @@
if (s->flags & SN_REDISP)
*(tmplog++) = '+';
tmplog = ltoa_o((s->req->cons->conn_retries>0)?(be->conn_retries - s->req->cons->conn_retries):be->conn_retries, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
+ if (!tmplog)
+ goto out;
last_isspace = 0;
break;
@@ -1014,11 +1020,16 @@
for (hdr = 0; hdr < fe->nb_req_cap; hdr++) {
if (hdr)
LOGCHAR('|');
- if (txn->req.cap[hdr] != NULL)
+ if (txn->req.cap[hdr] != NULL) {
tmplog = encode_string(tmplog, logline + MAX_SYSLOG_LEN,
'#', hdr_encode_map, txn->req.cap[hdr]);
+ if (*tmplog != '\0')
+ goto out;
+ }
}
LOGCHAR('}');
+ if (tmp->options & LOG_OPT_QUOTE)
+ LOGCHAR('"');
last_isspace = 0;
}
*tmplog = '\0';
@@ -1035,6 +1046,9 @@
if (txn->req.cap[hdr] != NULL) {
tmplog = encode_string(tmplog, logline + MAX_SYSLOG_LEN,
'#', hdr_encode_map, txn->req.cap[hdr]);
+ if (*tmplog != '\0')
+ goto out;
+
} else if (!(tmp->options & LOG_OPT_QUOTE))
LOGCHAR('-');
if (tmp->options & LOG_OPT_QUOTE)
@@ -1055,9 +1069,12 @@
for (hdr = 0; hdr < fe->nb_rsp_cap; hdr++) {
if (hdr)
LOGCHAR('|');
- if (txn->rsp.cap[hdr] != NULL)
+ if (txn->rsp.cap[hdr] != NULL) {
tmplog = encode_string(tmplog, logline + MAX_SYSLOG_LEN,
'#', hdr_encode_map, txn->rsp.cap[hdr]);
+ if (*tmplog != '\0')
+ goto out;
+ }
}
LOGCHAR('}');
last_isspace = 0;
@@ -1078,6 +1095,8 @@
if (txn->rsp.cap[hdr] != NULL) {
tmplog = encode_string(tmplog, logline + MAX_SYSLOG_LEN,
'#', hdr_encode_map, txn->rsp.cap[hdr]);
+ if (*tmplog != '\0')
+ goto out;
} else if (!(tmp->options & LOG_OPT_QUOTE))
LOGCHAR('-');
if (tmp->options & LOG_OPT_QUOTE)
@@ -1095,6 +1114,8 @@
uri = txn->uri ? txn->uri : "<BADREQ>";
tmplog = encode_string(tmplog, logline + MAX_SYSLOG_LEN,
'#', url_encode_map, uri);
+ if (*tmplog != '\0')
+ goto out;
if (tmp->options & LOG_OPT_QUOTE)
LOGCHAR('"');
*tmplog = '\0';