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);