From: Jeremy Harris Date: Tue, 20 Mar 2018 17:54:47 +0000 (+0000) Subject: Fix pipe transport to not use a socket-only syscall. Bug 2257 X-Git-Tag: exim-4_91_RC2~4 X-Git-Url: https://vcs.fsf.org/?p=exim.git;a=commitdiff_plain;h=b3b370766107a2bda78f6362170ddbe4b2c0bb21;ds=sidebyside Fix pipe transport to not use a socket-only syscall. Bug 2257 Broken-by: 42055a3385 --- diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 1dff01fb5..236ccae8b 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -163,6 +163,8 @@ JH/29 Bug 2250: Fix a longstanding bug in heavily-pipelined SMTP input (such JH/30 The (EXPERIMENTAL_DMARC) variable $dmarc_ar_header is withdrawn, being replaced by the ${authresults } expansion. +JH/31 Bug 2257: Fix pipe transport to not use a socket-only syscall. + Exim version 4.90 ----------------- diff --git a/src/src/macros.h b/src/src/macros.h index beab72a28..85ceb0acb 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -864,6 +864,7 @@ enum { #define topt_use_bdat 0x100 /* prepend chunks with RFC3030 BDAT header */ #define topt_output_string 0x200 /* create string rather than write to fd */ #define topt_continuation 0x400 /* do not reset buffer */ +#define topt_not_socket 0x800 /* cannot do socket-only syscalls */ /* Options for smtp_write_command */ diff --git a/src/src/transport.c b/src/src/transport.c index d598e5aab..073c4ad65 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -245,7 +245,8 @@ for (i = 0; i < 100; i++) tls_out.active == fd ? tls_write(FALSE, block, len, more) : #endif #ifdef MSG_MORE - more ? send(fd, block, len, MSG_MORE) : + more && !(tctx->options & topt_not_socket) + ? send(fd, block, len, MSG_MORE) : #endif write(fd, block, len); save_errno = errno; diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c index 37f994fac..321dbc947 100644 --- a/src/src/transports/appendfile.c +++ b/src/src/transports/appendfile.c @@ -945,9 +945,7 @@ copy_mbx_message(int to_fd, int from_fd, off_t saved_size) int used; off_t size; struct stat statbuf; -transport_ctx tctx = {{0}}; - -tctx.u.fd = to_fd; +transport_ctx tctx = { .u={.fd = to_fd}, .options = topt_not_socket }; /* If the current mailbox size is zero, write a header block */ @@ -2921,12 +2919,12 @@ at initialization time. */ if (yield == OK) { transport_ctx tctx = { - {fd}, - tblock, - addr, - ob->check_string, - ob->escape_string, - ob->options + .u = {.fd=fd}, + .tblock = tblock, + .addr = addr, + .check_string = ob->check_string, + .escape_string = ob->escape_string, + .options = ob->options | topt_not_socket }; if (!transport_write_message(&tctx, 0)) yield = DEFER; diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c index f85bc4739..c3ed16962 100644 --- a/src/src/transports/autoreply.c +++ b/src/src/transports/autoreply.c @@ -694,15 +694,17 @@ if (return_message) : US"------ This is a copy of the message, including all the headers.\n"; transport_ctx tctx = { - {fileno(f)}, - tblock, - addr, - NULL, NULL, - (tblock->body_only ? topt_no_headers : 0) | - (tblock->headers_only ? topt_no_body : 0) | - (tblock->return_path_add ? topt_add_return_path : 0) | - (tblock->delivery_date_add ? topt_add_delivery_date : 0) | - (tblock->envelope_to_add ? topt_add_envelope_to : 0) + .u = {.fd = fileno(f)}, + .tblock = tblock, + .addr = addr, + .check_string = NULL, + .escape_string = NULL, + .options = (tblock->body_only ? topt_no_headers : 0) + | (tblock->headers_only ? topt_no_body : 0) + | (tblock->return_path_add ? topt_add_return_path : 0) + | (tblock->delivery_date_add ? topt_add_delivery_date : 0) + | (tblock->envelope_to_add ? topt_add_envelope_to : 0) + | topt_not_socket }; if (bounce_return_size_limit > 0 && !tblock->headers_only) diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c index 1ae5a70d9..5470c72de 100644 --- a/src/src/transports/pipe.c +++ b/src/src/transports/pipe.c @@ -566,12 +566,11 @@ const uschar *envlist = ob->environment; uschar *cmd, *ss; uschar *eol = ob->use_crlf ? US"\r\n" : US"\n"; transport_ctx tctx = { - {0}, - tblock, - addr, - ob->check_string, - ob->escape_string, - ob->options /* set at initialization time */ + .tblock = tblock, + .addr = addr, + .check_string = ob->check_string, + .escape_string = ob->escape_string, + ob->options | topt_not_socket /* set at initialization time */ }; DEBUG(D_transport) debug_printf("%s transport entered\n", tblock->name);