A brief search of the mailing list archives on findmail.com didn't turn up
anything about this, so here's a bug report and potential fix for a crash
I got when attempting to use mailstore_format.
The problem is twofold:
First, having called
fd = open(filename, O_WRONLY|...);
(note write-only), the call to
env_file = fdopen(fd, "w+");
attempts to make the resulting FILE object read/write. On my Linux system,
this fails; it can be corrected by simply dropping the "+" from the mode
string in the fdopen() call, because `env_file' is never used for reading.
Second, the code never tested for failure of fdopen(), which resulted in a
crash. Patch for both of these details is below, though I'm not sure that
I set up the error values in the `addr' structure correctly.
A couple of additional remarks:
I found it rather difficult to debug this problem because there's no way
(except by editing the code) to stop exim from forking before delivery,
and there's no way (again other than editing to remove the setrlimit()
call) to cause it to generate a core dump. It would be nice if both of
these were controllable by debug settings.
A bit later on in the code, `fd' is disposed of by the sequence
fflush(env_file);
if (close(fd) < 0)
...
This is a potential problem, because if the program terminates with a call
to exit() [rather than _exit()], that FILE object may get implicitly
fclose()d. If the descriptor with the same number as fd has been reused
it the meantime, this could have unpleasant side effects. I believe it
would be correct to replace the above with
if (fclose(env_file) < 0)
...
or, if you're really paranoid, with
if (fclose(env_file) < 0 || (close(fd) < 0 && errno != EBADF))
...
but the patch below does not address this.
Index: src/transports/appendfile.c
===================================================================
--- appendfile.c 1999/01/19 06:37:45 1.1.1.1
+++ appendfile.c 1999/01/19 06:59:35 1.2
@@ -1826,7 +1826,16 @@
/* Write the envelope file, then close it. */
- env_file = fdopen(fd, "w+");
+ if ((env_file = fdopen(fd, "w")) == NULL)
+ {
+ addr->basic_errno = errno;
+ addr->transport_return = PANIC;
+ addr->message = string_sprintf("Open of %s ("
+ "for %s transport) failed", filename, tblock->name);
+ close(fd);
+ unlink(filename);
+ return;
+ }
if (ob->mailstore_prefix != NULL)
{
--
*** Exim information can be found at
http://www.exim.org/ ***