ecryptfs breaks lstat/readlink size assumption

Bug #524919 reported by Loïc Minier
50
This bug affects 9 people
Affects Status Importance Assigned to Milestone
Ubuntu Customization Kit
Won't Fix
Undecided
Unassigned
eCryptfs
Fix Released
Medium
Tyler Hicks
dpkg (Ubuntu)
Won't Fix
Undecided
Unassigned
Lucid
Won't Fix
Undecided
Unassigned
linux (Ubuntu)
Fix Released
High
Ubuntu Kernel Team
Lucid
Fix Released
High
Ubuntu Kernel Team

Bug Description

Hi

When running dpkg on an ecryptfs partition, I'm hitting assertion failures in dpkg; in this example I'm creating an i386 chroot in my home under lucid amd64:
sudo debootstrap --variant=buildd --arch i386 lucid lucid
[...]

I: Extracting tzdata...
I: Extracting udev...
I: Extracting upstart...
I: Extracting util-linux...
I: Extracting zlib1g...
I: Installing core packages...
W: Failure trying to run: chroot /home/lool/uml/lucid dpkg --force-depends --install /var/cache/apt/archives/base-files_5.0.0ubuntu10_i386.deb /var/cache/apt/archives/base-passwd_3.5.22_i386.deb

Running the above command manually:
sudo chroot /home/lool/uml/lucid dpkg --force-depends --install /var/cache/apt/archives/base-files_5.0.0ubuntu10_i386.deb /var/cache/apt/archives/base-passwd_3.5.22_i386.deb
dpkg: regarding .../base-files_5.0.0ubuntu10_i386.deb containing base-files, pre-dependency problem:
 base-files pre-depends on awk
  awk is not installed.
