--- /dev/null
+
+package CheckVulnerabilities;
+
+my $NAME = 'test-vulnerabilities.pl';
+my $DATE = '2013/01/23 20:26:29';
+my $AUTHORS = "Jim Meyering <meyering\@redhat.com>, Ward Vandewege <ward\@gnu.org>";
+my $COPYRIGHT = "2013";
+my $LICENSE = "GPLv3 or later - http://www.fsf.org/licenses/gpl.txt";
+my $URL = "http://www.gnu.org/prep/maintain/html_node/Automated-FTP-Uploads.html";
+
+use strict;
+use Exporter;
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
+
+$VERSION = 1.00;
+@ISA = qw(Exporter);
+@EXPORT = ();
+@EXPORT_OK = qw(check_vulnerabilities);
+%EXPORT_TAGS = ( DEFAULT => [qw(&check_vulnerabilities)] );
+
+sub check_vulnerabilities {
+ my ($upload_file,$log_style,$debug) = @_;
+
+ my ($error_string, $error_log_ref) = &automake_tests($upload_file,$log_style,$debug);
+
+ return ($error_string, $error_log_ref);
+}
+
+sub automake_tests {
+ my ($upload_file,$log_style,$debug) = @_;
+
+ my $error_string = '';
+ my @debug_log;
+
+ if (! -e $upload_file) {
+ return("Error: $upload_file not found\n\n", \@debug_log);
+ }
+
+ if (! -r $upload_file) {
+ return("Error: $upload_file is unreadable\n\n", \@debug_log);
+ }
+
+ # Reject an upload tarball if it contains a Makefile.in vulnerable
+ # as described in CVE-2009-4029.
+ # http://thread.gmane.org/gmane.comp.sysutils.autotools.announce/131
+ if ($upload_file =~ /\.(tar|)(\.|$)|\.t[bglx]z|\.tbz2$/) {
+ # First check if the file contains any Makefile.in files
+ push(@debug_log,"($log_style) DEBUG: testing $upload_file for presence of Makefile.in") if $debug;
+ my $tar_cmd = "/bin/tar -tf $upload_file";
+ open (TAR, "$tar_cmd|")
+ or return("Error: failed to run command: $tar_cmd\n\n", \@debug_log);
+ my $found_makefile = 0;
+ while (defined (my $line = <TAR>)) {
+ if ($line =~ /Makefile.in/i) {
+ $found_makefile = 1;
+ last;
+ }
+ }
+ close(TAR); # We don't care about errors here; the pipe can cause non-zero exit codes when tar is unhappy that it's asked to stop
+ return ($error_string, \@debug_log) if (!$found_makefile);
+ # If it does, check inside them
+ push(@debug_log,"($log_style) DEBUG: found Makefile.in, testing for CVE-2009-4029 and CVE-2012-3386") if $debug;
+ $tar_cmd = "/bin/tar --to-stdout -x -f $upload_file 'Makefile.in' --wildcards '*/Makefile.in' 2>/dev/null";
+ open (TAR, "$tar_cmd|")
+ or return("Error: failed to run command: $tar_cmd\n\n", \@debug_log);
+ my $found_cve_2009_4029 = 0;
+ my $found_cve_2012_3386 = 0;
+ while (defined (my $line = <TAR>)) {
+ if ($line =~ /perm -777 -exec chmod a\+rwx|chmod 777 \$\(distdir\)/) {
+ $found_cve_2009_4029 = 1;
+ }
+ if ($line =~ /chmod a\+w \$\(distdir\)/) {
+ $found_cve_2012_3386 = 1;
+ }
+ }
+ close(TAR); # We don't care about errors here; the pipe can cause non-zero exit codes when tar is unhappy that it's asked to stop
+
+ # Because CVE-2012-3386 was not fixed until 1.11.6 / 1.12.2, we point people to that version instead
+ # of 1.11.1, which fixes CVE-2009-4029. Ward, 2012-07-20
+ $found_cve_2009_4029 and $error_string .= "file rejected: $upload_file contains a vulnerable "
+ . "Makefile.in (CVE-2009-4029);\n"
+ . "Regenerate it with automake 1.11.6 / 1.12.2 or newer.\n\n";
+
+ $found_cve_2012_3386 and $error_string .= "file rejected: $upload_file contains a vulnerable "
+ . "Makefile.in (CVE-2012-3386);\n"
+ . "Regenerate it with automake 1.11.6 / 1.12.2 or newer.\n\n";
+
+ }
+ return ($error_string, \@debug_log);
+}
+
+1;