summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorAndrey Markovytch <andreym@codeaurora.org>2015-07-30 11:45:29 +0300
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 21:24:11 -0700
commit36f1ad69fd10838dc90d31e692a318c4992cd48b (patch)
treedea452ec92fd4c8804a98876b32bb5df6a4e33bd /fs
parentaaf495b3ab5c8476bffdd2d1e4ec3157268647c1 (diff)
eCryptfs: fixed some major bugs
1. Fixed bug which didn't allow several threads to work simultaneously on files in eCryptfs mounted folder 2. Fixed bug where PFK close callback was invoked multiple times when files was opened and closed multiple times. Now it is invoked just once when files is closed for the last time Change-Id: Iaa3ada03500e5a12752918b5d2bb4a852ddca5f0 Signed-off-by: Andrey Markovytch <andreym@codeaurora.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/ecryptfs/crypto.c8
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h11
-rw-r--r--fs/ecryptfs/events.c9
-rw-r--r--fs/ecryptfs/file.c3
-rw-r--r--fs/ecryptfs/keystore.c17
-rw-r--r--fs/ecryptfs/main.c16
-rw-r--r--fs/ecryptfs/super.c6
7 files changed, 48 insertions, 22 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index f68e4aa0165e..d0c5100d2c01 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -470,6 +470,8 @@ out:
static void init_ecryption_parameters(bool *hw_crypt, bool *cipher_supported,
struct ecryptfs_crypt_stat *crypt_stat)
{
+ unsigned char final[2*ECRYPTFS_MAX_CIPHER_NAME_SIZE+1];
+
if (!hw_crypt || !cipher_supported)
return;
@@ -480,7 +482,7 @@ static void init_ecryption_parameters(bool *hw_crypt, bool *cipher_supported,
*cipher_supported =
get_events()->is_cipher_supported_cb(
ecryptfs_get_full_cipher(crypt_stat->cipher,
- crypt_stat->cipher_mode));
+ crypt_stat->cipher_mode, final, sizeof(final)));
if (*cipher_supported) {
/**
* we should apply external algorythm
@@ -805,10 +807,12 @@ static void ecryptfs_generate_new_key(struct ecryptfs_crypt_stat *crypt_stat)
static int ecryptfs_generate_new_salt(struct ecryptfs_crypt_stat *crypt_stat)
{
size_t salt_size = 0;
+ unsigned char final[2*ECRYPTFS_MAX_CIPHER_NAME_SIZE+1];
salt_size = ecryptfs_get_salt_size_for_cipher(
ecryptfs_get_full_cipher(crypt_stat->cipher,
- crypt_stat->cipher_mode));
+ crypt_stat->cipher_mode,
+ final, sizeof(final)));
if (0 == salt_size)
return 0;
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 1c04de22e258..f5c96ed40805 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -534,16 +534,17 @@ ecryptfs_dentry_to_lower_path(struct dentry *dentry)
* concatenates them to create a new string of
* <cipher>_<mode> format.
*/
-static inline char *ecryptfs_get_full_cipher(
- char *cipher, char *mode)
+static inline unsigned char *ecryptfs_get_full_cipher(
+ unsigned char *cipher, unsigned char *mode,
+ unsigned char *final, size_t final_size)
{
- static char final[2*ECRYPTFS_MAX_CIPHER_NAME_SIZE+1];
+ memset(final, 0, final_size);
if (strlen(mode) > 0) {
- memset(final, 0, sizeof(final));
- snprintf(final, sizeof(final), "%s_%s", cipher, mode);
+ snprintf(final, final_size, "%s_%s", cipher, mode);
return final;
}
+
return cipher;
}
diff --git a/fs/ecryptfs/events.c b/fs/ecryptfs/events.c
index 0e970fa70996..043ea39c4901 100644
--- a/fs/ecryptfs/events.c
+++ b/fs/ecryptfs/events.c
@@ -176,6 +176,7 @@ size_t ecryptfs_get_key_size(void *data)
size_t ecryptfs_get_salt_size(void *data)
{
struct ecryptfs_crypt_stat *stat = NULL;
+ unsigned char final[2*ECRYPTFS_MAX_CIPHER_NAME_SIZE+1];
if (!data) {
ecryptfs_printk(KERN_ERR,
@@ -186,7 +187,8 @@ size_t ecryptfs_get_salt_size(void *data)
stat = (struct ecryptfs_crypt_stat *)data;
return ecryptfs_get_salt_size_for_cipher(
ecryptfs_get_full_cipher(stat->cipher,
- stat->cipher_mode));
+ stat->cipher_mode,
+ final, sizeof(final)));
}
@@ -196,7 +198,7 @@ size_t ecryptfs_get_salt_size(void *data)
*/
const unsigned char *ecryptfs_get_cipher(void *data)
{
-
+ unsigned char final[2*ECRYPTFS_MAX_CIPHER_NAME_SIZE+1];
struct ecryptfs_crypt_stat *stat = NULL;
if (!data) {
@@ -205,7 +207,8 @@ const unsigned char *ecryptfs_get_cipher(void *data)
return NULL;
}
stat = (struct ecryptfs_crypt_stat *)data;
- return ecryptfs_get_full_cipher(stat->cipher, stat->cipher_mode);
+ return ecryptfs_get_full_cipher(stat->cipher, stat->cipher_mode,
+ final, sizeof(final));
}
/**
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index ca9903aec422..bfcbe6f6876e 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -291,9 +291,6 @@ static int ecryptfs_release(struct inode *inode, struct file *file)
if (ret)
pr_err("failed to sync file ret = %d.\n", ret);
- if (get_events() && get_events()->release_cb)
- get_events()->release_cb(ecryptfs_inode_to_lower(inode));
-
ecryptfs_put_lower_file(inode);
kmem_cache_free(ecryptfs_file_info_cache,
ecryptfs_file_to_private(file));
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 70708270c905..82b99c786abb 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -1687,6 +1687,8 @@ static int
decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
struct ecryptfs_crypt_stat *crypt_stat)
{
+
+ unsigned char final[2*ECRYPTFS_MAX_CIPHER_NAME_SIZE+1];
struct scatterlist dst_sg[2];
struct scatterlist src_sg[2];
struct mutex *tfm_mutex;
@@ -1761,7 +1763,8 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
crypt_stat->key_size);
ecryptfs_dump_salt_hex(crypt_stat->key, crypt_stat->key_size,
ecryptfs_get_full_cipher(crypt_stat->cipher,
- crypt_stat->cipher_mode));
+ crypt_stat->cipher_mode,
+ final, sizeof(final)));
}
out:
return rc;
@@ -1998,15 +2001,17 @@ pki_encrypt_session_key(struct key *auth_tok_key,
size_t payload_len = 0;
struct ecryptfs_message *msg;
int rc;
+ unsigned char final[2*ECRYPTFS_MAX_CIPHER_NAME_SIZE+1];
rc = write_tag_66_packet(auth_tok->token.private_key.signature,
ecryptfs_code_for_cipher_string(
ecryptfs_get_full_cipher(
crypt_stat->cipher,
- crypt_stat->cipher_mode),
+ crypt_stat->cipher_mode,
+ final, sizeof(final)),
ecryptfs_get_key_size_to_enc_data(
crypt_stat)),
- crypt_stat, &payload, &payload_len);
+ crypt_stat, &payload, &payload_len);
up_write(&(auth_tok_key->sem));
key_put(auth_tok_key);
if (rc) {
@@ -2218,6 +2223,7 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes,
u8 cipher_code;
size_t packet_size_length;
size_t max_packet_size;
+ unsigned char final[2*ECRYPTFS_MAX_CIPHER_NAME_SIZE+1];
struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
crypt_stat->mount_crypt_stat;
struct blkcipher_desc desc = {
@@ -2328,7 +2334,8 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes,
ecryptfs_printk(KERN_DEBUG, "Encrypting [%zd] bytes of the salt key\n",
ecryptfs_get_salt_size_for_cipher(
ecryptfs_get_full_cipher(crypt_stat->cipher,
- crypt_stat->cipher_mode)));
+ crypt_stat->cipher_mode,
+ final, sizeof(final))));
rc = crypto_blkcipher_encrypt(&desc, dst_sg, src_sg,
(*key_rec).enc_key_size);
mutex_unlock(tfm_mutex);
@@ -2379,7 +2386,7 @@ encrypted_session_key_set:
* specified with strings */
cipher_code = ecryptfs_code_for_cipher_string(
ecryptfs_get_full_cipher(crypt_stat->cipher,
- crypt_stat->cipher_mode),
+ crypt_stat->cipher_mode, final, sizeof(final)),
crypt_stat->key_size);
if (cipher_code == 0) {
ecryptfs_printk(KERN_WARNING, "Unable to generate code for "
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index a3bd96a80ade..4565d6fa6cca 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -165,7 +165,13 @@ void ecryptfs_put_lower_file(struct inode *inode)
fput(inode_info->lower_file);
inode_info->lower_file = NULL;
mutex_unlock(&inode_info->lower_file_mutex);
+
+ if (get_events() && get_events()->release_cb)
+ get_events()->release_cb(
+ ecryptfs_inode_to_lower(inode));
}
+
+
}
enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig,
@@ -281,6 +287,7 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options,
char *cipher_key_bytes_src;
char *fn_cipher_key_bytes_src;
u8 cipher_code;
+ unsigned char final[2*ECRYPTFS_MAX_CIPHER_NAME_SIZE+1];
*check_ruid = 0;
@@ -425,7 +432,8 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options,
salt_size = ecryptfs_get_salt_size_for_cipher(
ecryptfs_get_full_cipher(
mount_crypt_stat->global_default_cipher_name,
- mount_crypt_stat->global_default_cipher_mode));
+ mount_crypt_stat->global_default_cipher_mode,
+ final, sizeof(final)));
if (!ecryptfs_check_space_for_salt(
mount_crypt_stat->global_default_cipher_key_size,
@@ -445,7 +453,8 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options,
cipher_code = ecryptfs_code_for_cipher_string(
ecryptfs_get_full_cipher(
mount_crypt_stat->global_default_cipher_name,
- mount_crypt_stat->global_default_cipher_mode),
+ mount_crypt_stat->global_default_cipher_mode,
+ final, sizeof(final)),
mount_crypt_stat->global_default_cipher_key_size);
if (!cipher_code) {
ecryptfs_printk(
@@ -453,7 +462,8 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options,
"eCryptfs doesn't support cipher: %s and key size %lu",
ecryptfs_get_full_cipher(
mount_crypt_stat->global_default_cipher_name,
- mount_crypt_stat->global_default_cipher_mode),
+ mount_crypt_stat->global_default_cipher_mode,
+ final, sizeof(final)),
mount_crypt_stat->global_default_cipher_key_size);
rc = -EINVAL;
goto out;
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
index 0066a4a6696d..25e436ddcf8e 100644
--- a/fs/ecryptfs/super.c
+++ b/fs/ecryptfs/super.c
@@ -155,6 +155,9 @@ static int ecryptfs_show_options(struct seq_file *m, struct dentry *root)
struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
&ecryptfs_superblock_to_private(sb)->mount_crypt_stat;
struct ecryptfs_global_auth_tok *walker;
+ unsigned char final[2*ECRYPTFS_MAX_CIPHER_NAME_SIZE+1];
+
+ memset(final, 0, sizeof(final));
mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex);
list_for_each_entry(walker,
@@ -170,7 +173,8 @@ static int ecryptfs_show_options(struct seq_file *m, struct dentry *root)
seq_printf(m, ",ecryptfs_cipher=%s",
ecryptfs_get_full_cipher(
mount_crypt_stat->global_default_cipher_name,
- mount_crypt_stat->global_default_cipher_mode));
+ mount_crypt_stat->global_default_cipher_mode,
+ final, sizeof(final)));
if (mount_crypt_stat->global_default_cipher_key_size)
seq_printf(m, ",ecryptfs_key_bytes=%zd",