projects
/
exim.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Cheap method to follow redis cluster MOVED replies
[exim.git]
/
src
/
src
/
spool_in.c
diff --git
a/src/src/spool_in.c
b/src/src/spool_in.c
index 3592fa7b64bed9e4cb6ae695d792cea87a1e4887..c8ddffe4135b068d1d8a2c9322ad6d3de4c87148 100644
(file)
--- a/
src/src/spool_in.c
+++ b/
src/src/spool_in.c
@@
-2,7
+2,7
@@
* Exim - an Internet mail transport agent *
*************************************************/
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 201
6
*/
+/* Copyright (c) University of Cambridge 1995 - 201
8
*/
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for reading spool files. When compiling for a utility (eximon),
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for reading spool files. When compiling for a utility (eximon),
@@
-232,7
+232,7
@@
Arguments:
Returns: spool_read_OK success
spool_read_notopen open failed
spool_read_enverror error in the envelope portion
Returns: spool_read_OK success
spool_read_notopen open failed
spool_read_enverror error in the envelope portion
- spool_read_hdr
d
rror error in the header portion
+ spool_read_hdr
e
rror error in the header portion
*/
int
*/
int
@@
-284,6
+284,9
@@
sender_ident = NULL;
sender_local = FALSE;
sender_set_untrusted = FALSE;
smtp_active_hostname = primary_hostname;
sender_local = FALSE;
sender_set_untrusted = FALSE;
smtp_active_hostname = primary_hostname;
+#ifndef COMPILE_UTILITY
+spool_file_wireformat = FALSE;
+#endif
tree_nonrecipients = NULL;
#ifdef EXPERIMENTAL_BRIGHTMAIL
tree_nonrecipients = NULL;
#ifdef EXPERIMENTAL_BRIGHTMAIL
@@
-299,7
+302,7
@@
dkim_collect_input = FALSE;
#ifdef SUPPORT_TLS
tls_in.certificate_verified = FALSE;
#ifdef SUPPORT_TLS
tls_in.certificate_verified = FALSE;
-# ifdef
EXPERIMENTAL
_DANE
+# ifdef
SUPPORT
_DANE
tls_in.dane_verified = FALSE;
# endif
tls_in.cipher = NULL;
tls_in.dane_verified = FALSE;
# endif
tls_in.cipher = NULL;
@@
-394,10
+397,11
@@
sender_address[n-3] = 0;
/* time */
if (Ufgets(big_buffer, big_buffer_size, f) == NULL) goto SPOOL_READ_ERROR;
/* time */
if (Ufgets(big_buffer, big_buffer_size, f) == NULL) goto SPOOL_READ_ERROR;
-if (sscanf(CS big_buffer,
"%d %d", &received_time
, &warning_count) != 2)
+if (sscanf(CS big_buffer,
TIME_T_FMT " %d", &received_time.tv_sec
, &warning_count) != 2)
goto SPOOL_FORMAT_ERROR;
goto SPOOL_FORMAT_ERROR;
+received_time.tv_usec = 0;
-message_age = time(NULL) - received_time;
+message_age = time(NULL) - received_time
.tv_sec
;
#ifndef COMPILE_UTILITY
DEBUG(D_deliver) debug_printf("user=%s uid=%ld gid=%ld sender=%s\n",
#ifndef COMPILE_UTILITY
DEBUG(D_deliver) debug_printf("user=%s uid=%ld gid=%ld sender=%s\n",
@@
-455,8
+459,8
@@
for (;;)
tree_node *node;
endptr = Ustrchr(big_buffer + 6, ' ');
if (endptr == NULL) goto SPOOL_FORMAT_ERROR;
tree_node *node;
endptr = Ustrchr(big_buffer + 6, ' ');
if (endptr == NULL) goto SPOOL_FORMAT_ERROR;
- name = string_sprintf("%c%.*s", big_buffer[4],
endptr - big_buffer - 6,
- big_buffer + 6);
+ name = string_sprintf("%c%.*s", big_buffer[4],
+
(int)(endptr - big_buffer - 6),
big_buffer + 6);
if (sscanf(CS endptr, " %d", &count) != 1) goto SPOOL_FORMAT_ERROR;
node = acl_var_create(name);
node->data.ptr = store_get(count + 1);
if (sscanf(CS endptr, " %d", &count) != 1) goto SPOOL_FORMAT_ERROR;
node = acl_var_create(name);
node->data.ptr = store_get(count + 1);
@@
-490,6
+494,7
@@
for (;;)
tree_node * node;
if ( sscanf(CS big_buffer + 5, "%u %u", &index, &count) != 2
|| index >= 20
tree_node * node;
if ( sscanf(CS big_buffer + 5, "%u %u", &index, &count) != 2
|| index >= 20
+ || count > 16384 /* arbitrary limit on variable size */
)
goto SPOOL_FORMAT_ERROR;
if (index < 10)
)
goto SPOOL_FORMAT_ERROR;
if (index < 10)
@@
-498,6
+503,8
@@
for (;;)
(void) string_format(name, sizeof(name), "%c%u", 'm', index - 10);
node = acl_var_create(name);
node->data.ptr = store_get(count + 1);
(void) string_format(name, sizeof(name), "%c%u", 'm', index - 10);
node = acl_var_create(name);
node->data.ptr = store_get(count + 1);
+ /* We sanity-checked the count, so disable the Coverity error */
+ /* coverity[tainted_data] */
if (fread(node->data.ptr, 1, count+1, f) < count) goto SPOOL_READ_ERROR;
(US node->data.ptr)[count] = '\0';
}
if (fread(node->data.ptr, 1, count+1, f) < count) goto SPOOL_READ_ERROR;
(US node->data.ptr)[count] = '\0';
}
@@
-567,7
+574,8
@@
for (;;)
break;
case 'l':
break;
case 'l':
- if (Ustrcmp(p, "ocal") == 0) sender_local = TRUE;
+ if (Ustrcmp(p, "ocal") == 0)
+ sender_local = TRUE;
else if (Ustrcmp(big_buffer, "-localerror") == 0)
local_error_message = TRUE;
else if (Ustrncmp(p, "ocal_scan ", 10) == 0)
else if (Ustrcmp(big_buffer, "-localerror") == 0)
local_error_message = TRUE;
else if (Ustrncmp(p, "ocal_scan ", 10) == 0)
@@
-587,6
+595,12
@@
for (;;)
case 'r':
if (Ustrncmp(p, "eceived_protocol", 16) == 0)
received_protocol = string_copy(big_buffer + 19);
case 'r':
if (Ustrncmp(p, "eceived_protocol", 16) == 0)
received_protocol = string_copy(big_buffer + 19);
+ else if (Ustrncmp(p, "eceived_time_usec", 17) == 0)
+ {
+ unsigned usec;
+ if (sscanf(CS big_buffer + 21, "%u", &usec) == 1)
+ received_time.tv_usec = usec;
+ }
break;
case 's':
break;
case 's':
@@
-600,6
+614,10
@@
for (;;)
else if (Ustrncmp(p, "pam_score_int ", 14) == 0)
spam_score_int = string_copy(big_buffer + 16);
#endif
else if (Ustrncmp(p, "pam_score_int ", 14) == 0)
spam_score_int = string_copy(big_buffer + 16);
#endif
+#ifndef COMPILE_UTILITY
+ else if (Ustrncmp(p, "pool_file_wireformat", 20) == 0)
+ spool_file_wireformat = TRUE;
+#endif
#if defined(SUPPORT_I18N) && !defined(COMPILE_UTILITY)
else if (Ustrncmp(p, "mtputf8", 7) == 0)
message_smtputf8 = TRUE;
#if defined(SUPPORT_I18N) && !defined(COMPILE_UTILITY)
else if (Ustrncmp(p, "mtputf8", 7) == 0)
message_smtputf8 = TRUE;
@@
-669,10
+687,12
@@
DEBUG(D_deliver)
#endif /* COMPILE_UTILITY */
/* After reading the tree, the next line has not yet been read into the
#endif /* COMPILE_UTILITY */
/* After reading the tree, the next line has not yet been read into the
-buffer. It contains the count of recipients which follow on separate lines. */
+buffer. It contains the count of recipients which follow on separate lines.
+Apply an arbitrary sanity check.*/
if (Ufgets(big_buffer, big_buffer_size, f) == NULL) goto SPOOL_READ_ERROR;
if (Ufgets(big_buffer, big_buffer_size, f) == NULL) goto SPOOL_READ_ERROR;
-if (sscanf(CS big_buffer, "%d", &rcount) != 1) goto SPOOL_FORMAT_ERROR;
+if (sscanf(CS big_buffer, "%d", &rcount) != 1 || rcount > 16384)
+ goto SPOOL_FORMAT_ERROR;
#ifndef COMPILE_UTILITY
DEBUG(D_deliver) debug_printf("recipients_count=%d\n", rcount);
#ifndef COMPILE_UTILITY
DEBUG(D_deliver) debug_printf("recipients_count=%d\n", rcount);
@@
-681,6
+701,10
@@
DEBUG(D_deliver) debug_printf("recipients_count=%d\n", rcount);
recipients_list_max = rcount;
recipients_list = store_get(rcount * sizeof(recipient_item));
recipients_list_max = rcount;
recipients_list = store_get(rcount * sizeof(recipient_item));
+/* We sanitised the count and know we have enough memory, so disable
+the Coverity error on recipients_count */
+/* coverity[tainted_data] */
+
for (recipients_count = 0; recipients_count < rcount; recipients_count++)
{
int nn;
for (recipients_count = 0; recipients_count < rcount; recipients_count++)
{
int nn;