Commit 12462f2d authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ecryptfs/ecryptfs-2.6

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