]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.0.1/ecryptfs-unlock-keys-needed-by-ecryptfsd.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.0.1 / ecryptfs-unlock-keys-needed-by-ecryptfsd.patch
CommitLineData
0d1514e0
GKH
1From b2987a5e05ec7a1af7ca42e5d5349d7a22753031 Mon Sep 17 00:00:00 2001
2From: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
3Date: Tue, 26 Jul 2011 19:47:08 -0500
4Subject: eCryptfs: Unlock keys needed by ecryptfsd
5
6From: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
7
8commit b2987a5e05ec7a1af7ca42e5d5349d7a22753031 upstream.
9
10Fixes a regression caused by b5695d04634fa4ccca7dcbc05bb4a66522f02e0b
11
12Kernel keyring keys containing eCryptfs authentication tokens should not
13be write locked when calling out to ecryptfsd to wrap and unwrap file
14encryption keys. The eCryptfs kernel code can not hold the key's write
15lock because ecryptfsd needs to request the key after receiving such a
16request from the kernel.
17
18Without this fix, all file opens and creates will timeout and fail when
19using the eCryptfs PKI infrastructure. This is not an issue when using
20passphrase-based mount keys, which is the most widely deployed eCryptfs
21configuration.
22
23Signed-off-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
24Acked-by: Roberto Sassu <roberto.sassu@polito.it>
25Tested-by: Roberto Sassu <roberto.sassu@polito.it>
26Tested-by: Alexis Hafner1 <haf@zurich.ibm.com>
27Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
28
29---
30 fs/ecryptfs/keystore.c | 47 +++++++++++++++++++++++++----------------------
31 1 file changed, 25 insertions(+), 22 deletions(-)
32
33--- a/fs/ecryptfs/keystore.c
34+++ b/fs/ecryptfs/keystore.c
35@@ -1868,11 +1868,6 @@ int ecryptfs_parse_packet_set(struct ecr
36 * just one will be sufficient to decrypt to get the FEK. */
37 find_next_matching_auth_tok:
38 found_auth_tok = 0;
39- if (auth_tok_key) {
40- up_write(&(auth_tok_key->sem));
41- key_put(auth_tok_key);
42- auth_tok_key = NULL;
43- }
44 list_for_each_entry(auth_tok_list_item, &auth_tok_list, list) {
45 candidate_auth_tok = &auth_tok_list_item->auth_tok;
46 if (unlikely(ecryptfs_verbosity > 0)) {
47@@ -1909,14 +1904,22 @@ found_matching_auth_tok:
48 memcpy(&(candidate_auth_tok->token.private_key),
49 &(matching_auth_tok->token.private_key),
50 sizeof(struct ecryptfs_private_key));
51+ up_write(&(auth_tok_key->sem));
52+ key_put(auth_tok_key);
53 rc = decrypt_pki_encrypted_session_key(candidate_auth_tok,
54 crypt_stat);
55 } else if (candidate_auth_tok->token_type == ECRYPTFS_PASSWORD) {
56 memcpy(&(candidate_auth_tok->token.password),
57 &(matching_auth_tok->token.password),
58 sizeof(struct ecryptfs_password));
59+ up_write(&(auth_tok_key->sem));
60+ key_put(auth_tok_key);
61 rc = decrypt_passphrase_encrypted_session_key(
62 candidate_auth_tok, crypt_stat);
63+ } else {
64+ up_write(&(auth_tok_key->sem));
65+ key_put(auth_tok_key);
66+ rc = -EINVAL;
67 }
68 if (rc) {
69 struct ecryptfs_auth_tok_list_item *auth_tok_list_item_tmp;
70@@ -1956,15 +1959,12 @@ found_matching_auth_tok:
71 out_wipe_list:
72 wipe_auth_tok_list(&auth_tok_list);
73 out:
74- if (auth_tok_key) {
75- up_write(&(auth_tok_key->sem));
76- key_put(auth_tok_key);
77- }
78 return rc;
79 }
80
81 static int
82-pki_encrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
83+pki_encrypt_session_key(struct key *auth_tok_key,
84+ struct ecryptfs_auth_tok *auth_tok,
85 struct ecryptfs_crypt_stat *crypt_stat,
86 struct ecryptfs_key_record *key_rec)
87 {
88@@ -1979,6 +1979,8 @@ pki_encrypt_session_key(struct ecryptfs_
89 crypt_stat->cipher,
90 crypt_stat->key_size),
91 crypt_stat, &payload, &payload_len);
92+ up_write(&(auth_tok_key->sem));
93+ key_put(auth_tok_key);
94 if (rc) {
95 ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet\n");
96 goto out;
97@@ -2008,6 +2010,8 @@ out:
98 * write_tag_1_packet - Write an RFC2440-compatible tag 1 (public key) packet
99 * @dest: Buffer into which to write the packet
100 * @remaining_bytes: Maximum number of bytes that can be writtn
101+ * @auth_tok_key: The authentication token key to unlock and put when done with
102+ * @auth_tok
103 * @auth_tok: The authentication token used for generating the tag 1 packet
104 * @crypt_stat: The cryptographic context
105 * @key_rec: The key record struct for the tag 1 packet
106@@ -2018,7 +2022,7 @@ out:
107 */
108 static int
109 write_tag_1_packet(char *dest, size_t *remaining_bytes,
110- struct ecryptfs_auth_tok *auth_tok,
111+ struct key *auth_tok_key, struct ecryptfs_auth_tok *auth_tok,
112 struct ecryptfs_crypt_stat *crypt_stat,
113 struct ecryptfs_key_record *key_rec, size_t *packet_size)
114 {
115@@ -2039,12 +2043,15 @@ write_tag_1_packet(char *dest, size_t *r
116 memcpy(key_rec->enc_key,
117 auth_tok->session_key.encrypted_key,
118 auth_tok->session_key.encrypted_key_size);
119+ up_write(&(auth_tok_key->sem));
120+ key_put(auth_tok_key);
121 goto encrypted_session_key_set;
122 }
123 if (auth_tok->session_key.encrypted_key_size == 0)
124 auth_tok->session_key.encrypted_key_size =
125 auth_tok->token.private_key.key_size;
126- rc = pki_encrypt_session_key(auth_tok, crypt_stat, key_rec);
127+ rc = pki_encrypt_session_key(auth_tok_key, auth_tok, crypt_stat,
128+ key_rec);
129 if (rc) {
130 printk(KERN_ERR "Failed to encrypt session key via a key "
131 "module; rc = [%d]\n", rc);
132@@ -2421,6 +2428,8 @@ ecryptfs_generate_key_packet_set(char *d
133 &max, auth_tok,
134 crypt_stat, key_rec,
135 &written);
136+ up_write(&(auth_tok_key->sem));
137+ key_put(auth_tok_key);
138 if (rc) {
139 ecryptfs_printk(KERN_WARNING, "Error "
140 "writing tag 3 packet\n");
141@@ -2438,8 +2447,8 @@ ecryptfs_generate_key_packet_set(char *d
142 }
143 (*len) += written;
144 } else if (auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) {
145- rc = write_tag_1_packet(dest_base + (*len),
146- &max, auth_tok,
147+ rc = write_tag_1_packet(dest_base + (*len), &max,
148+ auth_tok_key, auth_tok,
149 crypt_stat, key_rec, &written);
150 if (rc) {
151 ecryptfs_printk(KERN_WARNING, "Error "
152@@ -2448,14 +2457,13 @@ ecryptfs_generate_key_packet_set(char *d
153 }
154 (*len) += written;
155 } else {
156+ up_write(&(auth_tok_key->sem));
157+ key_put(auth_tok_key);
158 ecryptfs_printk(KERN_WARNING, "Unsupported "
159 "authentication token type\n");
160 rc = -EINVAL;
161 goto out_free;
162 }
163- up_write(&(auth_tok_key->sem));
164- key_put(auth_tok_key);
165- auth_tok_key = NULL;
166 }
167 if (likely(max > 0)) {
168 dest_base[(*len)] = 0x00;
169@@ -2468,11 +2476,6 @@ out_free:
170 out:
171 if (rc)
172 (*len) = 0;
173- if (auth_tok_key) {
174- up_write(&(auth_tok_key->sem));
175- key_put(auth_tok_key);
176- }
177-
178 mutex_unlock(&crypt_stat->keysig_list_mutex);
179 return rc;
180 }