From f3b52e907b53ee1977a3b7cc50f4c4dcedf4e8cc Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Wed, 22 Jun 2022 13:49:46 +0200 Subject: [PATCH] CVE-2022-2068: the c_rehash script allows command injection Related: rhbz#2098277 --- 0068-CVE-2022-2068.patch | 174 +++++++++++++++++++++++++++++++++++++++ openssl.spec | 5 ++ 2 files changed, 179 insertions(+) create mode 100644 0068-CVE-2022-2068.patch diff --git a/0068-CVE-2022-2068.patch b/0068-CVE-2022-2068.patch new file mode 100644 index 0000000..c4dd7f2 --- /dev/null +++ b/0068-CVE-2022-2068.patch @@ -0,0 +1,174 @@ +diff -up openssl-3.0.1/tools/c_rehash.in.cve20222068 openssl-3.0.1/tools/c_rehash.in +--- openssl-3.0.1/tools/c_rehash.in.cve20222068 2022-06-22 13:15:57.347421765 +0200 ++++ openssl-3.0.1/tools/c_rehash.in 2022-06-22 13:16:14.797576250 +0200 +@@ -104,18 +104,41 @@ foreach (@dirlist) { + } + exit($errorcount); + ++sub copy_file { ++ my ($src_fname, $dst_fname) = @_; ++ ++ if (open(my $in, "<", $src_fname)) { ++ if (open(my $out, ">", $dst_fname)) { ++ print $out $_ while (<$in>); ++ close $out; ++ } else { ++ warn "Cannot open $dst_fname for write, $!"; ++ } ++ close $in; ++ } else { ++ warn "Cannot open $src_fname for read, $!"; ++ } ++} ++ + sub hash_dir { ++ my $dir = shift; + my %hashlist; +- print "Doing $_[0]\n"; +- chdir $_[0]; +- opendir(DIR, "."); ++ ++ print "Doing $dir\n"; ++ ++ if (!chdir $dir) { ++ print STDERR "WARNING: Cannot chdir to '$dir', $!\n"; ++ return; ++ } ++ ++ opendir(DIR, ".") || print STDERR "WARNING: Cannot opendir '.', $!\n"; + my @flist = sort readdir(DIR); + closedir DIR; + if ( $removelinks ) { + # Delete any existing symbolic links + foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) { + if (-l $_) { +- print "unlink $_" if $verbose; ++ print "unlink $_\n" if $verbose; + unlink $_ || warn "Can't unlink $_, $!\n"; + } + } +@@ -130,13 +153,16 @@ sub hash_dir { + link_hash_cert($fname) if ($cert); + link_hash_crl($fname) if ($crl); + } ++ ++ chdir $pwd; + } + + sub check_file { + my ($is_cert, $is_crl) = (0,0); + my $fname = $_[0]; +- open IN, $fname; +- while() { ++ ++ open(my $in, "<", $fname); ++ while(<$in>) { + if (/^-----BEGIN (.*)-----/) { + my $hdr = $1; + if ($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) { +@@ -148,7 +174,7 @@ sub check_file { + } + } + } +- close IN; ++ close $in; + return ($is_cert, $is_crl); + } + +@@ -177,76 +203,49 @@ sub compute_hash { + # certificate fingerprints + + sub link_hash_cert { +- my $fname = $_[0]; +- my ($hash, $fprint) = compute_hash($openssl, "x509", $x509hash, +- "-fingerprint", "-noout", +- "-in", $fname); +- chomp $hash; +- chomp $fprint; +- return if !$hash; +- $fprint =~ s/^.*=//; +- $fprint =~ tr/://d; +- my $suffix = 0; +- # Search for an unused hash filename +- while(exists $hashlist{"$hash.$suffix"}) { +- # Hash matches: if fingerprint matches its a duplicate cert +- if ($hashlist{"$hash.$suffix"} eq $fprint) { +- print STDERR "WARNING: Skipping duplicate certificate $fname\n"; +- return; +- } +- $suffix++; +- } +- $hash .= ".$suffix"; +- if ($symlink_exists) { +- print "link $fname -> $hash\n" if $verbose; +- symlink $fname, $hash || warn "Can't symlink, $!"; +- } else { +- print "copy $fname -> $hash\n" if $verbose; +- if (open($in, "<", $fname)) { +- if (open($out,">", $hash)) { +- print $out $_ while (<$in>); +- close $out; +- } else { +- warn "can't open $hash for write, $!"; +- } +- close $in; +- } else { +- warn "can't open $fname for read, $!"; +- } +- } +- $hashlist{$hash} = $fprint; ++ link_hash($_[0], 'cert'); + } + + # Same as above except for a CRL. CRL links are of the form .r + + sub link_hash_crl { +- my $fname = $_[0]; +- my ($hash, $fprint) = compute_hash($openssl, "crl", $crlhash, ++ link_hash($_[0], 'crl'); ++} ++ ++sub link_hash { ++ my ($fname, $type) = @_; ++ my $is_cert = $type eq 'cert'; ++ ++ my ($hash, $fprint) = compute_hash($openssl, ++ $is_cert ? "x509" : "crl", ++ $is_cert ? $x509hash : $crlhash, + "-fingerprint", "-noout", + "-in", $fname); + chomp $hash; ++ $hash =~ s/^.*=// if !$is_cert; + chomp $fprint; + return if !$hash; + $fprint =~ s/^.*=//; + $fprint =~ tr/://d; + my $suffix = 0; + # Search for an unused hash filename +- while(exists $hashlist{"$hash.r$suffix"}) { ++ my $crlmark = $is_cert ? "" : "r"; ++ while(exists $hashlist{"$hash.$crlmark$suffix"}) { + # Hash matches: if fingerprint matches its a duplicate cert +- if ($hashlist{"$hash.r$suffix"} eq $fprint) { +- print STDERR "WARNING: Skipping duplicate CRL $fname\n"; ++ if ($hashlist{"$hash.$crlmark$suffix"} eq $fprint) { ++ my $what = $is_cert ? 'certificate' : 'CRL'; ++ print STDERR "WARNING: Skipping duplicate $what $fname\n"; + return; + } + $suffix++; + } +- $hash .= ".r$suffix"; ++ $hash .= ".$crlmark$suffix"; + if ($symlink_exists) { + print "link $fname -> $hash\n" if $verbose; + symlink $fname, $hash || warn "Can't symlink, $!"; + } else { +- print "cp $fname -> $hash\n" if $verbose; +- system ("cp", $fname, $hash); +- warn "Can't copy, $!" if ($? >> 8) != 0; ++ print "copy $fname -> $hash\n" if $verbose; ++ copy_file($fname, $hash); + } + $hashlist{$hash} = $fprint; + } diff --git a/openssl.spec b/openssl.spec index b8dd873..0eccec7 100644 --- a/openssl.spec +++ b/openssl.spec @@ -132,6 +132,9 @@ Patch65: 0065-CVE-2022-1292.patch Patch66: 0066-replace-expired-certs.patch # https://github.com/openssl/openssl/pull/18512 Patch67: 0067-fix-ppc64-montgomery.patch +#https://github.com/openssl/openssl/commit/2c9c35870601b4a44d86ddbf512b38df38285cfa +#https://github.com/openssl/openssl/commit/8a3579a7b7067a983e69a4eda839ac408c120739 +Patch68: 0068-CVE-2022-2068.patch License: ASL 2.0 URL: http://www.openssl.org/ @@ -474,6 +477,8 @@ install -m644 %{SOURCE9} \ - Related: rhbz#2098199 - Strict certificates validation shouldn't allow explicit EC parameters - Related: rhbz#2058663 +- CVE-2022-2068: the c_rehash script allows command injection +- Related: rhbz#2098277 * Wed Jun 08 2022 Clemens Lang - 1:3.0.1-35 - Add explicit indicators for signatures in FIPS mode and mark signature