I found the problem. Apache is using sendfile to pipe the contents of a file on disk to the network socket. eCryptfs simply forwards the sendfile request down to the lower filesystem. This results in the lower buffer getting piped through rather than the eCryptfs buffer, so it is obviously the wrong behavior. It's amazing that this hasn't hit anyone's radar until just now.
Fortunately, the fix is trivial: just redirect the eCryptfs sendfile (or splice, depending on your kernel version) file operation to the generic VFS function. This will send through the eCryptfs buffers, using the existing VM machinery to bring eCryptfs pages ``uptodate'' via the decryption execution paths already in place. The 20070911 release has this fix: http://downloads.sourceforge.net/ecryptfs/ecryptfs-20070911.tar.bz2 Here is a patch against 2.6.21; it should apply to 2.6.22 too. A patch against 2.6.23 will be much the same, only set .splice_read to generic_file_splice_read instead. So far I have only tested the 20070911 standalone release; I am in the process of testing the in-kernel fix in preparation for sending the patch upstream. Signed-off-by: Michael Halcrow <[EMAIL PROTECTED]> --- diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 7a7d25d..ea961fa 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c @@ -396,20 +396,6 @@ static int ecryptfs_fasync(int fd, struct file *file, int flag) return rc; } -static ssize_t ecryptfs_sendfile(struct file *file, loff_t * ppos, - size_t count, read_actor_t actor, void *target) -{ - struct file *lower_file = NULL; - int rc = -EINVAL; - - lower_file = ecryptfs_file_to_lower(file); - if (lower_file->f_op && lower_file->f_op->sendfile) - rc = lower_file->f_op->sendfile(lower_file, ppos, count, - actor, target); - - return rc; -} - static int ecryptfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); @@ -422,7 +408,7 @@ const struct file_operations ecryptfs_dir_fops = { .release = ecryptfs_release, .fsync = ecryptfs_fsync, .fasync = ecryptfs_fasync, - .sendfile = ecryptfs_sendfile, + .sendfile = generic_file_sendfile, }; const struct file_operations ecryptfs_main_fops = { @@ -439,7 +425,7 @@ const struct file_operations ecryptfs_main_fops = { .release = ecryptfs_release, .fsync = ecryptfs_fsync, .fasync = ecryptfs_fasync, - .sendfile = ecryptfs_sendfile, + .sendfile = generic_file_sendfile, }; static int --- On Sat, Sep 08, 2007 at 12:09:53PM -0700, Stefan Farestam wrote: > I've investigated a bit more thoroughly into this problem, but I am > still observing the same strange behavior. This time around I used > strace on the apache server process and verified that apache did indeed > only access the unencrypted file ($HOME/b/testfile.txt in the example > below). > > Here is the exact procedure that I have followed: > > * reboot > > * stop any running instances of apache: > % apache2ctl stop > > * delete and recreate the directories $HOME/a and $HOME/b > % rm -rf $HOME/{a,b} > % mkdir $HOME/{a,b} > > * mount the encrypted directory as root (plaintext passthrough disabled): > % mount -t ecryptfs $HOME/{a,b} -o cipher=aes,ecryptfs_key_bytes=32 > > * mtab entry becomes: > % fgrep $HOME/a /etc/mtab > /home/test/a /home/test/b ecryptfs > rw,ecryptfs_sig=4733efbff603498e,ecryptfs_cipher=aes,ecryptfs_key_bytes=32 > 0 0 > > * create testfile > % cat << EOF > $HOME/b/testfile.txt > 123456789-123456789-123456789-123456789-123456789- > 123456789-123456789-123456789-123456789-123456789- > 123456789-123456789-123456789-123456789-123456789- > 123456789-123456789-123456789-123456789-123456789- > 123456789-123456789-123456789-123456789-123456789- > 123456789-123456789-123456789-123456789-123456789- > EOF > > * start apache > % apache2ctl start > > * retrieve file with wget > % wget http://localhost/home/b/testfile.txt > > * check what we have: > % od -c testfile.txt > --- start > 0000000 \0 \0 \0 \0 \0 \0 001 2 360 022 \b + 314 223 277 336 > 0000020 002 \0 \0 002 \0 \0 \0 \0 001 214 - 004 \t 003 001 > 0000040 \0 021 " 3 D U f w ` 336 361 ! s 326 262 220 > 0000060 272 356 h $ 5 : % w 364 d 231 \t 030 200 330 351 > 0000100 t 210 273 324 217 e 366 331 373 355 025 b \b _ C O > 0000120 N S O L E \0 \0 \0 \0 G 3 357 277 366 003 I > 0000140 216 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 > 0000160 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 > * > 0000460 \0 \0 > 0000462 > --- end > > As I have previously noted the behavior appears only when the file is > longer than 255 bytes. > > Variants of the above that I have tried (with the same result): > > * Used algorithms "aes" and "blowfish" > > * Varied blocksize from 32 to 16 > > * Used Ubuntu kernel vmlinuz-2.6.20-16-generic with the > ecryptfs module supplied with that kernel distribution > > * Used custom compiled kernel vmlinuz-2.6.21.7 with kernel supplied > ecryptfs module > > * Used custom compiled kernel vmlinuz-2.6.22.6 with kernel supplied > ecryptfs module > > * Used custom compiled kernel vmlinuz-2.6.23-rc5 with kernel supplied > ecryptfs module > > I would be happy to run any other tests that someone suggests. > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio 2005. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > _______________________________________________ > eCryptfs-users mailing list > eCryptfs-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/ecryptfs-users
pgpJFyI9NURu9.pgp
Description: PGP signature
------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________ eCryptfs-users mailing list eCryptfs-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ecryptfs-users