[dpkg] 63/200: dpkg: Allow readlink(2) returning a size smaller than stat(2)

Ximin Luo infinity0 at debian.org
Wed Apr 5 15:17:17 UTC 2017


This is an automated email from the git hooks/post-receive script.

infinity0 pushed a commit to branch master
in repository dpkg.

commit 232c13c84b5d3c47f8319ea6f9adc8cc3ee71eda
Author: Guillem Jover <guillem at debian.org>
Date:   Sun Dec 4 22:58:45 2016 +0100

    dpkg: Allow readlink(2) returning a size smaller than stat(2)
    
    Some bogus filesystems do not return the actual symlink size in st_size,
    which contradicts POSIX. But allowing the case where the returned size
    is smaller than the one used to allocate memory is harmless, although
    suspect. Let it through, but still print a warning so that users can
    install stuff but are reminded they need to get a fixed filesystem in
    place.
    
    This has affected at least ecryptfs in the past and now file-based
    encryption support in ext4 on Android N.
    
    Reported-by: Jay Freeman <saurik at saurik.com>
---
 debian/changelog |  8 ++++++++
 src/archives.c   | 10 ++++++++--
 src/configure.c  |  5 ++++-
 3 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index a58dbec..3f51ec4 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -18,6 +18,14 @@ dpkg (1.18.16) UNRELEASED; urgency=medium
   * Use the new dpkg --validate-version command in dpkg-maintscript-helper,
     instead of abusing the --compare-versions command to perform version
     validation. Closes: #844701
+  * Allow readlink(2) to return a size smaller than stat(2) in dpkg. Some
+    bogus filesystems do not return the actual symlink size in st_size,
+    which contradicts POSIX. But allowing the case where the returned size
+    is smaller than the one used to allocate memory is harmless, although
+    suspect. Let it through, but still print a warning so that users can
+    install stuff but are reminded they need to get a fixed filesystem in
+    place. This has affected at least ecryptfs in the past and now
+    file-based encryption support in ext4 on Android N.
   * Perl modules:
     - Whitelist DPKG_GENSYMBOLS_CHECK_LEVEL, DPKG_ROOT, DPKG_ADMINDIR and
       DPKG_DATADIR environment variables in Dpkg::Build::Info.
diff --git a/src/archives.c b/src/archives.c
index 94e0411..840dd29 100644
--- a/src/archives.c
+++ b/src/archives.c
@@ -546,9 +546,12 @@ tarobject_matches(struct tarcontext *tc,
     linksize = readlink(fn_old, linkname, stab->st_size + 1);
     if (linksize < 0)
       ohshite(_("unable to read link '%.255s'"), fn_old);
-    else if (linksize != stab->st_size)
+    else if (linksize > stab->st_size)
       ohshit(_("symbolic link '%.250s' size has changed from %jd to %zd"),
              fn_old, (intmax_t)stab->st_size, linksize);
+    else if (linksize < stab->st_size)
+      warning(_("symbolic link '%.250s' size has changed from %jd to %zd"),
+             fn_old, (intmax_t)stab->st_size, linksize);
     linkname[linksize] = '\0';
     if (strcmp(linkname, te->linkname) == 0) {
       free(linkname);
@@ -1033,9 +1036,12 @@ tarobject(void *ctx, struct tar_entry *ti)
       r = readlink(fnamevb.buf, symlinkfn.buf, symlinkfn.size);
       if (r < 0)
         ohshite(_("unable to read link '%.255s'"), ti->name);
-      else if (r != stab.st_size)
+      else if (r > stab.st_size)
         ohshit(_("symbolic link '%.250s' size has changed from %jd to %zd"),
                fnamevb.buf, (intmax_t)stab.st_size, r);
+      else if (r < stab.st_size)
+        warning(_("symbolic link '%.250s' size has changed from %jd to %zd"),
+               fnamevb.buf, (intmax_t)stab.st_size, r);
       varbuf_trunc(&symlinkfn, r);
       varbuf_end_str(&symlinkfn);
       if (symlink(symlinkfn.buf,fnametmpvb.buf))
diff --git a/src/configure.c b/src/configure.c
index 36b0430..029188d 100644
--- a/src/configure.c
+++ b/src/configure.c
@@ -761,7 +761,10 @@ conffderef(struct pkginfo *pkg, struct varbuf *result, const char *in)
 				warning(_("symbolic link '%.250s' size has "
 				          "changed from %jd to %zd"),
 				        result->buf, (intmax_t)stab.st_size, r);
-				return -1;
+				/* If the returned size is smaller, let's
+				 * proceed, otherwise error out. */
+				if (r > stab.st_size)
+					return -1;
 			}
 			varbuf_trunc(&target, r);
 			varbuf_end_str(&target);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/dpkg.git



More information about the Reproducible-commits mailing list