Subject: | race conditions with SIGPIPE from gpg filehandles |
Hi,
there seem to be several race conditions in Mail::GnuPG 0.08 in
situations where the child gpg process exits immediately, eg. because of
an unknown keyid specified in its options. This may happen before the
module has had time to print() into the gpg filehandles, making the
program fail silently with SIGPIPE.
This problem was originally reported as Debian bug #412041,
<http://bugs.debian.org/412041>. The example script there fails for me
about 3% of the time.
I'm attaching a proposed patch that sets $SIG{PIPE}='IGNORE' for the
print() calls. Please consider including it.
Thanks for your work on Mail::GnuPG,
--
Niko Tyni (on behalf of the Debian Perl Group)
ntyni@iki.fi
Subject: | Mail-GnuPG.race.patch |
--- libmail-gnupg-perl-0.08.orig/GnuPG.pm
+++ libmail-gnupg-perl-0.08/GnuPG.pm
@@ -63,6 +63,16 @@
return $self;
}
+sub _maybe_print {
+ # print to a child gpg process, but don't care if it has died already
+ # everyone using this will read the error string out afterwards anyway
+ # see http://bugs.debian.org/412041
+
+ my $fh = shift;
+ local $SIG{PIPE} = 'IGNORE';
+ print $fh @_;
+}
+
sub _set_options {
my ($self,$gnupg) = @_;
$gnupg->options->meta_interactive( 0 );
@@ -162,11 +172,11 @@
# This passes in the passphrase
die "NO PASSPHRASE" unless defined $passphrase_fh;
- print $passphrase_fh $self->{passphrase};
+ _maybe_print $passphrase_fh,$self->{passphrase};
close $passphrase_fh;
# this passes in the plaintext
- print $input $ciphertext;
+ _maybe_print $input,$ciphertext;
# this closes the communication channel,
# indicating we are done
@@ -547,7 +557,7 @@
);
my $pid = $gnupg->detach_sign( handles => $handles );
die "NO PASSPHRASE" unless defined $passphrase_fh;
- print $passphrase_fh $self->{passphrase};
+ _maybe_print $passphrase_fh,$self->{passphrase};
close $passphrase_fh;
@@ -565,7 +575,7 @@
$plaintext =~ s/\x0D+/\x0D/g;
# should we store this back into the body?
- print $input $plaintext;
+ _maybe_print $input,$plaintext;
# DEBUG:
# print "SIGNING THIS STRING ----->\n";
@@ -653,7 +663,7 @@
$plaintext =~ s/\x0A/\x0D\x0A/g;
$plaintext =~ s/\x0D+/\x0D/g;
- print $input $plaintext;
+ _maybe_print $input,$plaintext;
close $input;
my @ciphertext = <$output>;
@@ -756,7 +766,7 @@
}
};
- print $input $plaintext;
+ _maybe_print $input,$plaintext;
close $input;
my @ciphertext = <$output>;
@@ -857,7 +867,7 @@
};
die "NO PASSPHRASE" unless defined $passphrase_fh;
- print $passphrase_fh $self->{passphrase};
+ _maybe_print $passphrase_fh,$self->{passphrase};
close $passphrase_fh;
# this passes in the plaintext
@@ -872,7 +882,7 @@
# $plaintext =~ s/\n/\x0D\x0A/sg;
# should we store this back into the body?
- print $input $plaintext;
+ _maybe_print $input,$plaintext;
# DEBUG:
#print "ENCRYPTING THIS STRING ----->\n";