Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ecryptfs...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 29 Oct 2010 21:15:12 +0000 (14:15 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 29 Oct 2010 21:15:12 +0000 (14:15 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ecryptfs/ecryptfs-2.6:
  eCryptfs: Print mount_auth_tok_only param in ecryptfs_show_options
  ecryptfs: added ecryptfs_mount_auth_tok_only mount parameter
  ecryptfs: checking return code of ecryptfs_find_auth_tok_for_sig()
  ecryptfs: release keys loaded in ecryptfs_keyring_auth_tok_for_sig()
  eCryptfs: Clear LOOKUP_OPEN flag when creating lower file
  ecryptfs: call vfs_setxattr() in ecryptfs_setxattr()

fs/ecryptfs/ecryptfs_kernel.h
fs/ecryptfs/inode.c
fs/ecryptfs/keystore.c
fs/ecryptfs/main.c
fs/ecryptfs/super.c

index 40186b9594296f5152119e43d3ade4092a17d07f..413a3c48f0bb8a539f2dd09c72cdc8c972db83c1 100644 (file)
@@ -377,6 +377,7 @@ struct ecryptfs_mount_crypt_stat {
 #define ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES      0x00000010
 #define ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK   0x00000020
 #define ECRYPTFS_GLOBAL_ENCFN_USE_FEK          0x00000040
+#define ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY    0x00000080
        u32 flags;
        struct list_head global_auth_tok_list;
        struct mutex global_auth_tok_list_mutex;
index 3fbc94203380acf8e6095627ee610ff058df5f38..9d1a22d62765af487333005a58e7c60230362a44 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/crypto.h>
 #include <linux/fs_stack.h>
 #include <linux/slab.h>
+#include <linux/xattr.h>
 #include <asm/unaligned.h>
 #include "ecryptfs_kernel.h"
 
@@ -70,15 +71,19 @@ ecryptfs_create_underlying_file(struct inode *lower_dir_inode,
        struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
        struct dentry *dentry_save;
        struct vfsmount *vfsmount_save;
+       unsigned int flags_save;
        int rc;
 
        dentry_save = nd->path.dentry;
        vfsmount_save = nd->path.mnt;
+       flags_save = nd->flags;
        nd->path.dentry = lower_dentry;
        nd->path.mnt = lower_mnt;
+       nd->flags &= ~LOOKUP_OPEN;
        rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd);
        nd->path.dentry = dentry_save;
        nd->path.mnt = vfsmount_save;
+       nd->flags = flags_save;
        return rc;
 }
 
@@ -1108,10 +1113,8 @@ ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
                rc = -EOPNOTSUPP;
                goto out;
        }
-       mutex_lock(&lower_dentry->d_inode->i_mutex);
-       rc = lower_dentry->d_inode->i_op->setxattr(lower_dentry, name, value,
-                                                  size, flags);
-       mutex_unlock(&lower_dentry->d_inode->i_mutex);
+
+       rc = vfs_setxattr(lower_dentry, name, value, size, flags);
 out:
        return rc;
 }
index 73811cfa2ea4369766a99a251c614ddb091bc8f4..b1f6858a5223323c43708b62b6ab2d9c139dc376 100644 (file)
@@ -446,6 +446,7 @@ out:
  */
 static int
 ecryptfs_find_auth_tok_for_sig(
+       struct key **auth_tok_key,
        struct ecryptfs_auth_tok **auth_tok,
        struct ecryptfs_mount_crypt_stat *mount_crypt_stat,
        char *sig)
@@ -453,12 +454,21 @@ ecryptfs_find_auth_tok_for_sig(
        struct ecryptfs_global_auth_tok *global_auth_tok;
        int rc = 0;
 
+       (*auth_tok_key) = NULL;
        (*auth_tok) = NULL;
        if (ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok,
                                                  mount_crypt_stat, sig)) {
-               struct key *auth_tok_key;
 
-               rc = ecryptfs_keyring_auth_tok_for_sig(&auth_tok_key, auth_tok,
+               /* if the flag ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY is set in the
+                * mount_crypt_stat structure, we prevent to use auth toks that
+                * are not inserted through the ecryptfs_add_global_auth_tok
+                * function.
+                */
+               if (mount_crypt_stat->flags
+                               & ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY)
+                       return -EINVAL;
+
+               rc = ecryptfs_keyring_auth_tok_for_sig(auth_tok_key, auth_tok,
                                                       sig);
        } else
                (*auth_tok) = global_auth_tok->global_auth_tok;
@@ -509,6 +519,7 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
                             char *filename, size_t filename_size)
 {
        struct ecryptfs_write_tag_70_packet_silly_stack *s;
+       struct key *auth_tok_key = NULL;
        int rc = 0;
 
        s = kmalloc(sizeof(*s), GFP_KERNEL);
@@ -606,6 +617,7 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
        }
        dest[s->i++] = s->cipher_code;
        rc = ecryptfs_find_auth_tok_for_sig(
+               &auth_tok_key,
                &s->auth_tok, mount_crypt_stat,
                mount_crypt_stat->global_default_fnek_sig);
        if (rc) {
@@ -753,6 +765,8 @@ out_free_unlock:
 out_unlock:
        mutex_unlock(s->tfm_mutex);
 out:
+       if (auth_tok_key)
+               key_put(auth_tok_key);
        kfree(s);
        return rc;
 }
