← Back to team overview

kernel-packages team mailing list archive

[Bug 1305335] Re: Cutting or copying files on btrfs to ecryptfs results in data loss

 

As a follow-up to comment #16: generally attempting to clone a  file in
a non-ecryptfs folder into a mounted ecryptfs folder appears to succeed
but in fact creates a zero-length invalid target file, but going the
other way (cloning from the mounted ecryptfs folder into the non-
ecryptfs folder) fails as it should. (Both cp --reflink=auto and glib's
file_copy_fallback try a clone operation and then try a non-clone
operation if this fails, so this second case is fine.)

The attached script demonstrates both cases by creating a mounted
ecryptfs system in /tmp/ecryptfs-test and using the folder 'private' to
hold the 'lower' encrypted ecryptfs files and the folder 'plaintext' as
the 'higher' mounted ecryptfs folder and then trying the clone operation
in both directions. ( /tmp must be on a btrfs partition and you need at
least ecryptfs-utils installed but you don't need an encrypted home
folder.)

The btrfs_ioctl_clone command (in fs/btrfs/ioctl.c in the kernel source)
is designed to only perform a clone if the source and dest files have
the same VFS mountpoint and to fail with EXDEV (invalid cross-device
link) if they don't:

ret = -EXDEV;
if (src_file.file->f_path.mnt != file->f_path.mnt)
  goto out_fput;

When trying to clone from the 'plaintext' folder into /tmp/ecryptfs-
test, this test fails (the mountpoints are represented by two different
dentries, '@' and '/').

However, when cloning into the 'plaintext' folder, btrfs_ioctl_clone is
actually being asked to clone using the 'lower' ecryptfs file as the
target (ie the target points to the 'private' folder, not the
'plaintext' folder), so the test passes. This is obviously wrong -
ecryptfs is designed so that the information gets directed to the
'plaintext' folder, intercepted in the kernel, and stored encrypted
instead in the 'private' folder.

To demonstrate this, I added this code just before the test:

	{
    #define BUFLEN 256
	char src_path[BUFLEN],dest_path[BUFLEN];
	int i;
	for (i=0;i<BUFLEN;++i) src_path[i]=dest_path[i]=0;    
	
	printk(KERN_INFO "btrfs reflink src: %s [mnt %s], dest: %s [mnt %s]\n", 
	  dentry_path_raw(src_file.file->f_path.dentry, src_path, BUFLEN),
	  src_file.file->f_path.mnt->mnt_root->d_iname, 
	  dentry_path_raw(file->f_path.dentry, dest_path, BUFLEN),
	  file->f_path.mnt->mnt_root->d_iname
	);
    }

With that code included in the kernel, the syslog shows something like
this after running the attached test script:

... btrfs reflink src: /@/tmp/ecryptfs-test/test [mnt @], dest: /@/tmp
/ecryptfs-test/private/ECRYPTFS_FNEK_ENCRYPTED... [mnt @]

ie the target file passed to btrfs_ioctl_clone is the 'lower' file in
'private'. (Note that after the clone, trying to access this file
results in an I/O error.)

I checked the cp code, and it calls:

return ioctl (dest_fd, BTRFS_IOC_CLONE, src_fd);

I used readlink to get the file path for dest_fd from
/proc/self/fd/<file desriptor>, and it returned "/tmp/ecryptfs-
test/plaintext/test", so desc_fd in the cp command is pointing to the
correct path for the 'higher' file.

My guess is that ecryptfs intercepts this 'higher' path and converts it
to the 'lower' path before it gets passed through to btrfs, but it
should just do a pass-through for the btrfs clone operation.

** Attachment added: "Script demonstrating the bug"
   https://bugs.launchpad.net/ubuntu/+source/nautilus/+bug/1305335/+attachment/4325528/+files/test-reflink.sh

-- 
You received this bug notification because you are a member of Kernel
Packages, which is subscribed to linux in Ubuntu.
https://bugs.launchpad.net/bugs/1305335

Title:
  Cutting or copying files on btrfs to ecryptfs results in data loss

Status in eCryptfs:
  Confirmed
Status in linux package in Ubuntu:
  Confirmed
Status in nautilus package in Ubuntu:
  Confirmed

Bug description:
  I've installed a fresh copy of 14.04 beta 2 on a brand-new SSD.  I
  used btrfs as the filesystem.

  I set up a Private folder usying ecryptfs-setup-private.

  I copied a few folders into the Private folder, and the entire
  directory structure and subfolders are copied, including the files
  themselves, yet every file contains 0 bytes.

  However, I can create and save new files in the Private directory.
  Also, folders and files can be correctly copied if I use the command line cp -R.

  Thanks,
  Damon

  ProblemType: Bug
  DistroRelease: Ubuntu 14.04
  Package: nautilus 1:3.10.1-0ubuntu8
  ProcVersionSignature: Ubuntu 3.13.0-23.45-generic 3.13.8
  Uname: Linux 3.13.0-23-generic x86_64
  ApportVersion: 2.14.1-0ubuntu1
  Architecture: amd64
  CurrentDesktop: Unity
  Date: Wed Apr  9 18:12:56 2014
  EcryptfsInUse: Yes
  GsettingsChanges: b'org.gnome.nautilus.list-view' b'default-column-order' b"['name', 'size', 'type', 'date_modified', 'date_accessed', 'owner', 'group', 'permissions', 'mime_type', 'where']"
  InstallationDate: Installed on 2014-04-05 (4 days ago)
  InstallationMedia: Ubuntu 14.04 LTS "Trusty Tahr" - Beta amd64 (20140326)
  ProcEnviron:
   LANGUAGE=en_CA:en
   PATH=(custom, no user)
   XDG_RUNTIME_DIR=<set>
   LANG=en_CA.UTF-8
   SHELL=/bin/bash
  SourcePackage: nautilus
  UpgradeStatus: No upgrade log present (probably fresh install)

To manage notifications about this bug go to:
https://bugs.launchpad.net/ecryptfs/+bug/1305335/+subscriptions