X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/d7978c0f8af20ff4c3f770589b1bb81568aecff3..0bfae1bfbd555b87f1a032ee3d78c19caccdbe42:/src/src/log.c diff --git a/src/src/log.c b/src/src/log.c index 4905b6d54..88cc12cd4 100644 --- a/src/src/log.c +++ b/src/src/log.c @@ -3,6 +3,7 @@ *************************************************/ /* Copyright (c) University of Cambridge 1995 - 2018 */ +/* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions for writing log files. The code for maintaining datestamped @@ -104,7 +105,8 @@ static const uschar * exim_errstrings[] = { US"Negotiation failed for proxy configured host", US"Authenticator 'other' failure", US"target not supporting SMTPUTF8", - US"", + US"host is local", + US"tainted filename", US"Not time for routing", US"Not time for local delivery", @@ -112,6 +114,7 @@ static const uschar * exim_errstrings[] = { US"Local-only delivery", US"Domain in queue_domains", US"Transport concurrency limit", + US"Event requests alternate response", }; @@ -241,7 +244,7 @@ if (s1) } if (f.receive_call_bombout) receive_bomb_out(NULL, s2); /* does not return */ if (smtp_input) smtp_closedown(s2); -exim_exit(EXIT_FAILURE, NULL); +exim_exit(EXIT_FAILURE); } @@ -312,7 +315,7 @@ Returns: a file descriptor, or < 0 on failure (errno set) int log_create_as_exim(uschar *name) { -pid_t pid = fork(); +pid_t pid = exim_fork(US"logfile-create"); int status = 1; int fd = -1; @@ -509,7 +512,7 @@ non-setuid binary with log_arguments set, called in certain ways.) Rather than just bombing out, force the log to stderr and carry on if stderr is available. */ -if (euid != root_uid && euid != exim_uid && log_stderr != NULL) +if (euid != root_uid && euid != exim_uid && log_stderr) { *fd = fileno(log_stderr); return; @@ -518,7 +521,9 @@ if (euid != root_uid && euid != exim_uid && log_stderr != NULL) /* Otherwise this is a disaster. This call is deliberately ONLY to the panic log. If possible, save a copy of the original line that was being logged. If we are recursing (can't open the panic log either), the pointer will already be -set. */ +set. Also, when we had to use a subprocess for the create we didn't retrieve +errno from it, so get the error from the open attempt above (which is often +meaningful enough, so leave it). */ if (!panic_save_buffer) if ((panic_save_buffer = US malloc(LOG_BUFFER_SIZE))) @@ -764,7 +769,7 @@ if (!log_buffer) if (!(log_buffer = US malloc(LOG_BUFFER_SIZE))) { fprintf(stderr, "exim: failed to get store for log buffer\n"); - exim_exit(EXIT_FAILURE, NULL); + exim_exit(EXIT_FAILURE); } /* If we haven't already done so, inspect the setting of log_file_path to @@ -864,9 +869,13 @@ DEBUG(D_any|D_v) if (flags & LOG_CONFIG) g = log_config_info(g, flags); + /* We want to be able to log tainted info, but log_buffer is directly + malloc'd. So use deliberately taint-nonchecking routines to build into + it, trusting that we will never expand the results. */ + va_start(ap, format); i = g->ptr; - if (!string_vformat(g, FALSE, format, ap)) + if (!string_vformat(g, SVFMT_TAINT_NOCHK, format, ap)) { g->ptr = i; g = string_cat(g, US"**** log string overflowed log buffer ****"); @@ -920,7 +929,12 @@ if (flags & LOG_CONFIG) va_start(ap, format); { int i = g->ptr; - if (!string_vformat(g, FALSE, format, ap)) + + /* We want to be able to log tainted info, but log_buffer is directly + malloc'd. So use deliberately taint-nonchecking routines to build into + it, trusting that we will never expand the results. */ + + if (!string_vformat(g, SVFMT_TAINT_NOCHK, format, ap)) { g->ptr = i; g = string_cat(g, US"**** log string overflowed log buffer ****\n"); @@ -933,7 +947,7 @@ this way because it kind of fits with LOG_RECIPIENTS. */ if ( flags & LOG_SENDER && g->ptr < LOG_BUFFER_SIZE - 10 - Ustrlen(raw_sender)) - g = string_fmt_append(g, " from <%s>", raw_sender); + g = string_fmt_append_f(g, SVFMT_TAINT_NOCHK, " from <%s>", raw_sender); /* Add list of recipients to the message if required; the raw list, before rewriting, was saved in raw_recipients. There may be none, if an ACL @@ -944,12 +958,12 @@ if ( flags & LOG_RECIPIENTS && raw_recipients_count > 0) { int i; - g = string_fmt_append(g, " for"); + g = string_fmt_append_f(g, SVFMT_TAINT_NOCHK, " for", NULL); for (i = 0; i < raw_recipients_count; i++) { uschar * s = raw_recipients[i]; if (LOG_BUFFER_SIZE - g->ptr < Ustrlen(s) + 3) break; - g = string_fmt_append(g, " %s", s); + g = string_fmt_append_f(g, SVFMT_TAINT_NOCHK, " %s", s); } } @@ -971,7 +985,7 @@ if (!f.really_exim || f.log_testing_mode) else fprintf(log_stderr, "%s", CS log_buffer); - if ((flags & LOG_PANIC_DIE) == LOG_PANIC_DIE) exim_exit(EXIT_FAILURE, US""); + if ((flags & LOG_PANIC_DIE) == LOG_PANIC_DIE) exim_exit(EXIT_FAILURE); return; } @@ -1045,39 +1059,34 @@ if (flags & LOG_REJECT) { if (header_list && LOGGING(rejected_header)) { - uschar * p = g->s + g->ptr; + gstring * g2; int i; if (recipients_count > 0) { /* List the sender */ - string_format(p, LOG_BUFFER_SIZE - g->ptr, - "Envelope-from: <%s>\n", sender_address); - while (*p) p++; - g->ptr = p - g->s; + g2 = string_fmt_append_f(g, SVFMT_TAINT_NOCHK, + "Envelope-from: <%s>\n", sender_address); + if (g2) g = g2; /* List up to 5 recipients */ - string_format(p, LOG_BUFFER_SIZE - g->ptr, - "Envelope-to: <%s>\n", recipients_list[0].address); - while (*p) p++; - g->ptr = p - g->s; + g2 = string_fmt_append_f(g, SVFMT_TAINT_NOCHK, + "Envelope-to: <%s>\n", recipients_list[0].address); + if (g2) g = g2; for (i = 1; i < recipients_count && i < 5; i++) { - string_format(p, LOG_BUFFER_SIZE - g->ptr, " <%s>\n", - recipients_list[i].address); - while (*p) p++; - g->ptr = p - g->s; + g2 = string_fmt_append_f(g, SVFMT_TAINT_NOCHK, + " <%s>\n", recipients_list[i].address); + if (g2) g = g2; } if (i < recipients_count) { - string_format(p, LOG_BUFFER_SIZE - g->ptr, - " ...\n"); - while (*p) p++; - g->ptr = p - g->s; + g2 = string_fmt_append_f(g, SVFMT_TAINT_NOCHK, " ...\n", NULL); + if (g2) g = g2; } } @@ -1085,11 +1094,11 @@ if (flags & LOG_REJECT) for (header_line * h = header_list; h; h = h->next) if (h->text) { - BOOL fitted = string_format(p, LOG_BUFFER_SIZE - g->ptr, - "%c %s", h->type, h->text); - while (*p) p++; - g->ptr = p - g->s; - if (!fitted) /* Buffer is full; truncate */ + g2 = string_fmt_append_f(g, SVFMT_TAINT_NOCHK, + "%c %s", h->type, h->text); + if (g2) + g = g2; + else /* Buffer is full; truncate */ { g->ptr -= 100; /* For message and separator */ if (g->s[g->ptr-1] == '\n') g->ptr--; @@ -1180,10 +1189,7 @@ if (flags & LOG_PANIC) panic_recurseflag = FALSE; if (panic_save_buffer) - { - int i = write(paniclogfd, panic_save_buffer, Ustrlen(panic_save_buffer)); - i = i; /* compiler quietening */ - } + (void) write(paniclogfd, panic_save_buffer, Ustrlen(panic_save_buffer)); written_len = write_to_fd_buf(paniclogfd, g->s, g->ptr); if (written_len != g->ptr) @@ -1291,14 +1297,14 @@ decode_bits(unsigned int *selector, size_t selsize, int *notall, uschar *string, bit_table *options, int count, uschar *which, int flags) { uschar *errmsg; -if (string == NULL) return; +if (!string) return; if (*string == '=') { char *end; /* Not uschar */ memset(selector, 0, sizeof(*selector)*selsize); *selector = strtoul(CS string+1, &end, 0); - if (*end == 0) return; + if (!*end) return; errmsg = string_sprintf("malformed numeric %s_selector setting: %s", which, string); goto ERROR_RETURN; @@ -1313,8 +1319,8 @@ else for(;;) int len; bit_table *start, *end; - while (isspace(*string)) string++; - if (*string == 0) return; + Uskip_whitespace(&string); + if (!*string) return; if (*string != '+' && *string != '-') { @@ -1336,7 +1342,6 @@ else for(;;) bit_table *middle = start + (end - start)/2; int c = Ustrncmp(s, middle->name, len); if (c == 0) - { if (middle->name[len] != 0) c = -1; else { unsigned int bit = middle->bit; @@ -1358,7 +1363,6 @@ else for(;;) break; /* Out of loop to match selector name */ } - } if (c < 0) end = middle; else start = middle + 1; } /* Loop to match selector name */