Skip Menu |

This queue is for tickets about the MIME-Lite CPAN distribution.

Report information
The Basics
Id: 17898
Status: open
Priority: 0/
Queue: MIME-Lite

People
Owner: Nobody in particular
Requestors: rz [...] softpoint.de
Cc: chisel [...] chizography.net
victor [...] vsespb.ru
AdminCc:

Bug Information
Severity: Critical
Broken in: (no value)
Fixed in: (no value)



Subject: Program code is executed twice while using the MIME-Lite Modul
Program code is executed twice while using the MIME-Lite Modul. The problem occurs in the following situtation: I executed the taint-save 'send' method in an 'eval' environment. But the sendmail command can't be 'exec()' (wrong path, never mind) and the child process is reached the 'die "can't exec...'. This should terminate the child but it did not because it is inside of an 'eval'-block. The child runs out of the eval and to a normal program ending. The father wait until the child is comming to an end and runs to a normal program ending too. e.g. program code is executed twice, this could be very critical. My suggestion is to termiate the child process by exit() instead of die(). Below you can see the concerned code snippet from the MIME-Lite send-method: my $pid = open SENDMAIL, "|-"; defined($pid) or die "open of pipe failed: $!\n"; if (!$pid) { ### child exec(@cmd) or die "can't exec $p{Sendmail}: $!\n"; ### NOTREACHED } else { ### parent $self->print(\*SENDMAIL); close SENDMAIL || die "error closing $p{Sendmail}: $! (exit $?)\n"; return 1; } greetings robert
On Tue Feb 28 13:08:56 2006, guest wrote: Show quoted text
> My suggestion is to termiate the child process by exit() instead of die().
I suggest to terminate process with POSIX::_exit() otherwise sometimes END{}/DESTROY executed twice (i.e. when die()/exit() used ) and sometimes once (i.e. when exec() is successful)
Replacing 'die' with 'exit' would be an improvement, but won't prevent all problems: END blocks and DESTROY methods would still be run in the child process. I don't think there's a complete solution to the problem of hiding your forks from the caller. 'exit' seems to be at least better than 'die', in that it won't be caught by eval/try/whatever. If the parent is trapping exit… they should know what they're doing. Maybe document more explicitly that MIME::Lite forks?
I've been caught by this bug again, and I have a solution. The attached patch replaces the messy open/exec with a simple multi-arg open. This fixes #21425, too: now the two "open"s are the same.
Subject: mime-lite-17898.patch
diff --git i/lib/MIME/Lite.pm w/lib/MIME/Lite.pm index ab9c2a3..550818e 100644 --- i/lib/MIME/Lite.pm +++ w/lib/MIME/Lite.pm @@ -2722,16 +2722,11 @@ sub send_by_sendmail { } ### Open the command in a taint-safe fashion: - my $pid = open SENDMAIL, "|-"; - defined($pid) or die "open of pipe failed: $!\n"; - if ( !$pid ) { ### child - exec(@cmd) or die "can't exec $p{Sendmail}: $!\n"; - ### NOTREACHED - } else { ### parent - $self->print( \*SENDMAIL ); - close SENDMAIL || die "error closing $p{Sendmail}: $! (exit $?)\n"; - $return = 1; - } + my $pid = open SENDMAIL, "|-", @cmd + or die "open of pipe failed: $!\n"; + $self->print( \*SENDMAIL ); + close SENDMAIL || die "error closing $p{Sendmail}: $! (exit $?)\n"; + $return = 1; } return $self->{last_send_successful} = $return; }