linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Tyler Hicks <tyhicks@canonical.com>
To: Yann Droneaud <ydroneaud@opteya.com>
Cc: ecryptfs@vger.kernel.org, linux-fsdevel@vger.kernel.org
Subject: Re: ecryptfs_privileged_open(): when kthread-ecryptfs is required ?
Date: Mon, 26 May 2014 15:53:36 +0200	[thread overview]
Message-ID: <20140526135336.GA21624@boyd> (raw)
In-Reply-To: <1400855045.23090.25.camel@localhost.localdomain>

[-- Attachment #1: Type: text/plain, Size: 4726 bytes --]

On 2014-05-23 16:24:05, Yann Droneaud wrote:
> Hi,
> 
> While trying to investigate why using ecryptfs is painfully sluggish,

When is it painfully sluggish for you?

The two biggest pain points, off of the top of my head, are:

 1) Extending a file to a much larger size is slow because pages of
    zeros are encrypted in the process

 2) Utils such as find and ls are slow when dealing with large numbers
    of files because, during lookups, the eCryptfs metadata has to be
    read from the front of each lower file in order to fill the eCryptfs
    inode

> I've find a piece of code that, I believed at first, wouldn't scale.
> 
> After adding some printk() there, I've found that it's not at all 
> called in my use case.
> So I wonder: what's making  ecryptfs_privileged_open()[1] submit work 
> to ecryptfs-kthread thread running ecryptfs_threadfn()[2] ?
> 
> [1]
> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/ecryptfs/kthread.c#n155
> 
> [2]
> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/ecryptfs/kthread.c#n56

This change (746f1e55) happened before my time of maintaining eCryptfs,
but we can piece together the reasoning...

Assume that an eCryptfs mount, /upper, is mounted on /lower and keep in
mind that there is only ever one lower file opened for all open eCryptfs
files that correspond to the lower inode. So, if two processes have open
file descriptors for /upper/foo, then /lower/foo is only opened once by
the eCryptfs and a pointer to the lower file struct is attached to the
eCryptfs inode's private data.

Since there's only ever one lower file opened for a given lower inode,
it must be opened as O_RDWR to satisfy all future open()s of the
eCryptfs file, as one of those future eCryptfs open()s may be O_RDWR.

The last paragraph of the 746f1e55 commit message, indicates that the
kthread was intended to work around DAC issues when opening the lower
file. That may have been the case back then, but it isn't the case now.
Today, dentry_open() succeeds even when the lower inode isn't writeable
by the current process.

Following the dentry_open() code path, I see that security_file_open()
is called from do_dentry_open(). That means that even though the kthread
is no longer needed from a DAC standpoint, it is still needed from the
LSM standpoint. I'll use AppArmor for a simple demonstration:

 1) Create a profile, "test", that grants access to all files but then
    revokes write permissions to /lower/foo
  
    $ echo "profile test { file, deny file /lower/foo w, }" | \
       sudo apparmor_parser -rq

 2) Create an eCryptfs the file
    - eCryptfs will create the lower file

    $ touch /upper/foo

 3) Open the eCryptfs file with O_RDONLY
    - It will succeed

    $ cat /upper/foo

 4) Open the eCryptfs file with O_RDONLY, while confined
    - It should succeed due to falling back to ecryptfs-kthread

    $ aa-exec -p test -- cat /upper/foo

 5) Remove the ecryptfs-kthread code, recompile the eCryptfs module,
    load the new module and set up the eCryptfs mount again

 6) Repeat step #4
    - It will fail this time since there's no ecryptfs-kthread

    $ aa-exec -p test -- cat /upper/foo
    cat: /upper/foo: Permission denied

 7) Note the eCryptfs error messages in the syslog

    [ 3395.362511] Error opening lower file for lower_dentry [0xffff88007461c288] and lower_mnt [0xffff88007a105420]; rc = [-13]
    [ 3395.375967] ecryptfs_open: Error attempting to initialize the lower file for the dentry with name [foo]; rc = [-13]

> BTW, I have a patch that remove this kernel thread as I think
> credentials can be given to dentry_open(), so instead of running an
> helper kthread, some privileged credentials can be given to
> dentry_open() in the case ecryptfs_privileged_open() really need to 
> open a file read/write. But as I'm not able to verify it's working as 
> expected, I'm holding such trival patch.

This made me think of a patch set from years ago that, unfortunately,
went unreviewed:

  https://lkml.org/lkml/2011/4/29/104

I think Roberto probably had the right idea. By default, all lower
inodes are opened using a cred that was set up at eCryptfs mount time.
Optionally, an eCryptfs mount option can be given to specify the LSM
security context that should be used when opening the lower inodes.

Would you have any interest in reviving that patch set?

If so, note that although I used AppArmor in my example above, you'd
need to use SELinux or SMACK to test the ecryptfs_security_ctx mount
option since AppArmor doesn't have support for
set_security_override_from_ctx().

Tyler

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

      reply	other threads:[~2014-05-26 13:53 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-23 14:24 ecryptfs_privileged_open(): when kthread-ecryptfs is required ? Yann Droneaud
2014-05-26 13:53 ` Tyler Hicks [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140526135336.GA21624@boyd \
    --to=tyhicks@canonical.com \
    --cc=ecryptfs@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=ydroneaud@opteya.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).