@@ -798,6 +812,7 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
                             char *data, size_t max_packet_size)
 {
        struct ecryptfs_parse_tag_70_packet_silly_stack *s;
+       struct key *auth_tok_key = NULL;
        int rc = 0;
 
        (*packet_size) = 0;
@@ -910,7 +925,8 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
         * >= ECRYPTFS_MAX_IV_BYTES. */
        memset(s->iv, 0, ECRYPTFS_MAX_IV_BYTES);
        s->desc.info = s->iv;
-       rc = ecryptfs_find_auth_tok_for_sig(&s->auth_tok, mount_crypt_stat,
+       rc = ecryptfs_find_auth_tok_for_sig(&auth_tok_key,
+                                           &s->auth_tok, mount_crypt_stat,
                                            s->fnek_sig_hex);
        if (rc) {
                printk(KERN_ERR "%s: Error attempting to find auth tok for "
@@ -986,6 +1002,8 @@ out:
                (*filename_size) = 0;
                (*filename) = NULL;
        }
+       if (auth_tok_key)
+               key_put(auth_tok_key);
        kfree(s);
        return rc;
 }
@@ -1557,14 +1575,19 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key,
                       ECRYPTFS_VERSION_MAJOR,
                       ECRYPTFS_VERSION_MINOR);
                rc = -EINVAL;
-               goto out;
+               goto out_release_key;
        }
        if ((*auth_tok)->token_type != ECRYPTFS_PASSWORD
            && (*auth_tok)->token_type != ECRYPTFS_PRIVATE_KEY) {
                printk(KERN_ERR "Invalid auth_tok structure "
                       "returned from key query\n");
                rc = -EINVAL;
-               goto out;
+               goto out_release_key;
+       }
+out_release_key:
+       if (rc) {
+               key_put(*auth_tok_key);
+               (*auth_tok_key) = NULL;
        }
 out:
        return rc;
@@ -1688,6 +1711,7 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
        struct ecryptfs_auth_tok_list_item *auth_tok_list_item;
        size_t tag_11_contents_size;
        size_t tag_11_packet_size;
+       struct key *auth_tok_key = NULL;
        int rc = 0;
 
        INIT_LIST_HEAD(&auth_tok_list);
@@ -1784,6 +1808,10 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
         * just one will be sufficient to decrypt to get the FEK. */
 find_next_matching_auth_tok:
        found_auth_tok = 0;
+       if (auth_tok_key) {
+               key_put(auth_tok_key);
+               auth_tok_key = NULL;
+       }
        list_for_each_entry(auth_tok_list_item, &auth_tok_list, list) {
                candidate_auth_tok = &auth_tok_list_item->auth_tok;
                if (unlikely(ecryptfs_verbosity > 0)) {
@@ -1800,10 +1828,11 @@ find_next_matching_auth_tok:
                        rc = -EINVAL;
                        goto out_wipe_list;
                }
-               ecryptfs_find_auth_tok_for_sig(&matching_auth_tok,
+               rc = ecryptfs_find_auth_tok_for_sig(&auth_tok_key,
+                                              &matching_auth_tok,
                                               crypt_stat->mount_crypt_stat,
                                               candidate_auth_tok_sig);
-               if (matching_auth_tok) {
+               if (!rc) {
                        found_auth_tok = 1;
                        goto found_matching_auth_tok;
                }
@@ -1866,6 +1895,8 @@ found_matching_auth_tok:
 out_wipe_list:
        wipe_auth_tok_list(&auth_tok_list);
 out:
+       if (auth_tok_key)
+               key_put(auth_tok_key);
        return rc;
 }
 
index 8585934712d447f122977b0eb4377f43e73c060d..a9dbd62518e6a875abee7da0e0698ac0ed7ba4ff 100644 (file)
@@ -208,7 +208,8 @@ enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig,
        ecryptfs_opt_passthrough, ecryptfs_opt_xattr_metadata,
        ecryptfs_opt_encrypted_view, ecryptfs_opt_fnek_sig,
        ecryptfs_opt_fn_cipher, ecryptfs_opt_fn_cipher_key_bytes,
-       ecryptfs_opt_unlink_sigs, ecryptfs_opt_err };
+       ecryptfs_opt_unlink_sigs, ecryptfs_opt_mount_auth_tok_only,
+       ecryptfs_opt_err };
 
 static const match_table_t tokens = {
        {ecryptfs_opt_sig, "sig=%s"},
@@ -223,6 +224,7 @@ static const match_table_t tokens = {
        {ecryptfs_opt_fn_cipher, "ecryptfs_fn_cipher=%s"},
        {ecryptfs_opt_fn_cipher_key_bytes, "ecryptfs_fn_key_bytes=%u"},
        {ecryptfs_opt_unlink_sigs, "ecryptfs_unlink_sigs"},
+       {ecryptfs_opt_mount_auth_tok_only, "ecryptfs_mount_auth_tok_only"},
        {ecryptfs_opt_err, NULL}
 };
 
@@ -406,6 +408,10 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options)
                case ecryptfs_opt_unlink_sigs:
                        mount_crypt_stat->flags |= ECRYPTFS_UNLINK_SIGS;
                        break;
+               case ecryptfs_opt_mount_auth_tok_only:
+                       mount_crypt_stat->flags |=
+                               ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY;
+                       break;
                case ecryptfs_opt_err:
                default:
                        printk(KERN_WARNING
index f7fc286a3aa9a7353ab7ca1bd0ba56e7cbb821e2..253732382d375e848edc61ca40a3eaadb60f80c7 100644 (file)
@@ -180,6 +180,8 @@ static int ecryptfs_show_options(struct seq_file *m, struct vfsmount *mnt)
                seq_printf(m, ",ecryptfs_encrypted_view");
        if (mount_crypt_stat->flags & ECRYPTFS_UNLINK_SIGS)
                seq_printf(m, ",ecryptfs_unlink_sigs");
+       if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY)
+               seq_printf(m, ",ecryptfs_mount_auth_tok_only");
 
        return 0;
 }