From 1ac6b2e7857d7b6645dbd09047c4c2ac3b6cef1d Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Fri, 23 Nov 2012 00:52:43 +0000 Subject: [PATCH] Check syscall return values. Mostly just compiler-quietening rather than intelligent error-handling. This deals with complaints of "attribute warn_unused_result" during an rpm build for SL6 (probably for Fedora also). --- src/src/dbfn.c | 3 +- src/src/deliver.c | 81 ++++++++++++++------- src/src/directory.c | 7 +- src/src/dkim.c | 7 +- src/src/exim.c | 16 +++-- src/src/exim_lock.c | 6 +- src/src/log.c | 5 +- src/src/malware.c | 14 ++-- src/src/queue.c | 5 +- src/src/rda.c | 120 ++++++++++++++++++++------------ src/src/receive.c | 7 +- src/src/smtp_in.c | 4 +- src/src/spool_in.c | 4 +- src/src/spool_mbox.c | 6 +- src/src/spool_out.c | 10 +-- src/src/transport.c | 17 +++-- src/src/transports/appendfile.c | 49 ++++++++++--- src/src/transports/autoreply.c | 16 +++-- src/src/transports/pipe.c | 11 ++- src/src/transports/tf_maildir.c | 2 +- 20 files changed, 262 insertions(+), 128 deletions(-) diff --git a/src/src/dbfn.c b/src/src/dbfn.c index c74ac9c50..4a1c20fe6 100644 --- a/src/src/dbfn.c +++ b/src/src/dbfn.c @@ -208,7 +208,8 @@ if (created && geteuid() == root_uid) if (Ustat(buffer, &statbuf) >= 0 && statbuf.st_uid != exim_uid) { DEBUG(D_hints_lookup) debug_printf("ensuring %s is owned by exim\n", buffer); - (void)Uchown(buffer, exim_uid, exim_gid); + if (Uchown(buffer, exim_uid, exim_gid)) + DEBUG(D_hints_lookup) debug_printf("failed setting %s to owned by exim\n", buffer); } } } diff --git a/src/src/deliver.c b/src/src/deliver.c index eef91036a..34f75fe13 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -1904,33 +1904,40 @@ if ((pid = fork()) == 0) int i; int local_part_length = Ustrlen(addr2->local_part); uschar *s; + int ret; - (void)write(pfd[pipe_write], (void *)&(addr2->transport_return), sizeof(int)); - (void)write(pfd[pipe_write], (void *)&transport_count, sizeof(transport_count)); - (void)write(pfd[pipe_write], (void *)&(addr2->flags), sizeof(addr2->flags)); - (void)write(pfd[pipe_write], (void *)&(addr2->basic_errno), sizeof(int)); - (void)write(pfd[pipe_write], (void *)&(addr2->more_errno), sizeof(int)); - (void)write(pfd[pipe_write], (void *)&(addr2->special_action), sizeof(int)); - (void)write(pfd[pipe_write], (void *)&(addr2->transport), - sizeof(transport_instance *)); + if( (ret = write(pfd[pipe_write], (void *)&(addr2->transport_return), sizeof(int))) != sizeof(int) + || (ret = write(pfd[pipe_write], (void *)&transport_count, sizeof(transport_count))) != sizeof(transport_count) + || (ret = write(pfd[pipe_write], (void *)&(addr2->flags), sizeof(addr2->flags))) != sizeof(addr2->flags) + || (ret = write(pfd[pipe_write], (void *)&(addr2->basic_errno), sizeof(int))) != sizeof(int) + || (ret = write(pfd[pipe_write], (void *)&(addr2->more_errno), sizeof(int))) != sizeof(int) + || (ret = write(pfd[pipe_write], (void *)&(addr2->special_action), sizeof(int))) != sizeof(int) + || (ret = write(pfd[pipe_write], (void *)&(addr2->transport), + sizeof(transport_instance *))) != sizeof(transport_instance *) /* For a file delivery, pass back the local part, in case the original was only part of the final delivery path. This gives more complete logging. */ - if (testflag(addr2, af_file)) - { - (void)write(pfd[pipe_write], (void *)&local_part_length, sizeof(int)); - (void)write(pfd[pipe_write], addr2->local_part, local_part_length); - } + || (testflag(addr2, af_file) + && ( (ret = write(pfd[pipe_write], (void *)&local_part_length, sizeof(int))) != sizeof(int) + || (ret = write(pfd[pipe_write], addr2->local_part, local_part_length)) != local_part_length + ) + ) + ) + log_write(0, LOG_MAIN|LOG_PANIC, "Failed writing transport results to pipe: %s\n", + ret == -1 ? strerror(errno) : "short write"); /* Now any messages */ for (i = 0, s = addr2->message; i < 2; i++, s = addr2->user_message) { int message_length = (s == NULL)? 0 : Ustrlen(s) + 1; - (void)write(pfd[pipe_write], (void *)&message_length, sizeof(int)); - if (message_length > 0) (void)write(pfd[pipe_write], s, message_length); + if( (ret = write(pfd[pipe_write], (void *)&message_length, sizeof(int))) != sizeof(int) + || (message_length > 0 && (ret = write(pfd[pipe_write], s, message_length)) != message_length) + ) + log_write(0, LOG_MAIN|LOG_PANIC, "Failed writing transport results to pipe: %s\n", + ret == -1 ? strerror(errno) : "short write"); } } @@ -3449,6 +3456,15 @@ while (parcount > max) +static void +rmt_dlv_checked_write(int fd, void * buf, int size) +{ +int ret = write(fd, buf, size); +if(ret != size) + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Failed writing transport result to pipe: %s\n", + ret == -1 ? strerror(errno) : "short write"); +} + /************************************************* * Do remote deliveries * *************************************************/ @@ -3968,7 +3984,7 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++) { if (h->address == NULL || h->status < hstatus_unusable) continue; sprintf(CS big_buffer, "H%c%c%s", h->status, h->why, h->address); - (void)write(fd, big_buffer, Ustrlen(big_buffer+3) + 4); + rmt_dlv_checked_write(fd, big_buffer, Ustrlen(big_buffer+3) + 4); } /* The number of bytes written. This is the same for each address. Even @@ -3978,7 +3994,7 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++) big_buffer[0] = 'S'; memcpy(big_buffer+1, &transport_count, sizeof(transport_count)); - (void)write(fd, big_buffer, sizeof(transport_count) + 1); + rmt_dlv_checked_write(fd, big_buffer, sizeof(transport_count) + 1); /* Information about what happened to each address. Four item types are used: an optional 'X' item first, for TLS information, then an optional "C" @@ -4007,7 +4023,7 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++) sprintf(CS ptr, "%.512s", addr->peerdn); while(*ptr++); } - (void)write(fd, big_buffer, ptr - big_buffer); + rmt_dlv_checked_write(fd, big_buffer, ptr - big_buffer); } #endif @@ -4016,21 +4032,21 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++) ptr = big_buffer; sprintf(CS big_buffer, "C1%.64s", client_authenticator); while(*ptr++); - (void)write(fd, big_buffer, ptr - big_buffer); + rmt_dlv_checked_write(fd, big_buffer, ptr - big_buffer); } if (client_authenticated_id) { ptr = big_buffer; sprintf(CS big_buffer, "C2%.64s", client_authenticated_id); while(*ptr++); - (void)write(fd, big_buffer, ptr - big_buffer); + rmt_dlv_checked_write(fd, big_buffer, ptr - big_buffer); } if (client_authenticated_sender) { ptr = big_buffer; sprintf(CS big_buffer, "C3%.64s", client_authenticated_sender); while(*ptr++); - (void)write(fd, big_buffer, ptr - big_buffer); + rmt_dlv_checked_write(fd, big_buffer, ptr - big_buffer); } /* Retry information: for most success cases this will be null. */ @@ -4049,7 +4065,7 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++) sprintf(CS ptr, "%.512s", r->message); while(*ptr++); } - (void)write(fd, big_buffer, ptr - big_buffer); + rmt_dlv_checked_write(fd, big_buffer, ptr - big_buffer); } /* The rest of the information goes in an 'A' item. */ @@ -4085,7 +4101,7 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++) memcpy(ptr, &(addr->host_used->port), sizeof(addr->host_used->port)); ptr += sizeof(addr->host_used->port); } - (void)write(fd, big_buffer, ptr - big_buffer); + rmt_dlv_checked_write(fd, big_buffer, ptr - big_buffer); } /* Add termination flag, close the pipe, and that's it. The character @@ -4095,7 +4111,7 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++) big_buffer[0] = 'Z'; big_buffer[1] = (continue_transport == NULL)? '0' : '1'; - (void)write(fd, big_buffer, 2); + rmt_dlv_checked_write(fd, big_buffer, 2); (void)close(fd); exit(EXIT_SUCCESS); } @@ -6022,12 +6038,23 @@ if (addr_local != NULL || addr_remote != NULL) that the mode is correct - the group setting doesn't always seem to get set automatically. */ - (void)fcntl(journal_fd, F_SETFD, fcntl(journal_fd, F_GETFD) | FD_CLOEXEC); - (void)fchown(journal_fd, exim_uid, exim_gid); - (void)fchmod(journal_fd, SPOOL_MODE); + if( fcntl(journal_fd, F_SETFD, fcntl(journal_fd, F_GETFD) | FD_CLOEXEC) + || fchown(journal_fd, exim_uid, exim_gid) + || fchmod(journal_fd, SPOOL_MODE) + ) + { + int ret = Uunlink(spoolname); + log_write(0, LOG_MAIN|LOG_PANIC, "Couldn't set perms on journal file %s: %s", + spoolname, strerror(errno)); + if(ret && errno != ENOENT) + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to unlink %s: %s", + spoolname, strerror(errno)); + return DELIVER_NOT_ATTEMPTED; + } } + /* Now we can get down to the business of actually doing deliveries. Local deliveries are done first, then remote ones. If ever the problems of how to handle fallback transports are figured out, this section can be put into a loop diff --git a/src/src/directory.c b/src/src/directory.c index c6d46aa5d..5c55a4524 100644 --- a/src/src/directory.c +++ b/src/src/directory.c @@ -74,7 +74,12 @@ while (c != 0 && *p != 0) /* Set the ownership if necessary. */ - if (use_chown) (void)Uchown(buffer, exim_uid, exim_gid); + if (use_chown && Uchown(buffer, exim_uid, exim_gid)) + { + if (!panic) return FALSE; + log_write(0, LOG_MAIN|LOG_PANIC_DIE, + "Failed to set owner on directory \"%s\": %s\n", buffer, strerror(errno)); + } /* It appears that any mode bits greater than 0777 are ignored by mkdir(), at least on some operating systems. Therefore, if the mode diff --git a/src/src/dkim.c b/src/src/dkim.c index 05b5fec56..cb7fc7065 100644 --- a/src/src/dkim.c +++ b/src/src/dkim.c @@ -504,7 +504,12 @@ uschar *dkim_exim_sign(int dkim_fd, rc = NULL; goto CLEANUP; } - (void)read(privkey_fd,big_buffer,(big_buffer_size-2)); + if (read(privkey_fd,big_buffer,(big_buffer_size-2)) < 0) { + log_write(0, LOG_MAIN|LOG_PANIC, "unable to read private key file: %s", + dkim_private_key_expanded); + rc = NULL; + goto CLEANUP; + } (void)close(privkey_fd); dkim_private_key_expanded = big_buffer; } diff --git a/src/src/exim.c b/src/src/exim.c index a59cfea9a..6be3c514b 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -222,7 +222,7 @@ to disrupt whatever is going on outside the signal handler. */ if (fd < 0) return; -(void)write(fd, process_info, process_info_len); +{int dummy = write(fd, process_info, process_info_len); dummy = dummy; } (void)close(fd); } @@ -3905,8 +3905,9 @@ if (((debug_selector & D_any) != 0 || (log_extra_selector & LX_arguments) != 0) { int i; uschar *p = big_buffer; - Ustrcpy(p, "cwd="); - (void)getcwd(CS p+4, big_buffer_size - 4); + char * dummy; + Ustrcpy(p, "cwd= (failed)"); + dummy = /* quieten compiler */ getcwd(CS p+4, big_buffer_size - 4); while (*p) p++; (void)string_format(p, big_buffer_size - (p - big_buffer), " %d args:", argc); while (*p) p++; @@ -3949,8 +3950,9 @@ privilege by now. Before the chdir, we try to ensure that the directory exists. if (Uchdir(spool_directory) != 0) { + int dummy; (void)directory_make(spool_directory, US"", SPOOL_DIRECTORY_MODE, FALSE); - (void)Uchdir(spool_directory); + dummy = /* quieten compiler */ Uchdir(spool_directory); } /* Handle calls with the -bi option. This is a sendmail option to rebuild *the* @@ -5398,7 +5400,11 @@ while (more) if (ftest_prefix != NULL) printf("Prefix = %s\n", ftest_prefix); if (ftest_suffix != NULL) printf("Suffix = %s\n", ftest_suffix); - (void)chdir("/"); /* Get away from wherever the user is running this from */ + if (chdir("/")) /* Get away from wherever the user is running this from */ + { + DEBUG(D_receive) debug_printf("chdir(\"/\") failed\n"); + exim_exit(EXIT_FAILURE); + } /* Now we run either a system filter test, or a user filter test, or both. In the latter case, headers added by the system filter will persist and be diff --git a/src/src/exim_lock.c b/src/src/exim_lock.c index 0a9dfde2d..0d3475138 100644 --- a/src/src/exim_lock.c +++ b/src/src/exim_lock.c @@ -583,12 +583,14 @@ if (restore_times) struct stat strestore; struct utimbuf ut; stat(filename, &strestore); - (void)system(command); + i = system(command); ut.actime = strestore.st_atime; ut.modtime = strestore.st_mtime; utime(filename, &ut); } -else (void)system(command); +else i = system(command); + +if(i && !quiet) printf("warning: nonzero status %d\n", i); /* Remove the locks and exit. Unlink the /tmp file if we can get an exclusive lock on the mailbox. This should be a non-blocking lock call, as there is no diff --git a/src/src/log.c b/src/src/log.c index 3a91ed295..7af92818e 100644 --- a/src/src/log.c +++ b/src/src/log.c @@ -1093,7 +1093,10 @@ if ((flags & LOG_PANIC) != 0) panic_recurseflag = FALSE; if (panic_save_buffer != NULL) - (void) write(paniclogfd, panic_save_buffer, Ustrlen(panic_save_buffer)); + { + int i = write(paniclogfd, panic_save_buffer, Ustrlen(panic_save_buffer)); + i = i; /* compiler quietening */ + } written_len = write_to_fd_buf(paniclogfd, log_buffer, length); if (written_len != length) diff --git a/src/src/malware.c b/src/src/malware.c index 7de913f49..994c62993 100644 --- a/src/src/malware.c +++ b/src/src/malware.c @@ -1214,7 +1214,7 @@ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) sizeof(sophie_options_buffer))) == NULL) { /* no options supplied, use default options */ sophie_options = sophie_options_default; - }; + } /* open the sophie socket */ sock = socket(AF_UNIX, SOCK_STREAM, 0); @@ -1249,14 +1249,14 @@ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) DEBUG(D_acl) debug_printf("Malware scan: issuing %s scan [%s]\n", scanner_name, sophie_options); - if (write(sock, file_name, Ustrlen(file_name)) < 0) { + if ( write(sock, file_name, Ustrlen(file_name)) < 0 + || write(sock, "\n", 1) != 1 + ) { (void)close(sock); log_write(0, LOG_MAIN|LOG_PANIC, "malware acl condition: unable to write to sophie UNIX socket (%s)", sophie_options); return DEFER; - }; - - (void)write(sock, "\n", 1); + } /* wait for result */ memset(av_buffer, 0, sizeof(av_buffer)); @@ -1265,7 +1265,7 @@ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) log_write(0, LOG_MAIN|LOG_PANIC, "malware acl condition: unable to read from sophie UNIX socket (%s)", sophie_options); return DEFER; - }; + } (void)close(sock); @@ -1283,7 +1283,7 @@ static int malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) else { /* all ok, no virus */ malware_name = NULL; - }; + } } /* ----------------------------------------------------------------------- */ diff --git a/src/src/queue.c b/src/src/queue.c index b3dbd2c4e..ff0ae67e5 100644 --- a/src/src/queue.c +++ b/src/src/queue.c @@ -650,7 +650,8 @@ for (i = (queue_run_in_order? -1 : 0); the mere fact that read() unblocks is enough. */ set_process_info("running queue: waiting for children of %d", pid); - (void)read(pfd[pipe_read], buffer, sizeof(buffer)); + if (read(pfd[pipe_read], buffer, sizeof(buffer)) >= 0) + log_write(0, LOG_MAIN|LOG_PANIC, "queue run: unexpected data on pipe"); (void)close(pfd[pipe_read]); set_process_info("running queue"); @@ -1018,7 +1019,7 @@ if (action >= MSG_SHOW_BODY) } while((rc = read(fd, big_buffer, big_buffer_size)) > 0) - (void)write(fileno(stdout), big_buffer, rc); + rc = write(fileno(stdout), big_buffer, rc); (void)close(fd); return TRUE; diff --git a/src/src/rda.c b/src/src/rda.c index 877434098..f915ce740 100644 --- a/src/src/rda.c +++ b/src/src/rda.c @@ -433,22 +433,24 @@ return parse_forward_list(data, * Write string down pipe * *************************************************/ -/* This function is used for tranferring a string down a pipe between +/* This function is used for transferring a string down a pipe between processes. If the pointer is NULL, a length of zero is written. Arguments: fd the pipe s the string -Returns: nothing +Returns: -1 on error, else 0 */ -static void +static int rda_write_string(int fd, uschar *s) { int len = (s == NULL)? 0 : Ustrlen(s) + 1; -(void)write(fd, &len, sizeof(int)); -if (s != NULL) (void)write(fd, s, len); +return ( write(fd, &len, sizeof(int)) != sizeof(int) + || (s != NULL && write(fd, s, len) != len) + ) + ? -1 : 0; } @@ -645,9 +647,11 @@ if ((pid = fork()) == 0) /* Pass back whether it was a filter, and the return code and any overall error text via the pipe. */ - (void)write(fd, filtertype, sizeof(int)); - (void)write(fd, &yield, sizeof(int)); - rda_write_string(fd, *error); + if ( write(fd, filtertype, sizeof(int)) != sizeof(int) + || write(fd, &yield, sizeof(int)) != sizeof(int) + || rda_write_string(fd, *error) != 0 + ) + goto bad; /* Pass back the contents of any syntax error blocks if we have a pointer */ @@ -655,11 +659,12 @@ if ((pid = fork()) == 0) { error_block *ep; for (ep = *eblockp; ep != NULL; ep = ep->next) - { - rda_write_string(fd, ep->text1); - rda_write_string(fd, ep->text2); - } - rda_write_string(fd, NULL); /* Indicates end of eblocks */ + if ( rda_write_string(fd, ep->text1) != 0 + || rda_write_string(fd, ep->text2) != 0 + ) + goto bad; + if (rda_write_string(fd, NULL) != 0) /* Indicates end of eblocks */ + goto bad; } /* If this is a system filter, we have to pass back the numbers of any @@ -671,27 +676,33 @@ if ((pid = fork()) == 0) int i = 0; header_line *h; for (h = header_list; h != waslast->next; i++, h = h->next) - { - if (h->type == htype_old) (void)write(fd, &i, sizeof(i)); - } + if ( h->type == htype_old + && write(fd, &i, sizeof(i)) != sizeof(i) + ) + goto bad; + i = -1; - (void)write(fd, &i, sizeof(i)); + if (write(fd, &i, sizeof(i)) != sizeof(i)) + goto bad; while (waslast != header_last) { waslast = waslast->next; if (waslast->type != htype_old) - { - rda_write_string(fd, waslast->text); - (void)write(fd, &(waslast->type), sizeof(waslast->type)); - } + if ( rda_write_string(fd, waslast->text) != 0 + || write(fd, &(waslast->type), sizeof(waslast->type)) + != sizeof(waslast->type) + ) + goto bad; } - rda_write_string(fd, NULL); /* Indicates end of added headers */ + if (rda_write_string(fd, NULL) != 0) /* Indicates end of added headers */ + goto bad; } /* Write the contents of the $n variables */ - (void)write(fd, filter_n, sizeof(filter_n)); + if (write(fd, filter_n, sizeof(filter_n)) != sizeof(filter_n)) + goto bad; /* If the result was DELIVERED or NOTDELIVERED, we pass back the generated addresses, and their associated information, through the pipe. This is @@ -707,52 +718,71 @@ if ((pid = fork()) == 0) { int reply_options = 0; - rda_write_string(fd, addr->address); - (void)write(fd, &(addr->mode), sizeof(addr->mode)); - (void)write(fd, &(addr->flags), sizeof(addr->flags)); - rda_write_string(fd, addr->p.errors_address); + if ( rda_write_string(fd, addr->address) != 0 + || write(fd, &(addr->mode), sizeof(addr->mode)) + != sizeof(addr->mode) + || write(fd, &(addr->flags), sizeof(addr->flags)) + != sizeof(addr->flags) + || rda_write_string(fd, addr->p.errors_address) != 0 + ) + goto bad; if (addr->pipe_expandn != NULL) { uschar **pp; for (pp = addr->pipe_expandn; *pp != NULL; pp++) - rda_write_string(fd, *pp); + if (rda_write_string(fd, *pp) != 0) + goto bad; } - rda_write_string(fd, NULL); + if (rda_write_string(fd, NULL) != 0) + goto bad; if (addr->reply == NULL) - (void)write(fd, &reply_options, sizeof(int)); /* 0 means no reply */ + { + if (write(fd, &reply_options, sizeof(int)) != sizeof(int)) /* 0 means no reply */ + goto bad; + } else { reply_options |= REPLY_EXISTS; if (addr->reply->file_expand) reply_options |= REPLY_EXPAND; if (addr->reply->return_message) reply_options |= REPLY_RETURN; - (void)write(fd, &reply_options, sizeof(int)); - (void)write(fd, &(addr->reply->expand_forbid), sizeof(int)); - (void)write(fd, &(addr->reply->once_repeat), sizeof(time_t)); - rda_write_string(fd, addr->reply->to); - rda_write_string(fd, addr->reply->cc); - rda_write_string(fd, addr->reply->bcc); - rda_write_string(fd, addr->reply->from); - rda_write_string(fd, addr->reply->reply_to); - rda_write_string(fd, addr->reply->subject); - rda_write_string(fd, addr->reply->headers); - rda_write_string(fd, addr->reply->text); - rda_write_string(fd, addr->reply->file); - rda_write_string(fd, addr->reply->logfile); - rda_write_string(fd, addr->reply->oncelog); + if ( write(fd, &reply_options, sizeof(int)) != sizeof(int) + || write(fd, &(addr->reply->expand_forbid), sizeof(int)) + != sizeof(int) + || write(fd, &(addr->reply->once_repeat), sizeof(time_t)) + != sizeof(time_t) + || rda_write_string(fd, addr->reply->to) != 0 + || rda_write_string(fd, addr->reply->cc) != 0 + || rda_write_string(fd, addr->reply->bcc) != 0 + || rda_write_string(fd, addr->reply->from) != 0 + || rda_write_string(fd, addr->reply->reply_to) != 0 + || rda_write_string(fd, addr->reply->subject) != 0 + || rda_write_string(fd, addr->reply->headers) != 0 + || rda_write_string(fd, addr->reply->text) != 0 + || rda_write_string(fd, addr->reply->file) != 0 + || rda_write_string(fd, addr->reply->logfile) != 0 + || rda_write_string(fd, addr->reply->oncelog) != 0 + ) + goto bad; } } - rda_write_string(fd, NULL); /* Marks end of addresses */ + if (rda_write_string(fd, NULL) != 0) /* Marks end of addresses */ + goto bad; } /* OK, this process is now done. Free any cached resources. Must use _exit() and not exit() !! */ +out: (void)close(fd); search_tidyup(); _exit(0); + +bad: + DEBUG(D_rewrite) debug_printf("rda_interpret: failed write to pipe\n"); + goto out; } /* Back in the main process: panic if the fork did not succeed. */ diff --git a/src/src/receive.c b/src/src/receive.c index 9b9b71790..1943a74c7 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -2793,7 +2793,10 @@ if (data_fd < 0) /* Make sure the file's group is the Exim gid, and double-check the mode because the group setting doesn't always get set automatically. */ -(void)fchown(data_fd, exim_uid, exim_gid); +if (fchown(data_fd, exim_uid, exim_gid)) + log_write(0, LOG_MAIN|LOG_PANIC_DIE, + "Failed setting ownership on spool file %s: %s", + spool_name, strerror(errno)); (void)fchmod(data_fd, SPOOL_MODE); /* We now have data file open. Build a stream for it and lock it. We lock only @@ -2823,7 +2826,7 @@ if (next != NULL) { uschar *s = next->text; int len = next->slen; - (void)fwrite(s, 1, len, data_file); + len = fwrite(s, 1, len, data_file); len = len; /* compiler quietening */ body_linecount++; /* Assumes only 1 line */ } diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 5bc331fc3..243b8f7d1 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -3192,7 +3192,9 @@ while (done <= 0) if (tls_in.active >= 0) (void)tls_write(TRUE, s, ptr); else #endif - (void)fwrite(s, 1, ptr, smtp_out); + { + int i = fwrite(s, 1, ptr, smtp_out); i = i; /* compiler quietening */ + } DEBUG(D_receive) { uschar *cr; diff --git a/src/src/spool_in.c b/src/src/spool_in.c index 674780475..a546b6521 100644 --- a/src/src/spool_in.c +++ b/src/src/spool_in.c @@ -718,8 +718,8 @@ while ((n = fgetc(f)) != EOF) int i; if (!isdigit(n)) goto SPOOL_FORMAT_ERROR; - (void)ungetc(n, f); - (void)fscanf(f, "%d%c ", &n, flag); + if(ungetc(n, f) == EOF || fscanf(f, "%d%c ", &n, flag) == EOF) + goto SPOOL_READ_ERROR; if (flag[0] != '*') message_size += n; /* Omit non-transmitted headers */ if (read_headers) diff --git a/src/src/spool_mbox.c b/src/src/spool_mbox.c index bdeb2b1a6..12cf3d43e 100644 --- a/src/src/spool_mbox.c +++ b/src/src/spool_mbox.c @@ -96,7 +96,11 @@ FILE *spool_mbox(unsigned long *mbox_file_size, uschar *source_file_override) { }; /* End headers */ - (void)fwrite("\n", 1, 1, mbox_file); + if (fwrite("\n", 1, 1, mbox_file) != 1) { + log_write(0, LOG_MAIN|LOG_PANIC, "Error/short write while writing \ + message headers to %s", mbox_path); + goto OUT; + } /* copy body file */ if (source_file_override == NULL) { diff --git a/src/src/spool_out.c b/src/src/spool_out.c index 5df2a414e..ce25a564e 100644 --- a/src/src/spool_out.c +++ b/src/src/spool_out.c @@ -93,10 +93,12 @@ double-check the mode because the group setting doesn't always get set automatically. */ if (fd >= 0) - { - (void)fchown(fd, exim_uid, exim_gid); - (void)fchmod(fd, SPOOL_MODE); - } + if (fchown(fd, exim_uid, exim_gid) || fchmod(fd, SPOOL_MODE)) + { + DEBUG(D_any) debug_printf("failed setting perms on %s\n", temp_name); + (void) close(fd); fd = -1; + Uunlink(temp_name); + } return fd; } diff --git a/src/src/transport.c b/src/src/transport.c index 7c79bb009..160d080b9 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -1226,9 +1226,14 @@ if ((write_pid = fork()) == 0) size_limit, add_headers, remove_headers, NULL, NULL, rewrite_rules, rewrite_existflags); save_errno = errno; - (void)write(pfd[pipe_write], (void *)&rc, sizeof(BOOL)); - (void)write(pfd[pipe_write], (void *)&save_errno, sizeof(int)); - (void)write(pfd[pipe_write], (void *)&(addr->more_errno), sizeof(int)); + if ( write(pfd[pipe_write], (void *)&rc, sizeof(BOOL)) + != sizeof(BOOL) + || write(pfd[pipe_write], (void *)&save_errno, sizeof(int)) + != sizeof(int) + || write(pfd[pipe_write], (void *)&(addr->more_errno), sizeof(int)) + != sizeof(int) + ) + rc = FALSE; /* compiler quietening */ _exit(0); } save_errno = errno; @@ -1339,11 +1344,11 @@ if (write_pid > 0) if (rc == 0) { BOOL ok; - (void)read(pfd[pipe_read], (void *)&ok, sizeof(BOOL)); + int dummy = read(pfd[pipe_read], (void *)&ok, sizeof(BOOL)); if (!ok) { - (void)read(pfd[pipe_read], (void *)&save_errno, sizeof(int)); - (void)read(pfd[pipe_read], (void *)&(addr->more_errno), sizeof(int)); + dummy = read(pfd[pipe_read], (void *)&save_errno, sizeof(int)); + dummy = read(pfd[pipe_read], (void *)&(addr->more_errno), sizeof(int)); yield = FALSE; } } diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c index 11c59bb0b..db3b5aeee 100644 --- a/src/src/transports/appendfile.c +++ b/src/src/transports/appendfile.c @@ -1771,8 +1771,14 @@ if (!isdirectory) /* We have successfully created and opened the file. Ensure that the group and the mode are correct. */ - (void)Uchown(filename, uid, gid); - (void)Uchmod(filename, mode); + if(Uchown(filename, uid, gid) || Uchmod(filename, mode)) + { + addr->basic_errno = errno; + addr->message = string_sprintf("while setting perms on mailbox %s", + filename); + addr->transport_return = FAIL; + goto RETURN; + } } @@ -2573,8 +2579,13 @@ else /* Why are these here? Put in because they are present in the non-maildir directory case above. */ - (void)Uchown(filename, uid, gid); - (void)Uchmod(filename, mode); + if(Uchown(filename, uid, gid) || Uchmod(filename, mode)) + { + addr->basic_errno = errno; + addr->message = string_sprintf("while setting perms on maildir %s", + filename); + return FALSE; + } } #endif /* SUPPORT_MAILDIR */ @@ -2615,8 +2626,13 @@ else /* Why are these here? Put in because they are present in the non-maildir directory case above. */ - (void)Uchown(filename, uid, gid); - (void)Uchmod(filename, mode); + if(Uchown(filename, uid, gid) || Uchmod(filename, mode)) + { + addr->basic_errno = errno; + addr->message = string_sprintf("while setting perms on file %s", + filename); + return FALSE; + } /* Built a C stream from the open file descriptor. */ @@ -2707,8 +2723,13 @@ else Uunlink(filename); return FALSE; } - (void)Uchown(dataname, uid, gid); - (void)Uchmod(dataname, mode); + if(Uchown(dataname, uid, gid) || Uchmod(dataname, mode)) + { + addr->basic_errno = errno; + addr->message = string_sprintf("while setting perms on file %s", + dataname); + return FALSE; + } } #endif /* SUPPORT_MAILSTORE */ @@ -2717,8 +2738,13 @@ else /* In all cases of writing to a new file, ensure that the file which is going to be renamed has the correct ownership and mode. */ - (void)Uchown(filename, uid, gid); - (void)Uchmod(filename, mode); + if(Uchown(filename, uid, gid) || Uchmod(filename, mode)) + { + addr->basic_errno = errno; + addr->message = string_sprintf("while setting perms on file %s", + filename); + return FALSE; + } } @@ -3095,7 +3121,8 @@ if (yield != OK) investigated so far have ftruncate(), whereas not all have the F_FREESP fcntl() call (BSDI & FreeBSD do not). */ - if (!isdirectory) (void)ftruncate(fd, saved_size); + if (!isdirectory && ftruncate(fd, saved_size)) + DEBUG(D_transport) debug_printf("Error restting file size\n"); } /* Handle successful writing - we want the modification time to be now for diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c index cce1cd771..4e391b8db 100644 --- a/src/src/transports/autoreply.c +++ b/src/src/transports/autoreply.c @@ -529,8 +529,10 @@ if (oncelog != NULL && *oncelog != 0 && to != NULL) uschar *ptr = log_buffer; sprintf(CS ptr, "%s\n previously sent to %.200s\n", tod_stamp(tod_log), to); while(*ptr) ptr++; - (void)write(log_fd, log_buffer, ptr - log_buffer); - (void)close(log_fd); + if(write(log_fd, log_buffer, ptr - log_buffer) != ptr-log_buffer + || close(log_fd)) + DEBUG(D_transport) debug_printf("Problem writing log file %s for %s " + "transport\n", logfile, tblock->name); } goto END_OFF; } @@ -753,7 +755,9 @@ if (cache_fd >= 0) } memcpy(cache_time, &now, sizeof(time_t)); - (void)write(cache_fd, from, size); + if(write(cache_fd, from, size) != size) + DEBUG(D_transport) debug_printf("Problem writing cache file %s for %s " + "transport\n", oncelog, tblock->name); } /* Update DBM file */ @@ -849,8 +853,10 @@ if (logfile != NULL) " %s\n", headers); while(*ptr) ptr++; } - (void)write(log_fd, log_buffer, ptr - log_buffer); - (void)close(log_fd); + if(write(log_fd, log_buffer, ptr - log_buffer) != ptr-log_buffer + || close(log_fd)) + DEBUG(D_transport) debug_printf("Problem writing log file %s for %s " + "transport\n", logfile, tblock->name); } else DEBUG(D_transport) debug_printf("Failed to open log file %s for %s " "transport: %s\n", logfile, tblock->name, strerror(errno)); diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c index 32a7bfa7c..fe94e8575 100644 --- a/src/src/transports/pipe.c +++ b/src/src/transports/pipe.c @@ -749,14 +749,19 @@ if (outpid == 0) while ((rc = read(fd_out, big_buffer, big_buffer_size)) > 0) { if (addr->return_file >= 0) - write(addr->return_file, big_buffer, rc); + if(write(addr->return_file, big_buffer, rc) != rc) + DEBUG(D_transport) debug_printf("Problem writing to return_file\n"); count += rc; if (count > ob->max_output) { - uschar *message = US"\n\n*** Too much output - remainder discarded ***\n"; DEBUG(D_transport) debug_printf("Too much output from pipe - killed\n"); if (addr->return_file >= 0) - write(addr->return_file, message, Ustrlen(message)); + { + uschar *message = US"\n\n*** Too much output - remainder discarded ***\n"; + rc = Ustrlen(message); + if(write(addr->return_file, message, rc) != rc) + DEBUG(D_transport) debug_printf("Problem writing to return_file\n"); + } killpg(pid, SIGKILL); break; } diff --git a/src/src/transports/tf_maildir.c b/src/src/transports/tf_maildir.c index 7a240b6c0..cfe7cb291 100644 --- a/src/src/transports/tf_maildir.c +++ b/src/src/transports/tf_maildir.c @@ -212,7 +212,7 @@ uschar buffer[256]; sprintf(CS buffer, "%d 1\n", size); len = Ustrlen(buffer); (void)lseek(fd, 0, SEEK_END); -(void)write(fd, buffer, len); +len = write(fd, buffer, len); DEBUG(D_transport) debug_printf("added '%.*s' to maildirsize file\n", len-1, buffer); } -- 2.25.1