X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fspool_in.c;h=6ed5664118f6206d19f5da17c63ca6581ae5acc2;hb=b6040544759110aa97f93e9ba0dd8232cd5e5188;hp=1b7cee6b08ec46a1a6420ee2376b7e21ac04dc80;hpb=4dc2379ac1ab6c21f265abed06dd9aaa214976af;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/spool_in.c b/src/src/spool_in.c index 1b7cee6b0..6ed566411 100644 --- a/src/src/spool_in.c +++ b/src/src/spool_in.c @@ -25,6 +25,8 @@ fact it won't be written to. Just in case there's a major disaster (e.g. overwriting some other file descriptor with the value of this one), open it with append. +As called by deliver_message() (at least) we are operating as root. + Argument: the id of the message Returns: fd if file successfully opened and locked, else -1 @@ -55,7 +57,11 @@ for (i = 0; i < 2; i++) fname = spool_fname(US"input", message_subdir, id, US"-D"); DEBUG(D_deliver) debug_printf("Trying spool file %s\n", fname); - if ((fd = Uopen(fname, O_RDWR | O_APPEND, 0)) >= 0) + if ((fd = Uopen(fname, +#ifdef O_CLOEXEC + O_CLOEXEC | +#endif + O_RDWR | O_APPEND, 0)) >= 0) break; save_errno = errno; if (errno == ENOENT) @@ -81,8 +87,9 @@ an open file descriptor (at least, I think that's the Cygwin story). On real Unix systems it doesn't make any difference as long as Exim is consistent in what it locks. */ -(void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | - FD_CLOEXEC); +#ifndef O_CLOEXEC +(void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); +#endif lock_data.l_type = F_WRLCK; lock_data.l_whence = SEEK_SET; @@ -215,6 +222,8 @@ have been the cause of that incident, but in any case, this code must be robust against such an event, and if such a file is encountered, it must be treated as malformed. +As called from deliver_message() (at least) we are running as root. + Arguments: name name of the header file, including the -H read_headers TRUE if in-store header structures are to be built @@ -223,7 +232,7 @@ Arguments: Returns: spool_read_OK success spool_read_notopen open failed spool_read_enverror error in the envelope portion - spool_read_hdrdrror error in the header portion + spool_read_hdrerror error in the header portion */ int @@ -481,6 +490,7 @@ for (;;) 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) @@ -489,6 +499,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); + /* 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'; } @@ -660,10 +672,12 @@ DEBUG(D_deliver) #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 (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); @@ -672,6 +686,10 @@ DEBUG(D_deliver) debug_printf("recipients_count=%d\n", rcount); 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;