dpkg: warning: ignoring pre-dependency problem!
(Reading database ... 50%
dpkg: warning: files list file for package `base-files' missing, assuming package has no files currently installed.
(Reading database ... 0 files and directories currently installed.)
Preparing to replace base-files 5.0.0ubuntu10 (using .../base-files_5.0.0ubuntu10_i386.deb) ...
Unpacking replacement base-files ...
dpkg: ../../src/archives.c:754: tarobject: Assertion `r == stab.st_size' failed.
zsh: abort (core dumped) sudo chroot /home/lool/uml/lucid dpkg --force-depends --install

I checked the dpkg source code, and in src/archives.c:tarobject() it does:
statr= lstat(fnamevb.buf,&stab);
[...]
      r = readlink(fnamevb.buf, symlinkfn.buf, symlinkfn.size);
[...]
      assert(r == stab.st_size);

The lstat() manpage states that:
       The st_size field gives the size of the file (if it is a regular file
       or a symbolic link) in bytes. The size of a symlink is the length of
       the pathname it contains, without a trailing null byte.

and the readlink manpage:
RETURN VALUE
       On success, readlink() returns the number of bytes placed in buf. On
       error, -1 is returned and errno is set to indicate the error.

I believe that ecryptfs is returning the sizes of the backing filesystem objects instead of the sizes of the unencrypted data; this can only break applications IMO since read()/write() is going to return less bytes than the reported (stat()) length.

Thanks,

Revision history for this message
Loïc Minier (lool) wrote :

I think the regression was caused by the fix for bug #390833.

Changed in linux (Ubuntu):
importance: Undecided → High
assignee: nobody → Ubuntu Kernel Team (ubuntu-kernel-team)
Changed in linux (Ubuntu Lucid):
assignee: nobody → Ubuntu Kernel Team (ubuntu-kernel-team)
Revision history for this message
Dustin Kirkland  (kirkland) wrote :

Argh, what a mess...

Well, bug #390833 has a work around, albeit inconvenient. ie, users must use du --apparent-size ...

I'm CC'ing Tyler here, since he's the author of the upstream patch and will want to know about this.

Changed in linux (Ubuntu Lucid):
status: New → Confirmed
Revision history for this message
Tyler Hicks (tyhicks) wrote :

I don't believe this is a regression caused by the fix in bug #390833. The only change that fix made was to the st_blocks field of the stat struct.

The problem that Loïc is seeing is that return value of readlink() and st_size don't match. As far as I can tell, that has always been the case since the inception of the encrypted filename feature in eCryptfs. The reason is that when we create a symbolic link, we have to store the encrypted version of the target path in the sym link file. However, when readlink() is called we decrypt that path and return the unencrypted path, resulting in a difference in readlink()'s return value and the reported st_size of the sym link file.

Loïc, have you been able to successfully use dpkg inside your eCryptfs partition (with encrypted filenames enabled) before? My guess is that either no one has tried this before or the 'assert(r == stab.st_size);' is relatively new.

Revision history for this message
Loïc Minier (lool) wrote :

Yes, I was running it fine a couple days of earlier, but we did get a dpkg update on 14 Feb.

The assert was committed on Sep 2009 in dpkg:
- do {
- varbufextend(&symlinkfn);
- r= readlink(fnamevb.buf,symlinkfn.buf,symlinkfn.size);
- if (r<0) ohshite(_("unable to read link `%.255s'"),ti->Name);
- } while ((size_t)r == symlinkfn.size);
+ varbuf_grow(&symlinkfn, stab.st_size + 1);
+ r = readlink(fnamevb.buf, symlinkfn.buf, symlinkfn.size);
+ if (r < 0)
+ ohshite(_("unable to read link `%.255s'"), ti->Name);
+ assert(r == stab.st_size);

commit 353b02acb33224bc2d7e3b0295538d592b9c8bad
Author: Guillem Jover <email address hidden>
Date: Wed Sep 30 03:10:27 2009 +0200

    dpkg: Use stat size to varbuf_grow the buffer for readlink

    Do not expand the buffer indefinitely by trying several times until
    the buffer is big enough. Pre-allocate just once using varbuf_grow
    with the known size from stat.

that said, I find it hard to blame the dpkg developers for assuming that behavior given that it's the documented one.

Wouldn't it make more sense to consistently return unencrypted sizes/metadata for all syscalls on ecryptfs files?

Revision history for this message
Tyler Hicks (tyhicks) wrote : Re: [Bug 524919] Re: ecryptfs breaks lstat/readlink size assumption

On 02/26/2010 02:58 AM, Loïc Minier wrote:
> Wouldn't it make more sense to consistently return unencrypted
> sizes/metadata for all syscalls on ecryptfs files?

I agree with you. I think it is reasonable to check if the file is a
symlink and then attempt to decrypt the target. If that's successful,
return the length of the decrypted target.

Tyler Hicks (tyhicks)
Changed in ecryptfs:
assignee: nobody → Tyler Hicks (tyhicks)
importance: Undecided → Medium
status: New → Triaged
Revision history for this message
Josef Spillner (josefspillner) wrote :

Is anybody working on a patch already? I've just been hit by this issue as well. My poor workaround is to run the debootstrap in /tmp.

tags: added: kernel-series-unknown
Revision history for this message
Salvatore Iovene (salvatore-launchpad) wrote :

I'm affected by this in Ubuntu Karmic. I run scratchbox <http://www.scratchbox.org/> in an encrypted partitions, and dpkg 1.15.5.5+maemo3+0m6 fails with the same error. I run ecryptfs 81-0ubuntu3.

Tyler Hicks (tyhicks)
Changed in ecryptfs:
status: Triaged → In Progress
Revision history for this message
Tyler Hicks (tyhicks) wrote :
Changed in ecryptfs:
status: In Progress → Fix Released
Revision history for this message
Dustin Kirkland  (kirkland) wrote :

So this should be fixed in Ubuntu Maverick (or if we cherrypick this fix from -stable) for Lucid.

Revision history for this message
Tim Gardner (timg-tpi) wrote :

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3a60a1686f0d51c99bd0df8ac93050fb6dfce647 has been queued for 2.6.32 stable updates and will be picked up in Lucid in due course.

Revision history for this message
Pascal de Bruijn (pmjdebruijn) wrote :

This is still a problem in Lucid-rc

Revision history for this message
tankdriver (stoneraider-deactivatedaccount) wrote :

Users of UbuntuCustomizationKit with "encrypted home" might have similar problems. Bug #567945 eventually could be a duplicate of this bug.

Revision history for this message
Pascal de Bruijn (pmjdebruijn) wrote :

Indeed, that's how I noticed this problem. UCK does not work on eCryptfs homedirs...

Revision history for this message
GerhardGaußling (ggrubbish-web) wrote :

Is this also a Problem on ntfs mounts?
I ask this because I get in huge trouble on a hardy->lucid do-release-upgrade -m desktop -d, I think now due to a move of the /usr/share/doc to a ntfs partition because I had not enough space in /usr for the upgrade.
I symlinked the doc-folder on the ntfs partitition to /usr/share/doc then.

Here is the bug report:
https://bugs.launchpad.net/ubuntu/+source/dpkg/+bug/573696

Revision history for this message
Fabrizio Balliano (fabrizio-balliano) wrote :

this seems not to be a UCK bug to me

Changed in uck:
status: New → Won't Fix
Changed in dpkg (Ubuntu):
status: New → Won't Fix
Changed in dpkg (Ubuntu Lucid):
status: New → Won't Fix
Revision history for this message
Tim Gardner (timg-tpi) wrote :

Fix released in Lucid since Ubuntu-2.6.32-23.37

Changed in linux (Ubuntu):
status: Confirmed → Fix Released
Changed in linux (Ubuntu Lucid):
status: Confirmed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.