* [PATCH v2 0/5] eCryptfs key locking patches
@ 2011-03-21 15:00 Roberto Sassu
2011-03-21 15:00 ` [PATCH v2 1/5] eCryptfs: removed num_global_auth_toks from ecryptfs_mount_crypt_stat Roberto Sassu
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Roberto Sassu @ 2011-03-21 15:00 UTC (permalink / raw)
To: tyhicks
Cc: kirkland, dhowells, jmorris, linux-fsdevel, keyrings,
linux-kernel, ecryptfs-devel, Roberto Sassu
[-- Attachment #1: Type: text/plain, Size: 1428 bytes --]
This patch set modifies the eCryptfs code in order to lock requested keys
while authentication tokens are used to encrypt or decrypt files.
Changelog:
- removed patch "eCryptfs: ecryptfs_keyring_auth_tok_for_sig() bug fix"
(already applied to the eCryptfs git repository at git.kernel.org);
- added new patch "eCryptfs: removed num_global_auth_toks from
ecryptfs_mount_crypt_stat";
- patch 3/5: avoid invalidating a global authentication token only if
key_validate() returns the error -EKEYEXPIRED;
- patch 3/5: added new function
process_find_global_auth_tok_for_sig_err() to handle errors
returned by ecryptfs_find_global_auth_tok_for_sig();
- patch 3/5: return an error in the function
ecryptfs_generate_key_packet_set() if at least one global
authentication token cannot be retrieved.
Roberto Sassu
Roberto Sassu (5):
eCryptfs: removed num_global_auth_toks from ecryptfs_mount_crypt_stat
eCryptfs: modified size of keysig in the ecryptfs_key_sig structure
eCryptfs: verify authentication tokens before their use
eCryptfs: move ecryptfs_find_auth_tok_for_sig() call before
mutex_lock
eCryptfs: write lock requested keys
fs/ecryptfs/crypto.c | 1 -
fs/ecryptfs/ecryptfs_kernel.h | 4 +-
fs/ecryptfs/keystore.c | 280 ++++++++++++++++++++++++++---------------
fs/ecryptfs/main.c | 8 +-
4 files changed, 185 insertions(+), 108 deletions(-)
--
1.7.4
[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2061 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 1/5] eCryptfs: removed num_global_auth_toks from ecryptfs_mount_crypt_stat
2011-03-21 15:00 [PATCH v2 0/5] eCryptfs key locking patches Roberto Sassu
@ 2011-03-21 15:00 ` Roberto Sassu
2011-03-21 15:00 ` [PATCH v2 2/5] eCryptfs: modified size of keysig in the ecryptfs_key_sig structure Roberto Sassu
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Roberto Sassu @ 2011-03-21 15:00 UTC (permalink / raw)
To: tyhicks
Cc: kirkland, dhowells, jmorris, linux-fsdevel, keyrings,
linux-kernel, ecryptfs-devel, Roberto Sassu
[-- Attachment #1: Type: text/plain, Size: 2042 bytes --]
This patch removes the 'num_global_auth_toks' field of the
ecryptfs_mount_crypt_stat structure, used to count the number of items in
the 'global_auth_tok_list' list. This variable is not needed because there
are no checks based upon it.
Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
---
fs/ecryptfs/crypto.c | 1 -
fs/ecryptfs/ecryptfs_kernel.h | 1 -
fs/ecryptfs/keystore.c | 1 -
3 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index bfd8b68..38178ff 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -266,7 +266,6 @@ void ecryptfs_destroy_mount_crypt_stat(
&mount_crypt_stat->global_auth_tok_list,
mount_crypt_stat_list) {
list_del(&auth_tok->mount_crypt_stat_list);
- mount_crypt_stat->num_global_auth_toks--;
if (auth_tok->global_auth_tok_key
&& !(auth_tok->flags & ECRYPTFS_AUTH_TOK_INVALID))
key_put(auth_tok->global_auth_tok_key);
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index e007534..6ea1faa 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -380,7 +380,6 @@ struct ecryptfs_mount_crypt_stat {
u32 flags;
struct list_head global_auth_tok_list;
struct mutex global_auth_tok_list_mutex;
- size_t num_global_auth_toks;
size_t global_default_cipher_key_size;
size_t global_default_fn_cipher_key_bytes;
unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 4feb78c..523e51d 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -2454,7 +2454,6 @@ ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat,
mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex);
list_add(&new_auth_tok->mount_crypt_stat_list,
&mount_crypt_stat->global_auth_tok_list);
- mount_crypt_stat->num_global_auth_toks++;
mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex);
out:
return rc;
--
1.7.4
[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2061 bytes --]
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 2/5] eCryptfs: modified size of keysig in the ecryptfs_key_sig structure
2011-03-21 15:00 [PATCH v2 0/5] eCryptfs key locking patches Roberto Sassu
2011-03-21 15:00 ` [PATCH v2 1/5] eCryptfs: removed num_global_auth_toks from ecryptfs_mount_crypt_stat Roberto Sassu
@ 2011-03-21 15:00 ` Roberto Sassu
2011-03-21 15:00 ` [PATCH v2 3/5] eCryptfs: verify authentication tokens before their use Roberto Sassu
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Roberto Sassu @ 2011-03-21 15:00 UTC (permalink / raw)
To: tyhicks
Cc: kirkland, dhowells, jmorris, linux-fsdevel, keyrings,
linux-kernel, ecryptfs-devel, Roberto Sassu
[-- Attachment #1: Type: text/plain, Size: 1423 bytes --]
The size of the 'keysig' array is incremented of one byte in order to make
room for the NULL character. The 'keysig' variable is used, in the function
ecryptfs_generate_key_packet_set(), to find an authentication token with
the given signature and is printed a debug message if it cannot be
retrieved.
Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
---
fs/ecryptfs/ecryptfs_kernel.h | 2 +-
fs/ecryptfs/keystore.c | 1 +
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 6ea1faa..f39956a 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -233,7 +233,7 @@ ecryptfs_get_key_payload_data(struct key *key)
struct ecryptfs_key_sig {
struct list_head crypt_stat_list;
- char keysig[ECRYPTFS_SIG_SIZE_HEX];
+ char keysig[ECRYPTFS_SIG_SIZE_HEX + 1];
};
struct ecryptfs_filename {
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 523e51d..bd139df 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -2425,6 +2425,7 @@ int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig)
return -ENOMEM;
}
memcpy(new_key_sig->keysig, sig, ECRYPTFS_SIG_SIZE_HEX);
+ new_key_sig->keysig[ECRYPTFS_SIG_SIZE_HEX] = '\0';
/* Caller must hold keysig_list_mutex */
list_add(&new_key_sig->crypt_stat_list, &crypt_stat->keysig_list);
--
1.7.4
[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2061 bytes --]
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 3/5] eCryptfs: verify authentication tokens before their use
2011-03-21 15:00 [PATCH v2 0/5] eCryptfs key locking patches Roberto Sassu
2011-03-21 15:00 ` [PATCH v2 1/5] eCryptfs: removed num_global_auth_toks from ecryptfs_mount_crypt_stat Roberto Sassu
2011-03-21 15:00 ` [PATCH v2 2/5] eCryptfs: modified size of keysig in the ecryptfs_key_sig structure Roberto Sassu
@ 2011-03-21 15:00 ` Roberto Sassu
2011-03-21 15:00 ` [PATCH v2 4/5] eCryptfs: move ecryptfs_find_auth_tok_for_sig() call before mutex_lock Roberto Sassu
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Roberto Sassu @ 2011-03-21 15:00 UTC (permalink / raw)
To: tyhicks
Cc: kirkland, dhowells, jmorris, linux-fsdevel, keyrings,
linux-kernel, ecryptfs-devel, Roberto Sassu
[-- Attachment #1: Type: text/plain, Size: 10563 bytes --]
Authentication tokens content may change if another requestor calls the
update() method of the corresponding key. The new function
ecryptfs_verify_auth_tok_from_key() retrieves the authentication token from
the provided key and verifies if it is still valid before being used to
encrypt or decrypt an eCryptfs file.
Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
---
fs/ecryptfs/ecryptfs_kernel.h | 1 -
fs/ecryptfs/keystore.c | 220 ++++++++++++++++++++++++++---------------
fs/ecryptfs/main.c | 4 +-
3 files changed, 144 insertions(+), 81 deletions(-)
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index f39956a..43ab593 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -333,7 +333,6 @@ struct ecryptfs_global_auth_tok {
u32 flags;
struct list_head mount_crypt_stat_list;
struct key *global_auth_tok_key;
- struct ecryptfs_auth_tok *global_auth_tok;
unsigned char sig[ECRYPTFS_SIG_SIZE_HEX + 1];
};
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index bd139df..ff92b3c 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -65,6 +65,26 @@ static int process_request_key_err(long err_code)
return rc;
}
+static int process_find_global_auth_tok_for_sig_err(int err_code)
+{
+ int rc = err_code;
+
+ switch (err_code) {
+ case -ENOENT:
+ ecryptfs_printk(KERN_WARNING,
+ "Missing auth tok\n");
+ break;
+ case -EINVAL:
+ ecryptfs_printk(KERN_WARNING,
+ "Invalid auth tok\n");
+ break;
+ default:
+ rc = process_request_key_err(err_code);
+ break;
+ }
+ return rc;
+}
+
/**
* ecryptfs_parse_packet_length
* @data: Pointer to memory containing length at offset
@@ -403,27 +423,122 @@ out:
return rc;
}
+/**
+ * ecryptfs_verify_version
+ * @version: The version number to confirm
+ *
+ * Returns zero on good version; non-zero otherwise
+ */
+static int ecryptfs_verify_version(u16 version)
+{
+ int rc = 0;
+ unsigned char major;
+ unsigned char minor;
+
+ major = ((version >> 8) & 0xFF);
+ minor = (version & 0xFF);
+ if (major != ECRYPTFS_VERSION_MAJOR) {
+ ecryptfs_printk(KERN_ERR, "Major version number mismatch. "
+ "Expected [%d]; got [%d]\n",
+ ECRYPTFS_VERSION_MAJOR, major);
+ rc = -EINVAL;
+ goto out;
+ }
+ if (minor != ECRYPTFS_VERSION_MINOR) {
+ ecryptfs_printk(KERN_ERR, "Minor version number mismatch. "
+ "Expected [%d]; got [%d]\n",
+ ECRYPTFS_VERSION_MINOR, minor);
+ rc = -EINVAL;
+ goto out;
+ }
+out:
+ return rc;
+}
+
+/**
+ * ecryptfs_verify_auth_tok_from_key
+ * @auth_tok_key: key containing the authentication token
+ * @auth_tok: authentication token
+ *
+ * Returns zero on valid auth tok; -EINVAL otherwise
+ */
+static int
+ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key,
+ struct ecryptfs_auth_tok **auth_tok)
+{
+ int rc = 0;
+
+ (*auth_tok) = ecryptfs_get_key_payload_data(auth_tok_key);
+ if (ecryptfs_verify_version((*auth_tok)->version)) {
+ printk(KERN_ERR
+ "Data structure version mismatch. "
+ "Userspace tools must match eCryptfs "
+ "kernel module with major version [%d] "
+ "and minor version [%d]\n",
+ ECRYPTFS_VERSION_MAJOR,
+ ECRYPTFS_VERSION_MINOR);
+ rc = -EINVAL;
+ goto out;
+ }
+ 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;
+ }
+out:
+ return rc;
+}
+
static int
ecryptfs_find_global_auth_tok_for_sig(
- struct ecryptfs_global_auth_tok **global_auth_tok,
+ struct key **auth_tok_key,
+ struct ecryptfs_auth_tok **auth_tok,
struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig)
{
struct ecryptfs_global_auth_tok *walker;
int rc = 0;
- (*global_auth_tok) = NULL;
+ (*auth_tok_key) = NULL;
+ (*auth_tok) = NULL;
mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex);
list_for_each_entry(walker,
&mount_crypt_stat->global_auth_tok_list,
mount_crypt_stat_list) {
- if (memcmp(walker->sig, sig, ECRYPTFS_SIG_SIZE_HEX) == 0) {
- rc = key_validate(walker->global_auth_tok_key);
- if (!rc)
- (*global_auth_tok) = walker;
+ if (memcmp(walker->sig, sig, ECRYPTFS_SIG_SIZE_HEX))
+ continue;
+
+ if (walker->flags & ECRYPTFS_AUTH_TOK_INVALID) {
+ rc = -EINVAL;
goto out;
}
+
+ rc = key_validate(walker->global_auth_tok_key);
+ if (rc) {
+ if (rc == -EKEYEXPIRED)
+ goto out;
+ else
+ goto out_invalid_auth_tok;
+ }
+
+ rc = ecryptfs_verify_auth_tok_from_key(
+ walker->global_auth_tok_key, auth_tok);
+ if (rc)
+ goto out_invalid_auth_tok;
+
+ (*auth_tok_key) = walker->global_auth_tok_key;
+ key_get(*auth_tok_key);
+ goto out;
}
- rc = -EINVAL;
+ rc = -ENOENT;
+ goto out;
+
+out_invalid_auth_tok:
+ printk(KERN_WARNING "Invalidating auth tok with sig = [%s]\n", sig);
+ walker->flags |= ECRYPTFS_AUTH_TOK_INVALID;
+ key_put(walker->global_auth_tok_key);
+ walker->global_auth_tok_key = NULL;
out:
mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex);
return rc;
@@ -451,14 +566,11 @@ ecryptfs_find_auth_tok_for_sig(
struct ecryptfs_mount_crypt_stat *mount_crypt_stat,
char *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)) {
-
+ rc = ecryptfs_find_global_auth_tok_for_sig(auth_tok_key, auth_tok,
+ mount_crypt_stat, sig);
+ if (rc == -ENOENT) {
/* 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
@@ -470,8 +582,8 @@ ecryptfs_find_auth_tok_for_sig(
rc = ecryptfs_keyring_auth_tok_for_sig(auth_tok_key, auth_tok,
sig);
- } else
- (*auth_tok) = global_auth_tok->global_auth_tok;
+ }
+
return rc;
}
@@ -1520,38 +1632,6 @@ out:
return rc;
}
-/**
- * ecryptfs_verify_version
- * @version: The version number to confirm
- *
- * Returns zero on good version; non-zero otherwise
- */
-static int ecryptfs_verify_version(u16 version)
-{
- int rc = 0;
- unsigned char major;
- unsigned char minor;
-
- major = ((version >> 8) & 0xFF);
- minor = (version & 0xFF);
- if (major != ECRYPTFS_VERSION_MAJOR) {
- ecryptfs_printk(KERN_ERR, "Major version number mismatch. "
- "Expected [%d]; got [%d]\n",
- ECRYPTFS_VERSION_MAJOR, major);
- rc = -EINVAL;
- goto out;
- }
- if (minor != ECRYPTFS_VERSION_MINOR) {
- ecryptfs_printk(KERN_ERR, "Minor version number mismatch. "
- "Expected [%d]; got [%d]\n",
- ECRYPTFS_VERSION_MINOR, minor);
- rc = -EINVAL;
- goto out;
- }
-out:
- return rc;
-}
-
int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key,
struct ecryptfs_auth_tok **auth_tok,
char *sig)
@@ -1566,29 +1646,12 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key,
(*auth_tok_key) = NULL;
goto out;
}
- (*auth_tok) = ecryptfs_get_key_payload_data(*auth_tok_key);
- if (ecryptfs_verify_version((*auth_tok)->version)) {
- printk(KERN_ERR
- "Data structure version mismatch. "
- "Userspace tools must match eCryptfs "
- "kernel module with major version [%d] "
- "and minor version [%d]\n",
- ECRYPTFS_VERSION_MAJOR,
- ECRYPTFS_VERSION_MINOR);
- rc = -EINVAL;
- 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_release_key;
- }
-out_release_key:
+
+ rc = ecryptfs_verify_auth_tok_from_key(*auth_tok_key, auth_tok);
if (rc) {
key_put(*auth_tok_key);
(*auth_tok_key) = NULL;
+ goto out;
}
out:
return rc;
@@ -2325,7 +2388,7 @@ ecryptfs_generate_key_packet_set(char *dest_base,
size_t max)
{
struct ecryptfs_auth_tok *auth_tok;
- struct ecryptfs_global_auth_tok *global_auth_tok;
+ struct key *auth_tok_key = NULL;
struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
&ecryptfs_superblock_to_private(
ecryptfs_dentry->d_sb)->mount_crypt_stat;
@@ -2344,21 +2407,17 @@ ecryptfs_generate_key_packet_set(char *dest_base,
list_for_each_entry(key_sig, &crypt_stat->keysig_list,
crypt_stat_list) {
memset(key_rec, 0, sizeof(*key_rec));
- rc = ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok,
+ rc = ecryptfs_find_global_auth_tok_for_sig(&auth_tok_key,
+ &auth_tok,
mount_crypt_stat,
key_sig->keysig);
if (rc) {
- printk(KERN_ERR "Error attempting to get the global "
- "auth_tok; rc = [%d]\n", rc);
- goto out_free;
- }
- if (global_auth_tok->flags & ECRYPTFS_AUTH_TOK_INVALID) {
printk(KERN_WARNING
- "Skipping invalid auth tok with sig = [%s]\n",
- global_auth_tok->sig);
- continue;
+ "Unable to retrieve auth tok with sig = [%s]\n",
+ key_sig->keysig);
+ rc = process_find_global_auth_tok_for_sig_err(rc);
+ goto out_free;
}
- auth_tok = global_auth_tok->global_auth_tok;
if (auth_tok->token_type == ECRYPTFS_PASSWORD) {
rc = write_tag_3_packet((dest_base + (*len)),
&max, auth_tok,
@@ -2396,6 +2455,8 @@ ecryptfs_generate_key_packet_set(char *dest_base,
rc = -EINVAL;
goto out_free;
}
+ key_put(auth_tok_key);
+ auth_tok_key = NULL;
}
if (likely(max > 0)) {
dest_base[(*len)] = 0x00;
@@ -2408,6 +2469,9 @@ out_free:
out:
if (rc)
(*len) = 0;
+ if (auth_tok_key)
+ key_put(auth_tok_key);
+
mutex_unlock(&crypt_stat->keysig_list_mutex);
return rc;
}
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 758323a..f079473 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -241,14 +241,14 @@ static int ecryptfs_init_global_auth_toks(
struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
{
struct ecryptfs_global_auth_tok *global_auth_tok;
+ struct ecryptfs_auth_tok *auth_tok;
int rc = 0;
list_for_each_entry(global_auth_tok,
&mount_crypt_stat->global_auth_tok_list,
mount_crypt_stat_list) {
rc = ecryptfs_keyring_auth_tok_for_sig(
- &global_auth_tok->global_auth_tok_key,
- &global_auth_tok->global_auth_tok,
+ &global_auth_tok->global_auth_tok_key, &auth_tok,
global_auth_tok->sig);
if (rc) {
printk(KERN_ERR "Could not find valid key in user "
--
1.7.4
[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2061 bytes --]
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 4/5] eCryptfs: move ecryptfs_find_auth_tok_for_sig() call before mutex_lock
2011-03-21 15:00 [PATCH v2 0/5] eCryptfs key locking patches Roberto Sassu
` (2 preceding siblings ...)
2011-03-21 15:00 ` [PATCH v2 3/5] eCryptfs: verify authentication tokens before their use Roberto Sassu
@ 2011-03-21 15:00 ` Roberto Sassu
2011-03-21 15:00 ` [PATCH v2 5/5] eCryptfs: write lock requested keys Roberto Sassu
2011-03-22 21:32 ` [PATCH v2 0/5] eCryptfs key locking patches Tyler Hicks
5 siblings, 0 replies; 7+ messages in thread
From: Roberto Sassu @ 2011-03-21 15:00 UTC (permalink / raw)
To: tyhicks
Cc: kirkland, dhowells, jmorris, linux-fsdevel, keyrings,
linux-kernel, ecryptfs-devel, Roberto Sassu
[-- Attachment #1: Type: text/plain, Size: 3055 bytes --]
The ecryptfs_find_auth_tok_for_sig() call is moved before the
mutex_lock(s->tfm_mutex) instruction in order to avoid possible deadlocks
that may occur by holding the lock on the two semaphores 'key->sem' and
's->tfm_mutex' in reverse order.
Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
---
fs/ecryptfs/keystore.c | 38 +++++++++++++++++++-------------------
1 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index ff92b3c..09b3afe 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -643,6 +643,16 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
}
s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
(*packet_size) = 0;
+ 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) {
+ printk(KERN_ERR "%s: Error attempting to find auth tok for "
+ "fnek sig [%s]; rc = [%d]\n", __func__,
+ mount_crypt_stat->global_default_fnek_sig, rc);
+ goto out;
+ }
rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(
&s->desc.tfm,
&s->tfm_mutex, mount_crypt_stat->global_default_fn_cipher_name);
@@ -728,16 +738,6 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
goto out_free_unlock;
}
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) {
- printk(KERN_ERR "%s: Error attempting to find auth tok for "
- "fnek sig [%s]; rc = [%d]\n", __func__,
- mount_crypt_stat->global_default_fnek_sig, rc);
- goto out_free_unlock;
- }
/* TODO: Support other key modules than passphrase for
* filename encryption */
if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) {
@@ -991,6 +991,15 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
__func__, s->cipher_code);
goto out;
}
+ 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 "
+ "fnek sig [%s]; rc = [%d]\n", __func__, s->fnek_sig_hex,
+ rc);
+ goto out;
+ }
rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&s->desc.tfm,
&s->tfm_mutex,
s->cipher_string);
@@ -1037,15 +1046,6 @@ 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(&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 "
- "fnek sig [%s]; rc = [%d]\n", __func__, s->fnek_sig_hex,
- rc);
- goto out_free_unlock;
- }
/* TODO: Support other key modules than passphrase for
* filename encryption */
if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) {
--
1.7.4
[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2061 bytes --]
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 5/5] eCryptfs: write lock requested keys
2011-03-21 15:00 [PATCH v2 0/5] eCryptfs key locking patches Roberto Sassu
` (3 preceding siblings ...)
2011-03-21 15:00 ` [PATCH v2 4/5] eCryptfs: move ecryptfs_find_auth_tok_for_sig() call before mutex_lock Roberto Sassu
@ 2011-03-21 15:00 ` Roberto Sassu
2011-03-22 21:32 ` [PATCH v2 0/5] eCryptfs key locking patches Tyler Hicks
5 siblings, 0 replies; 7+ messages in thread
From: Roberto Sassu @ 2011-03-21 15:00 UTC (permalink / raw)
To: tyhicks
Cc: kirkland, dhowells, jmorris, linux-fsdevel, keyrings,
linux-kernel, ecryptfs-devel, Roberto Sassu
[-- Attachment #1: Type: text/plain, Size: 3394 bytes --]
A requested key is write locked in order to prevent modifications on the
authentication token while it is being used.
Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
---
fs/ecryptfs/keystore.c | 26 ++++++++++++++++++++------
fs/ecryptfs/main.c | 4 +++-
2 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 09b3afe..455ce8f 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -522,10 +522,11 @@ ecryptfs_find_global_auth_tok_for_sig(
goto out_invalid_auth_tok;
}
+ down_write(&(walker->global_auth_tok_key->sem));
rc = ecryptfs_verify_auth_tok_from_key(
walker->global_auth_tok_key, auth_tok);
if (rc)
- goto out_invalid_auth_tok;
+ goto out_invalid_auth_tok_unlock;
(*auth_tok_key) = walker->global_auth_tok_key;
key_get(*auth_tok_key);
@@ -534,6 +535,8 @@ ecryptfs_find_global_auth_tok_for_sig(
rc = -ENOENT;
goto out;
+out_invalid_auth_tok_unlock:
+ up_write(&(walker->global_auth_tok_key->sem));
out_invalid_auth_tok:
printk(KERN_WARNING "Invalidating auth tok with sig = [%s]\n", sig);
walker->flags |= ECRYPTFS_AUTH_TOK_INVALID;
@@ -877,8 +880,10 @@ out_free_unlock:
out_unlock:
mutex_unlock(s->tfm_mutex);
out:
- if (auth_tok_key)
+ if (auth_tok_key) {
+ up_write(&(auth_tok_key->sem));
key_put(auth_tok_key);
+ }
kfree(s);
return rc;
}
@@ -1114,8 +1119,10 @@ out:
(*filename_size) = 0;
(*filename) = NULL;
}
- if (auth_tok_key)
+ if (auth_tok_key) {
+ up_write(&(auth_tok_key->sem));
key_put(auth_tok_key);
+ }
kfree(s);
return rc;
}
@@ -1646,9 +1653,10 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key,
(*auth_tok_key) = NULL;
goto out;
}
-
+ down_write(&(*auth_tok_key)->sem);
rc = ecryptfs_verify_auth_tok_from_key(*auth_tok_key, auth_tok);
if (rc) {
+ up_write(&(*auth_tok_key)->sem);
key_put(*auth_tok_key);
(*auth_tok_key) = NULL;
goto out;
@@ -1873,6 +1881,7 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
find_next_matching_auth_tok:
found_auth_tok = 0;
if (auth_tok_key) {
+ up_write(&(auth_tok_key->sem));
key_put(auth_tok_key);
auth_tok_key = NULL;
}
@@ -1959,8 +1968,10 @@ found_matching_auth_tok:
out_wipe_list:
wipe_auth_tok_list(&auth_tok_list);
out:
- if (auth_tok_key)
+ if (auth_tok_key) {
+ up_write(&(auth_tok_key->sem));
key_put(auth_tok_key);
+ }
return rc;
}
@@ -2455,6 +2466,7 @@ ecryptfs_generate_key_packet_set(char *dest_base,
rc = -EINVAL;
goto out_free;
}
+ up_write(&(auth_tok_key->sem));
key_put(auth_tok_key);
auth_tok_key = NULL;
}
@@ -2469,8 +2481,10 @@ out_free:
out:
if (rc)
(*len) = 0;
- if (auth_tok_key)
+ if (auth_tok_key) {
+ up_write(&(auth_tok_key->sem));
key_put(auth_tok_key);
+ }
mutex_unlock(&crypt_stat->keysig_list_mutex);
return rc;
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index f079473..ada50a3 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -256,8 +256,10 @@ static int ecryptfs_init_global_auth_toks(
"option: [%s]\n", global_auth_tok->sig);
global_auth_tok->flags |= ECRYPTFS_AUTH_TOK_INVALID;
goto out;
- } else
+ } else {
global_auth_tok->flags &= ~ECRYPTFS_AUTH_TOK_INVALID;
+ up_write(&(global_auth_tok->global_auth_tok_key)->sem);
+ }
}
out:
return rc;
--
1.7.4
[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2061 bytes --]
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 0/5] eCryptfs key locking patches
2011-03-21 15:00 [PATCH v2 0/5] eCryptfs key locking patches Roberto Sassu
` (4 preceding siblings ...)
2011-03-21 15:00 ` [PATCH v2 5/5] eCryptfs: write lock requested keys Roberto Sassu
@ 2011-03-22 21:32 ` Tyler Hicks
5 siblings, 0 replies; 7+ messages in thread
From: Tyler Hicks @ 2011-03-22 21:32 UTC (permalink / raw)
To: Roberto Sassu
Cc: kirkland, dhowells, jmorris, linux-fsdevel, keyrings,
linux-kernel, ecryptfs-devel
On Mon Mar 21, 2011 at 04:00:50PM +0100, Roberto Sassu <roberto.sassu@polito.it> wrote:
> This patch set modifies the eCryptfs code in order to lock requested keys
> while authentication tokens are used to encrypt or decrypt files.
>
> Changelog:
> - removed patch "eCryptfs: ecryptfs_keyring_auth_tok_for_sig() bug fix"
> (already applied to the eCryptfs git repository at git.kernel.org);
> - added new patch "eCryptfs: removed num_global_auth_toks from
> ecryptfs_mount_crypt_stat";
> - patch 3/5: avoid invalidating a global authentication token only if
> key_validate() returns the error -EKEYEXPIRED;
> - patch 3/5: added new function
> process_find_global_auth_tok_for_sig_err() to handle errors
> returned by ecryptfs_find_global_auth_tok_for_sig();
> - patch 3/5: return an error in the function
> ecryptfs_generate_key_packet_set() if at least one global
> authentication token cannot be retrieved.
Thanks Roberto - This revision looks good to me. I'll keep the patch set
in my tree for another day or two, to see if anyone else has comments,
and then set up a pull request to try to get it into the rc1 release.
Tyler
>
> Roberto Sassu
>
>
> Roberto Sassu (5):
> eCryptfs: removed num_global_auth_toks from ecryptfs_mount_crypt_stat
> eCryptfs: modified size of keysig in the ecryptfs_key_sig structure
> eCryptfs: verify authentication tokens before their use
> eCryptfs: move ecryptfs_find_auth_tok_for_sig() call before
> mutex_lock
> eCryptfs: write lock requested keys
>
> fs/ecryptfs/crypto.c | 1 -
> fs/ecryptfs/ecryptfs_kernel.h | 4 +-
> fs/ecryptfs/keystore.c | 280 ++++++++++++++++++++++++++---------------
> fs/ecryptfs/main.c | 8 +-
> 4 files changed, 185 insertions(+), 108 deletions(-)
>
> --
> 1.7.4
>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2011-03-22 21:32 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-21 15:00 [PATCH v2 0/5] eCryptfs key locking patches Roberto Sassu
2011-03-21 15:00 ` [PATCH v2 1/5] eCryptfs: removed num_global_auth_toks from ecryptfs_mount_crypt_stat Roberto Sassu
2011-03-21 15:00 ` [PATCH v2 2/5] eCryptfs: modified size of keysig in the ecryptfs_key_sig structure Roberto Sassu
2011-03-21 15:00 ` [PATCH v2 3/5] eCryptfs: verify authentication tokens before their use Roberto Sassu
2011-03-21 15:00 ` [PATCH v2 4/5] eCryptfs: move ecryptfs_find_auth_tok_for_sig() call before mutex_lock Roberto Sassu
2011-03-21 15:00 ` [PATCH v2 5/5] eCryptfs: write lock requested keys Roberto Sassu
2011-03-22 21:32 ` [PATCH v2 0/5] eCryptfs key locking patches Tyler Hicks
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).