[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#745866: FileFd::Size failure on all big-endian architectures (patch attached)



Hi,

On Fri, Apr 25, 2014 at 07:49:17PM -0600, Adam Conrad wrote:
> Package: apt
> Version: 1.0.2
> Severity: serious
> Tags: patch
> Justification: fails to build from source (but built successfully in the past)

The testcase failing the build is new (in this form), so this bug exists
for a longer time (in the "somewhere between 2011 and 2013" ballpark)
and is "just" detected now.
(I didn't thought writing it would pay off so early and now it found
 three bugs/oddities already…)


Effected are only operations which act on a gzip compressed file
directly asking for the content size, uncompressing them first ist fine
as well as just reading from the file.

The only default configuration using this was pdiff, which might be the
reason why nobody has found this so far in Ubuntu/Debian (stable) as
pdiffs do not exist there and even on Debian unstable you have the
chance to never see it if you can spare enough memory (The size was used
to request a mmap of this size). Add to it that even pdiff isn't affected
anymore since the rewrite at the beginning of the year (it still does
the uncompressing on the fly, but doesn't use an mmap anymore).


> This patch should be fairly self-explanatory for people who grok
> binary math and endian flips.  Fixes the FTBFS on big-endian arches.

After a bit of talking on IRC, we agreed that both patches and than some
should be applied. Beside that it hopefully still fixes the build
(testers welcome to confirm), it also removes the dependency on binary
math and endian flip grokking – and even reduces codesize. ;)


Best regards

David Kalnischkies
commit 05eab8afb692823f86c53c4c2ced783a7c185cf9
Author: Adam Conrad <adconrad@debian.org>
Date:   Sat Apr 26 10:24:40 2014 +0200

    fix FileFd::Size bitswap on big-endian architectures
    
    gzip only gives us 32bit of size, storing it in a 64bit container and
    doing a 32bit flip on it has therefore unintended results.
    So we just go with a exact size container and let the flipping be handled
    by eglibc provided le32toh removing our #ifdef machinery.
    
    Closes: 745866

diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index de73a7f..b77c7ff 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -58,13 +58,10 @@
 	#include <bzlib.h>
 #endif
 #ifdef HAVE_LZMA
-	#include <stdint.h>
 	#include <lzma.h>
 #endif
-
-#ifdef WORDS_BIGENDIAN
-#include <inttypes.h>
-#endif
+#include <endian.h>
+#include <stdint.h>
 
 #include <apti18n.h>
 									/*}}}*/
@@ -1880,19 +1877,13 @@ unsigned long long FileFd::Size()
 	  FileFdErrno("lseek","Unable to seek to end of gzipped file");
 	  return 0;
        }
-       size = 0;
+       uint32_t size = 0;
        if (read(iFd, &size, 4) != 4)
        {
 	  FileFdErrno("read","Unable to read original size of gzipped file");
 	  return 0;
        }
-
-#ifdef WORDS_BIGENDIAN
-       uint32_t tmp_size = size;
-       uint8_t const * const p = (uint8_t const * const) &tmp_size;
-       tmp_size = (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
-       size = tmp_size;
-#endif
+       size = le32toh(size);
 
        if (lseek(iFd, oldPos, SEEK_SET) < 0)
        {

Attachment: signature.asc
Description: Digital signature


Reply to: