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

Bug#725483: apt: libapt-inst fails with >2G debs



Package: apt
Version: 0.9.11.4
Severity: important
Tags: lfs patch

Hi,

Whilst doing some dak testing with large (fake) debs for
data.debian.org, I came across an issue with the following test code:

=============
#!/usr/bin/python

import apt_inst
deb = apt_inst.DebFile('/home/mark/bigdeb.deb')
deb.control.extractall('/home/mark/testex')
deb.data.extractall('/home/mark/testex')
=============

mark@mhy-sid:~$ ls -l bigdeb.deb 
-rw-r--r-- 2 mark mark 2147595076 Oct  5 11:31 bigdeb.deb

On sid-amd64, we get the following:
=============
mark@wheezy-amd64:~$ python
Python 2.7.3 (default, Jan  2 2013, 13:56:14) 
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import apt_inst
>>> deb = apt_inst.DebFile('bigdeb.deb')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  SystemError: E:Unable to seek ahead 2147592128
=============

On sid-i386, we get the following:
=============
mark@mhy-sid:~$ python test.py 
Traceback (most recent call last):
  File "test.py", line 4, in <module>
      deb = apt_inst.DebFile('/home/mark/bigdeb.deb')
      SystemError: E:Failed to read the archive headers
=============

Both of which point to LFS issues in parts of apt.  I've traced this
back to bugs in arfile.cc and fileutl.cc.  This bug also exists in
wheezy (and squeeze, although I don't think we need to fix that).

Attached are two patches - one for the version of apt in sid, one for
wheezy which fix the problem - I've checked that we can then extract the
control and data members properly with these fixes and it seems to work
fine.

I'm not an expert C++ programmer so I'd appreciate someone reviewing
these patches to see if they're sane.  Assuming the patches are
acceptable, from the ftpmaster point of view, we probably need to talk
to the stable team about getting this patched in stable too because dak
uses the python-apt bindings (which in turn use libapt-inst and
libapt-pkg) and as franck.d.o runs stable, we'll need this fixing to get
data.d.o up and running.

As far as I can see, these patches don't cause any ABI changes to the
libraries.

Thanks,

Mark

-- Package-specific info:

-- (no /etc/apt/preferences present) --


-- (/etc/apt/sources.list present, but not submitted) --


-- System Information:
Debian Release: jessie/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: amd64 (x86_64)

Kernel: Linux 3.2.0-4-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages apt depends on:
ii  debian-archive-keyring  2012.4
ii  gnupg                   1.4.14-1
ii  libapt-pkg4.12          0.9.11.4
ii  libc6                   2.17-93
ii  libgcc1                 1:4.8.1-10
ii  libstdc++6              4.8.1-10

apt recommends no packages.

Versions of packages apt suggests:
pn  apt-doc     <none>
ii  aptitude    0.6.8.2-1.2
ii  dpkg-dev    1.17.1
ii  python-apt  0.8.9.1+b1
ii  xz-utils    5.1.1alpha+20120614-2

-- no debconf information
diff --git a/apt-inst/contrib/arfile.cc b/apt-inst/contrib/arfile.cc
index 2dee1a4..b77c77d 100644
--- a/apt-inst/contrib/arfile.cc
+++ b/apt-inst/contrib/arfile.cc
@@ -64,7 +64,7 @@ ARArchive::~ARArchive()
    byte plain text header then the file data, another header, data, etc */
 bool ARArchive::LoadHeaders()
 {
-   signed long Left = File.Size();
+   off_t Left = File.Size();
    
    // Check the magic byte
    char Magic[8];
@@ -120,7 +120,7 @@ bool ARArchive::LoadHeaders()
       }
 
       // Account for the AR header alignment 
-      unsigned Skip = Memb->Size % 2;
+      off_t Skip = Memb->Size % 2;
       
       // Add it to the list
       Memb->Next = List;
@@ -128,7 +128,7 @@ bool ARArchive::LoadHeaders()
       Memb->Start = File.Tell();
       if (File.Skip(Memb->Size + Skip) == false)
 	 return false;
-      if (Left < (signed)(Memb->Size + Skip))
+      if (Left < (off_t)(Memb->Size + Skip))
 	 return _error->Error(_("Archive is too short"));
       Left -= Memb->Size + Skip;
    }   
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index 90e49cb..136a9d7 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -650,9 +650,9 @@ string flNoLink(string File)
    while (1)
    {
       // Read the link
-      int Res;
+      ssize_t Res;
       if ((Res = readlink(NFile.c_str(),Buffer,sizeof(Buffer))) <= 0 || 
-	  (unsigned)Res >= sizeof(Buffer))
+	  (size_t)Res >= sizeof(Buffer))
 	  return File;
       
       // Append or replace the previous path
@@ -1221,7 +1221,7 @@ FileFd::~FileFd()
    gracefully. */
 bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual)
 {
-   int Res;
+   ssize_t Res;
    errno = 0;
    if (Actual != 0)
       *Actual = 0;
@@ -1323,7 +1323,7 @@ char* FileFd::ReadLine(char *To, unsigned long long const Size)
 /* */
 bool FileFd::Write(const void *From,unsigned long long Size)
 {
-   int Res;
+   ssize_t Res;
    errno = 0;
    do
    {
@@ -1379,7 +1379,7 @@ bool FileFd::Write(const void *From,unsigned long long Size)
 }
 bool FileFd::Write(int Fd, const void *From, unsigned long long Size)
 {
-   int Res;
+   ssize_t Res;
    errno = 0;
    do
    {
@@ -1458,14 +1458,14 @@ bool FileFd::Seek(unsigned long long To)
       d->seekpos = To;
       return true;
    }
-   int res;
+   off_t res;
 #ifdef HAVE_ZLIB
    if (d != NULL && d->gz)
       res = gzseek(d->gz,To,SEEK_SET);
    else
 #endif
       res = lseek(iFd,To,SEEK_SET);
-   if (res != (signed)To)
+   if (res != (off_t)To)
    {
       Flags |= Fail;
       return _error->Error("Unable to seek to %llu", To);
@@ -1502,7 +1502,7 @@ bool FileFd::Skip(unsigned long long Over)
       return true;
    }
 
-   int res;
+   off_t res;
 #ifdef HAVE_ZLIB
    if (d != NULL && d->gz != NULL)
       res = gzseek(d->gz,Over,SEEK_CUR);
diff --git a/apt-inst/contrib/arfile.cc b/apt-inst/contrib/arfile.cc
index d7ee528..9d84c17 100644
--- a/apt-inst/contrib/arfile.cc
+++ b/apt-inst/contrib/arfile.cc
@@ -64,7 +64,7 @@ ARArchive::~ARArchive()
    byte plain text header then the file data, another header, data, etc */
 bool ARArchive::LoadHeaders()
 {
-   signed long Left = File.Size();
+   off_t Left = File.Size();
    
    // Check the magic byte
    char Magic[8];
@@ -123,7 +123,7 @@ bool ARArchive::LoadHeaders()
       }
 
       // Account for the AR header alignment 
-      unsigned Skip = Memb->Size % 2;
+      off_t Skip = Memb->Size % 2;
       
       // Add it to the list
       Memb->Next = List;
@@ -131,7 +131,7 @@ bool ARArchive::LoadHeaders()
       Memb->Start = File.Tell();
       if (File.Skip(Memb->Size + Skip) == false)
 	 return false;
-      if (Left < (signed)(Memb->Size + Skip))
+      if (Left < (off_t)(Memb->Size + Skip))
 	 return _error->Error(_("Archive is too short"));
       Left -= Memb->Size + Skip;
    }   
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index 3966eb0..0261119 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -656,9 +656,9 @@ string flNoLink(string File)
    while (1)
    {
       // Read the link
-      int Res;
+      ssize_t Res;
       if ((Res = readlink(NFile.c_str(),Buffer,sizeof(Buffer))) <= 0 || 
-	  (unsigned)Res >= sizeof(Buffer))
+	  (size_t)Res >= sizeof(Buffer))
 	  return File;
       
       // Append or replace the previous path
@@ -1244,7 +1244,7 @@ FileFd::~FileFd()
    gracefully. */
 bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual)
 {
-   int Res;
+   ssize_t Res;
    errno = 0;
    if (Actual != 0)
       *Actual = 0;
@@ -1344,7 +1344,7 @@ char* FileFd::ReadLine(char *To, unsigned long long const Size)
 /* */
 bool FileFd::Write(const void *From,unsigned long long Size)
 {
-   int Res;
+   ssize_t Res;
    errno = 0;
    do
    {
@@ -1398,7 +1398,7 @@ bool FileFd::Write(const void *From,unsigned long long Size)
 }
 bool FileFd::Write(int Fd, const void *From, unsigned long long Size)
 {
-   int Res;
+   ssize_t Res;
    errno = 0;
    do
    {
@@ -1471,14 +1471,14 @@ bool FileFd::Seek(unsigned long long To)
       d->seekpos = To;
       return true;
    }
-   int res;
+   off_t res;
 #ifdef HAVE_ZLIB
    if (d != NULL && d->gz)
       res = gzseek(d->gz,To,SEEK_SET);
    else
 #endif
       res = lseek(iFd,To,SEEK_SET);
-   if (res != (signed)To)
+   if (res != (off_t)To)
       return FileFdError("Unable to seek to %llu", To);
 
    if (d != NULL)
@@ -1509,7 +1509,7 @@ bool FileFd::Skip(unsigned long long Over)
       return true;
    }
 
-   int res;
+   off_t res;
 #ifdef HAVE_ZLIB
    if (d != NULL && d->gz != NULL)
       res = gzseek(d->gz,Over,SEEK_CUR);

Reply to: