[SCM] KDE Development Platform Libraries module packaging branch, squeeze, updated. debian/4.4.5-2+squeeze1-7-g66efdda

Modestas Vainius modax at alioth.debian.org
Sat May 14 23:29:43 UTC 2011


The following commit has been merged in the squeeze branch:
commit af9374ec888f9286002a24551f2512431fd1db72
Author: Modestas Vainius <modax at debian.org>
Date:   Sat May 14 19:53:45 2011 +0300

    KTar: use unsigned arithmetic when calculating checksum of tar header record.
    
    According to the ustar specification, implementations must use unsigned
    arithmetic when calculating checksum field of the tar header record. KTar prior
    to this patch used signed arithmetic for checksum calculation when writing an
    archive. The patch fixes this.
    
    However, there are more broken tar implementations out there (including former
    KTar itself) so the patch also makes KTar to verify checksums using both
    unsigned and signed arithmetic when reading archives. If either of checksums
    matches, archive is accepted.
    
    Implemented in ktar_header_checksum_fix.diff patch.
---
 debian/changelog                             |    5 ++
 debian/patches/ktar_header_checksum_fix.diff |   94 ++++++++++++++++++++++++++
 debian/patches/series                        |    1 +
 3 files changed, 100 insertions(+), 0 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 402d0d1..2bdb245 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -10,6 +10,11 @@ kde4libs (4:4.4.5-2+squeeze2) UNRELEASED; urgency=low
     an IP address) by cve_2011_1094_ssl_verify_hostname.diff.
 
   [ Modestas Vainius ]
+  * KTar: use unsigned arithmetic when calculating checksum of tar header record
+    (as per ustar specification). However, when reading archive, verify
+    checksum by calculating it both ways (unsigned and signed) and accept if
+    either matches (partially solves #612675). Implemented in
+    ktar_header_checksum_fix.diff patch.
 
  -- José Manuel Santamaría Lema <panfaust at gmail.com>  Tue, 12 Apr 2011 21:16:20 +0200
 
diff --git a/debian/patches/ktar_header_checksum_fix.diff b/debian/patches/ktar_header_checksum_fix.diff
new file mode 100644
index 0000000..297aaac
--- /dev/null
+++ b/debian/patches/ktar_header_checksum_fix.diff
@@ -0,0 +1,94 @@
+From: Modestas Vainius <modax at debian.org>
+Subject: Use unsigned arithmetic when calculating tar header checksum
+Forwarded: yes
+Bug: https://bugs.kde.org/show_bug.cgi?id=266141
+Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=612675
+Last-Update: 2011-05-14
+Origin: vendor
+
+According to the ustar specification, implementations must use unsigned
+arithmetic when calculating checksum field of the tar header record. KTar prior
+to this patch used signed arithmetic for checksum calculation when writing an
+archive. The patch fixes this.
+
+However, there are more broken tar implementations out there (including former
+KTar itself) so the patch also makes KTar to verify checksums using both
+unsigned and signed arithmetic when reading archives. If either of checksums
+matches, archive is accepted.
+
+--- a/kio/kio/ktar.cpp
++++ b/kio/kio/ktar.cpp
+@@ -198,26 +198,41 @@ qint64 KTar::KTarPrivate::readRawHeader(
+     if (strncmp(buffer + 257, "ustar", 5)) {
+       // The magic isn't there (broken/old tars), but maybe a correct checksum?
+ 
+-      int check = 0;
+-      for( uint j = 0; j < 0x200; ++j )
+-        check += buffer[j];
++      // Checksum is supposed to be a sum of unsigned bytes but some
++      // implementations sum signed chars. Therefore, just check both.
++      int check_unsigned = 0, check_signed = 0;
++      for( uint j = 0; j < 0x200; ++j ) {
++        check_unsigned += (unsigned char) buffer[j];
++        check_signed += buffer[j];
++      }
+ 
+       // adjust checksum to count the checksum fields as blanks
+-      for( uint j = 0; j < 8 /*size of the checksum field including the \0 and the space*/; j++ )
+-        check -= buffer[148 + j];
+-      check += 8 * ' ';
+-
+-      QByteArray s = QByteArray::number( check, 8 ); // octal
+-
+-      // only compare those of the 6 checksum digits that mean something,
+-      // because the other digits are filled with all sorts of different chars by different tars ...
+-      // Some tars right-justify the checksum so it could start in one of three places - we have to check each.
+-      if( strncmp( buffer + 148 + 6 - s.length(), s.data(), s.length() )
+-        && strncmp( buffer + 148 + 7 - s.length(), s.data(), s.length() )
+-        && strncmp( buffer + 148 + 8 - s.length(), s.data(), s.length() ) ) {
++      for( uint j = 0; j < 8 /*size of the checksum field including the \0 and the space*/; j++ ) {
++        check_unsigned -= (unsigned char) buffer[148 + j];
++        check_signed -= buffer[148 + j];
++      }
++      check_unsigned += 8 * ' ';
++      check_signed += 8 * ' ';
++
++      QList<QByteArray> checks;
++      checks << QByteArray::number( check_unsigned, 8 ); // octal
++      if (check_unsigned != check_signed)
++        checks << QByteArray::number( check_signed, 8 ); // octal
++
++      bool checksum_ok = false;
++      foreach (QByteArray s, checks) {
++        // only compare those of the 6 checksum digits that mean something,
++        // because the other digits are filled with all sorts of different chars by different tars ...
++        // Some tars right-justify the checksum so it could start in one of three places - we have to check each.
++        if ((checksum_ok = !strncmp( buffer + 148 + 6 - s.length(), s.data(), s.length() )
++          || !strncmp( buffer + 148 + 7 - s.length(), s.data(), s.length() )
++          || !strncmp( buffer + 148 + 8 - s.length(), s.data(), s.length() )))
++            break;
++      }
++      if (!checksum_ok) {
+         kWarning(7041) << "KTar: invalid TAR file. Header is:" << QByteArray( buffer+257, 5 )
+                        << "instead of ustar. Reading from wrong pos in file?"
+-                       << "checksum=" << QByteArray( buffer + 148 + 6 - s.length(), s.length() );
++                       << "checksum=" << QByteArray( buffer + 148, 6 );
+         return -1;
+       }
+     }/*end if*/
+@@ -658,10 +673,12 @@ void KTar::KTarPrivate::fillBuffer( char
+   // group
+   strcpy( buffer + 0x129, gname );
+ 
+-  // Header check sum
+-  int check = 32;
++  // For checksumming purposes, all checksum[8] bytes must be 0x20. The 7th
++  // checksum byte (0x9a) byte is initialized to 0 above hence initialize
++  // 'check' value to 0x20 in order to compensate for that.
++  int check = 0x20;
+   for( uint j = 0; j < 0x200; ++j )
+-    check += buffer[j];
++    check += (unsigned char) buffer[j]; // checksum must use unsigned arithmetic
+   s = QByteArray::number( check, 8 ); // octal
+   s = s.rightJustified( 6, '0' );
+   memcpy( buffer + 0x94, s.constData(), 6 );
diff --git a/debian/patches/series b/debian/patches/series
index d9a33e2..ca529c8 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -21,3 +21,4 @@
 cve_2011_1168_konqueror_xss.diff
 cve_2010_3170_cn_wildcards.diff
 cve_2011_1094_ssl_verify_hostname.diff
+ktar_header_checksum_fix.diff

-- 
KDE Development Platform Libraries module packaging



More information about the pkg-kde-commits mailing list