1. 23 Sep, 2009 8 commits
    • Tyler Hicks's avatar
      eCryptfs: Propagate vfs_read and vfs_write return codes · 96a7b9c2
      Tyler Hicks authored
      Errors returned from vfs_read() and vfs_write() calls to the lower
      filesystem were being masked as -EINVAL.  This caused some confusion to
      users who saw EINVAL instead of ENOSPC when the disk was full, for
      instance.
      
      Also, the actual bytes read or written were not accessible by callers to
      ecryptfs_read_lower() and ecryptfs_write_lower(), which may be useful in
      some cases.  This patch updates the error handling logic where those
      functions are called in order to accept positive return codes indicating
      success.
      
      Cc: Eric Sandeen <esandeen@redhat.com>
      Acked-by: default avatarSerge Hallyn <serue@us.ibm.com>
      Cc: ecryptfs-devel@lists.launchpad.net
      Signed-off-by: default avatarTyler Hicks <tyhicks@linux.vnet.ibm.com>
      96a7b9c2
    • Tyler Hicks's avatar
      eCryptfs: Validate global auth tok keys · 38919598
      Tyler Hicks authored
      When searching through the global authentication tokens for a given key
      signature, verify that a matching key has not been revoked and has not
      expired.  This allows the `keyctl revoke` command to be properly used on
      keys in use by eCryptfs.
      Acked-by: default avatarSerge Hallyn <serue@us.ibm.com>
      Cc: ecryptfs-devel@lists.launchpad.net
      Cc: stable <stable@kernel.org>
      Signed-off-by: default avatarTyler Hicks <tyhicks@linux.vnet.ibm.com>
      38919598
    • Tyler Hicks's avatar
      eCryptfs: Filename encryption only supports password auth tokens · df6ad33b
      Tyler Hicks authored
      Returns -ENOTSUPP when attempting to use filename encryption with
      something other than a password authentication token, such as a private
      token from openssl.  Using filename encryption with a userspace eCryptfs
      key module is a future goal.  Until then, this patch handles the
      situation a little better than simply using a BUG_ON().
      Acked-by: default avatarSerge Hallyn <serue@us.ibm.com>
      Cc: ecryptfs-devel@lists.launchpad.net
      Cc: stable <stable@kernel.org>
      Signed-off-by: default avatarTyler Hicks <tyhicks@linux.vnet.ibm.com>
      df6ad33b
    • Tyler Hicks's avatar
      eCryptfs: Check for O_RDONLY lower inodes when opening lower files · ac22ba23
      Tyler Hicks authored
      If the lower inode is read-only, don't attempt to open the lower file
      read/write and don't hand off the open request to the privileged
      eCryptfs kthread for opening it read/write.  Instead, only try an
      unprivileged, read-only open of the file and give up if that fails.
      This patch fixes an oops when eCryptfs is mounted on top of a read-only
      mount.
      Acked-by: default avatarSerge Hallyn <serue@us.ibm.com>
      Cc: Eric Sandeen <esandeen@redhat.com>
      Cc: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
      Cc: ecryptfs-devel@lists.launchpad.net
      Cc: stable <stable@kernel.org>
      Signed-off-by: default avatarTyler Hicks <tyhicks@linux.vnet.ibm.com>
      ac22ba23
    • Tyler Hicks's avatar
      eCryptfs: Handle unrecognized tag 3 cipher codes · b0105eae
      Tyler Hicks authored
      Returns an error when an unrecognized cipher code is present in a tag 3
      packet or an ecryptfs_crypt_stat cannot be initialized.  Also sets an
      crypt_stat->tfm error pointer to NULL to ensure that it will not be
      incorrectly freed in ecryptfs_destroy_crypt_stat().
      Acked-by: default avatarSerge Hallyn <serue@us.ibm.com>
      Cc: ecryptfs-devel@lists.launchpad.net
      Cc: stable <stable@kernel.org>
      Signed-off-by: default avatarTyler Hicks <tyhicks@linux.vnet.ibm.com>
      b0105eae
    • Dave Hansen's avatar
      ecryptfs: improved dependency checking and reporting · 38268498
      Dave Hansen authored
      So, I compiled a 2.6.31-rc5 kernel with ecryptfs and loaded its module.
      When it came time to mount my filesystem, I got this in dmesg, and it
      refused to mount:
      
      [93577.776637] Unable to allocate crypto cipher with name [aes]; rc = [-2]
      [93577.783280] Error attempting to initialize key TFM cipher with name = [aes]; rc = [-2]
      [93577.791183] Error attempting to initialize cipher with name = [aes] and key size = [32]; rc = [-2]
      [93577.800113] Error parsing options; rc = [-22]
      
      I figured from the error message that I'd either forgotten to load "aes"
      or that my key size was bogus.  Neither one of those was the case.  In
      fact, I was missing the CRYPTO_ECB config option and the 'ecb' module.
      Unfortunately, there's no trace of 'ecb' in that error message.
      
      I've done two things to fix this.  First, I've modified ecryptfs's
      Kconfig entry to select CRYPTO_ECB and CRYPTO_CBC.  I also took CRYPTO
      out of the dependencies since the 'select' will take care of it for us.
      
      I've also modified the error messages to print a string that should
      contain both 'ecb' and 'aes' in my error case.  That will give any
      future users a chance of finding the right modules and Kconfig options.
      
      I also wonder if we should:
      
      	select CRYPTO_AES if !EMBEDDED
      
      since I think most ecryptfs users are using AES like me.
      
      Cc: ecryptfs-devel@lists.launchpad.net
      Cc: linux-fsdevel@vger.kernel.org
      Cc: linux-kernel@vger.kernel.org
      Cc: Dustin Kirkland <kirkland@canonical.com>
      Signed-off-by: default avatarDave Hansen <dave@linux.vnet.ibm.com>
      [tyhicks@linux.vnet.ibm.com: Removed extra newline, 80-char violation]
      Signed-off-by: default avatarTyler Hicks <tyhicks@linux.vnet.ibm.com>
      38268498
    • Roland Dreier's avatar
      eCryptfs: Fix lockdep-reported AB-BA mutex issue · aa06117f
      Roland Dreier authored
      Lockdep reports the following valid-looking possible AB-BA deadlock with
      global_auth_tok_list_mutex and keysig_list_mutex:
      
        ecryptfs_new_file_context() ->
            ecryptfs_copy_mount_wide_sigs_to_inode_sigs() ->
                mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex);
                -> ecryptfs_add_keysig() ->
                    mutex_lock(&crypt_stat->keysig_list_mutex);
      
      vs
      
        ecryptfs_generate_key_packet_set() ->
            mutex_lock(&crypt_stat->keysig_list_mutex);
            -> ecryptfs_find_global_auth_tok_for_sig() ->
                mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex);
      
      ie the two mutexes are taken in opposite orders in the two different
      code paths.  I'm not sure if this is a real bug where two threads could
      actually hit the two paths in parallel and deadlock, but it at least
      makes lockdep impossible to use with ecryptfs since this report triggers
      every time and disables future lockdep reporting.
      
      Since ecryptfs_add_keysig() is called only from the single callsite in
      ecryptfs_copy_mount_wide_sigs_to_inode_sigs(), the simplest fix seems to
      be to move the lock of keysig_list_mutex back up outside of the where
      global_auth_tok_list_mutex is taken.  This patch does that, and fixes
      the lockdep report on my system (and ecryptfs still works OK).
      
      The full output of lockdep fixed by this patch is:
      
      =======================================================
      [ INFO: possible circular locking dependency detected ]
      2.6.31-2-generic #14~rbd2
      -------------------------------------------------------
      gdm/2640 is trying to acquire lock:
       (&mount_crypt_stat->global_auth_tok_list_mutex){+.+.+.}, at: [<ffffffff8121591e>] ecryptfs_find_global_auth_tok_for_sig+0x2e/0x90
      
      but task is already holding lock:
       (&crypt_stat->keysig_list_mutex){+.+.+.}, at: [<ffffffff81217728>] ecryptfs_generate_key_packet_set+0x58/0x2b0
      
      which lock already depends on the new lock.
      
      the existing dependency chain (in reverse order) is:
      
      -> #1 (&crypt_stat->keysig_list_mutex){+.+.+.}:
             [<ffffffff8108c897>] check_prev_add+0x2a7/0x370
             [<ffffffff8108cfc1>] validate_chain+0x661/0x750
             [<ffffffff8108d2e7>] __lock_acquire+0x237/0x430
             [<ffffffff8108d585>] lock_acquire+0xa5/0x150
             [<ffffffff815526cd>] __mutex_lock_common+0x4d/0x3d0
             [<ffffffff81552b56>] mutex_lock_nested+0x46/0x60
             [<ffffffff8121526a>] ecryptfs_add_keysig+0x5a/0xb0
             [<ffffffff81213299>] ecryptfs_copy_mount_wide_sigs_to_inode_sigs+0x59/0xb0
             [<ffffffff81214b06>] ecryptfs_new_file_context+0xa6/0x1a0
             [<ffffffff8120e42a>] ecryptfs_initialize_file+0x4a/0x140
             [<ffffffff8120e54d>] ecryptfs_create+0x2d/0x60
             [<ffffffff8113a7d4>] vfs_create+0xb4/0xe0
             [<ffffffff8113a8c4>] __open_namei_create+0xc4/0x110
             [<ffffffff8113d1c1>] do_filp_open+0xa01/0xae0
             [<ffffffff8112d8d9>] do_sys_open+0x69/0x140
             [<ffffffff8112d9f0>] sys_open+0x20/0x30
             [<ffffffff81013132>] system_call_fastpath+0x16/0x1b
             [<ffffffffffffffff>] 0xffffffffffffffff
      
      -> #0 (&mount_crypt_stat->global_auth_tok_list_mutex){+.+.+.}:
             [<ffffffff8108c675>] check_prev_add+0x85/0x370
             [<ffffffff8108cfc1>] validate_chain+0x661/0x750
             [<ffffffff8108d2e7>] __lock_acquire+0x237/0x430
             [<ffffffff8108d585>] lock_acquire+0xa5/0x150
             [<ffffffff815526cd>] __mutex_lock_common+0x4d/0x3d0
             [<ffffffff81552b56>] mutex_lock_nested+0x46/0x60
             [<ffffffff8121591e>] ecryptfs_find_global_auth_tok_for_sig+0x2e/0x90
             [<ffffffff812177d5>] ecryptfs_generate_key_packet_set+0x105/0x2b0
             [<ffffffff81212f49>] ecryptfs_write_headers_virt+0xc9/0x120
             [<ffffffff8121306d>] ecryptfs_write_metadata+0xcd/0x200
             [<ffffffff8120e44b>] ecryptfs_initialize_file+0x6b/0x140
             [<ffffffff8120e54d>] ecryptfs_create+0x2d/0x60
             [<ffffffff8113a7d4>] vfs_create+0xb4/0xe0
             [<ffffffff8113a8c4>] __open_namei_create+0xc4/0x110
             [<ffffffff8113d1c1>] do_filp_open+0xa01/0xae0
             [<ffffffff8112d8d9>] do_sys_open+0x69/0x140
             [<ffffffff8112d9f0>] sys_open+0x20/0x30
             [<ffffffff81013132>] system_call_fastpath+0x16/0x1b
             [<ffffffffffffffff>] 0xffffffffffffffff
      
      other info that might help us debug this:
      
      2 locks held by gdm/2640:
       #0:  (&sb->s_type->i_mutex_key#11){+.+.+.}, at: [<ffffffff8113cb8b>] do_filp_open+0x3cb/0xae0
       #1:  (&crypt_stat->keysig_list_mutex){+.+.+.}, at: [<ffffffff81217728>] ecryptfs_generate_key_packet_set+0x58/0x2b0
      
      stack backtrace:
      Pid: 2640, comm: gdm Tainted: G         C 2.6.31-2-generic #14~rbd2
      Call Trace:
       [<ffffffff8108b988>] print_circular_bug_tail+0xa8/0xf0
       [<ffffffff8108c675>] check_prev_add+0x85/0x370
       [<ffffffff81094912>] ? __module_text_address+0x12/0x60
       [<ffffffff8108cfc1>] validate_chain+0x661/0x750
       [<ffffffff81017275>] ? print_context_stack+0x85/0x140
       [<ffffffff81089c68>] ? find_usage_backwards+0x38/0x160
       [<ffffffff8108d2e7>] __lock_acquire+0x237/0x430
       [<ffffffff8108d585>] lock_acquire+0xa5/0x150
       [<ffffffff8121591e>] ? ecryptfs_find_global_auth_tok_for_sig+0x2e/0x90
       [<ffffffff8108b0b0>] ? check_usage_backwards+0x0/0xb0
       [<ffffffff815526cd>] __mutex_lock_common+0x4d/0x3d0
       [<ffffffff8121591e>] ? ecryptfs_find_global_auth_tok_for_sig+0x2e/0x90
       [<ffffffff8121591e>] ? ecryptfs_find_global_auth_tok_for_sig+0x2e/0x90
       [<ffffffff8108c02c>] ? mark_held_locks+0x6c/0xa0
       [<ffffffff81125b0d>] ? kmem_cache_alloc+0xfd/0x1a0
       [<ffffffff8108c34d>] ? trace_hardirqs_on_caller+0x14d/0x190
       [<ffffffff81552b56>] mutex_lock_nested+0x46/0x60
       [<ffffffff8121591e>] ecryptfs_find_global_auth_tok_for_sig+0x2e/0x90
       [<ffffffff812177d5>] ecryptfs_generate_key_packet_set+0x105/0x2b0
       [<ffffffff81212f49>] ecryptfs_write_headers_virt+0xc9/0x120
       [<ffffffff8121306d>] ecryptfs_write_metadata+0xcd/0x200
       [<ffffffff81210240>] ? ecryptfs_init_persistent_file+0x60/0xe0
       [<ffffffff8120e44b>] ecryptfs_initialize_file+0x6b/0x140
       [<ffffffff8120e54d>] ecryptfs_create+0x2d/0x60
       [<ffffffff8113a7d4>] vfs_create+0xb4/0xe0
       [<ffffffff8113a8c4>] __open_namei_create+0xc4/0x110
       [<ffffffff8113d1c1>] do_filp_open+0xa01/0xae0
       [<ffffffff8129a93e>] ? _raw_spin_unlock+0x5e/0xb0
       [<ffffffff8155410b>] ? _spin_unlock+0x2b/0x40
       [<ffffffff81139e9b>] ? getname+0x3b/0x240
       [<ffffffff81148a5a>] ? alloc_fd+0xfa/0x140
       [<ffffffff8112d8d9>] do_sys_open+0x69/0x140
       [<ffffffff81553b8f>] ? trace_hardirqs_on_thunk+0x3a/0x3f
       [<ffffffff8112d9f0>] sys_open+0x20/0x30
       [<ffffffff81013132>] system_call_fastpath+0x16/0x1b
      Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
      Signed-off-by: default avatarTyler Hicks <tyhicks@linux.vnet.ibm.com>
      aa06117f
    • Roland Dreier's avatar
      ecryptfs: Remove unneeded locking that triggers lockdep false positives · 05dafedb
      Roland Dreier authored
      In ecryptfs_destroy_inode(), inode_info->lower_file_mutex is locked,
      and just after the mutex is unlocked, the code does:
      
       	kmem_cache_free(ecryptfs_inode_info_cache, inode_info);
      
      This means that if another context could possibly try to take the same
      mutex as ecryptfs_destroy_inode(), then it could end up getting the
      mutex just before the data structure containing the mutex is freed.
      So any such use would be an obvious use-after-free bug (catchable with
      slab poisoning or mutex debugging), and therefore the locking in
      ecryptfs_destroy_inode() is not needed and can be dropped.
      
      Similarly, in ecryptfs_destroy_crypt_stat(), crypt_stat->keysig_list_mutex
      is locked, and then the mutex is unlocked just before the code does:
      
       	memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));
      
      Therefore taking this mutex is similarly not necessary.
      
      Removing this locking fixes false-positive lockdep reports such as the
      following (and they are false-positives for exactly the same reason
      that the locking is not needed):
      
      =================================
      [ INFO: inconsistent lock state ]
      2.6.31-2-generic #14~rbd3
      ---------------------------------
      inconsistent {RECLAIM_FS-ON-W} -> {IN-RECLAIM_FS-W} usage.
      kswapd0/323 [HC0[0]:SC0[0]:HE1:SE1] takes:
       (&inode_info->lower_file_mutex){+.+.?.}, at: [<ffffffff81210d34>] ecryptfs_destroy_inode+0x34/0x100
      {RECLAIM_FS-ON-W} state was registered at:
        [<ffffffff8108c02c>] mark_held_locks+0x6c/0xa0
        [<ffffffff8108c10f>] lockdep_trace_alloc+0xaf/0xe0
        [<ffffffff81125a51>] kmem_cache_alloc+0x41/0x1a0
        [<ffffffff8113117a>] get_empty_filp+0x7a/0x1a0
        [<ffffffff8112dd46>] dentry_open+0x36/0xc0
        [<ffffffff8121a36c>] ecryptfs_privileged_open+0x5c/0x2e0
        [<ffffffff81210283>] ecryptfs_init_persistent_file+0xa3/0xe0
        [<ffffffff8120e838>] ecryptfs_lookup_and_interpose_lower+0x278/0x380
        [<ffffffff8120f97a>] ecryptfs_lookup+0x12a/0x250
        [<ffffffff8113930a>] real_lookup+0xea/0x160
        [<ffffffff8113afc8>] do_lookup+0xb8/0xf0
        [<ffffffff8113b518>] __link_path_walk+0x518/0x870
        [<ffffffff8113bd9c>] path_walk+0x5c/0xc0
        [<ffffffff8113be5b>] do_path_lookup+0x5b/0xa0
        [<ffffffff8113bfe7>] user_path_at+0x57/0xa0
        [<ffffffff811340dc>] vfs_fstatat+0x3c/0x80
        [<ffffffff8113424b>] vfs_stat+0x1b/0x20
        [<ffffffff81134274>] sys_newstat+0x24/0x50
        [<ffffffff81013132>] system_call_fastpath+0x16/0x1b
        [<ffffffffffffffff>] 0xffffffffffffffff
      irq event stamp: 7811
      hardirqs last  enabled at (7811): [<ffffffff810c037f>] call_rcu+0x5f/0x90
      hardirqs last disabled at (7810): [<ffffffff810c0353>] call_rcu+0x33/0x90
      softirqs last  enabled at (3764): [<ffffffff810631da>] __do_softirq+0x14a/0x220
      softirqs last disabled at (3751): [<ffffffff8101440c>] call_softirq+0x1c/0x30
      
      other info that might help us debug this:
      2 locks held by kswapd0/323:
       #0:  (shrinker_rwsem){++++..}, at: [<ffffffff810f67ed>] shrink_slab+0x3d/0x190
       #1:  (&type->s_umount_key#35){.+.+..}, at: [<ffffffff811429a1>] prune_dcache+0xd1/0x1b0
      
      stack backtrace:
      Pid: 323, comm: kswapd0 Tainted: G         C 2.6.31-2-generic #14~rbd3
      Call Trace:
       [<ffffffff8108ad6c>] print_usage_bug+0x18c/0x1a0
       [<ffffffff8108aff0>] ? check_usage_forwards+0x0/0xc0
       [<ffffffff8108bac2>] mark_lock_irq+0xf2/0x280
       [<ffffffff8108bd87>] mark_lock+0x137/0x1d0
       [<ffffffff81164710>] ? fsnotify_clear_marks_by_inode+0x30/0xf0
       [<ffffffff8108bee6>] mark_irqflags+0xc6/0x1a0
       [<ffffffff8108d337>] __lock_acquire+0x287/0x430
       [<ffffffff8108d585>] lock_acquire+0xa5/0x150
       [<ffffffff81210d34>] ? ecryptfs_destroy_inode+0x34/0x100
       [<ffffffff8108d2e7>] ? __lock_acquire+0x237/0x430
       [<ffffffff815526ad>] __mutex_lock_common+0x4d/0x3d0
       [<ffffffff81210d34>] ? ecryptfs_destroy_inode+0x34/0x100
       [<ffffffff81164710>] ? fsnotify_clear_marks_by_inode+0x30/0xf0
       [<ffffffff81210d34>] ? ecryptfs_destroy_inode+0x34/0x100
       [<ffffffff8129a91e>] ? _raw_spin_unlock+0x5e/0xb0
       [<ffffffff81552b36>] mutex_lock_nested+0x46/0x60
       [<ffffffff81210d34>] ecryptfs_destroy_inode+0x34/0x100
       [<ffffffff81145d27>] destroy_inode+0x87/0xd0
       [<ffffffff81146b4c>] generic_delete_inode+0x12c/0x1a0
       [<ffffffff81145832>] iput+0x62/0x70
       [<ffffffff811423c8>] dentry_iput+0x98/0x110
       [<ffffffff81142550>] d_kill+0x50/0x80
       [<ffffffff81142623>] prune_one_dentry+0xa3/0xc0
       [<ffffffff811428b1>] __shrink_dcache_sb+0x271/0x290
       [<ffffffff811429d9>] prune_dcache+0x109/0x1b0
       [<ffffffff81142abf>] shrink_dcache_memory+0x3f/0x50
       [<ffffffff810f68dd>] shrink_slab+0x12d/0x190
       [<ffffffff810f9377>] balance_pgdat+0x4d7/0x640
       [<ffffffff8104c4c0>] ? finish_task_switch+0x40/0x150
       [<ffffffff810f63c0>] ? isolate_pages_global+0x0/0x60
       [<ffffffff810f95f7>] kswapd+0x117/0x170
       [<ffffffff810777a0>] ? autoremove_wake_function+0x0/0x40
       [<ffffffff810f94e0>] ? kswapd+0x0/0x170
       [<ffffffff810773be>] kthread+0x9e/0xb0
       [<ffffffff8101430a>] child_rip+0xa/0x20
       [<ffffffff81013c90>] ? restore_args+0x0/0x30
       [<ffffffff81077320>] ? kthread+0x0/0xb0
       [<ffffffff81014300>] ? child_rip+0x0/0x20
      Signed-off-by: default avatarRoland Dreier <roland@digitalvampire.org>
      Signed-off-by: default avatarTyler Hicks <tyhicks@linux.vnet.ibm.com>
      05dafedb
  2. 24 Sep, 2009 32 commits