diff options
Diffstat (limited to 'fs/ecryptfs/main.c')
-rw-r--r-- | fs/ecryptfs/main.c | 121 |
1 files changed, 44 insertions, 77 deletions
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index a98497264fe8..6e2170c96c02 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -179,38 +179,40 @@ static match_table_t tokens = { | |||
179 | {ecryptfs_opt_err, NULL} | 179 | {ecryptfs_opt_err, NULL} |
180 | }; | 180 | }; |
181 | 181 | ||
182 | /** | 182 | static int ecryptfs_init_global_auth_toks( |
183 | * ecryptfs_verify_version | 183 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) |
184 | * @version: The version number to confirm | ||
185 | * | ||
186 | * Returns zero on good version; non-zero otherwise | ||
187 | */ | ||
188 | static int ecryptfs_verify_version(u16 version) | ||
189 | { | 184 | { |
185 | struct ecryptfs_global_auth_tok *global_auth_tok; | ||
190 | int rc = 0; | 186 | int rc = 0; |
191 | unsigned char major; | 187 | |
192 | unsigned char minor; | 188 | list_for_each_entry(global_auth_tok, |
193 | 189 | &mount_crypt_stat->global_auth_tok_list, | |
194 | major = ((version >> 8) & 0xFF); | 190 | mount_crypt_stat_list) { |
195 | minor = (version & 0xFF); | 191 | if ((rc = ecryptfs_keyring_auth_tok_for_sig( |
196 | if (major != ECRYPTFS_VERSION_MAJOR) { | 192 | &global_auth_tok->global_auth_tok_key, |
197 | ecryptfs_printk(KERN_ERR, "Major version number mismatch. " | 193 | &global_auth_tok->global_auth_tok, |
198 | "Expected [%d]; got [%d]\n", | 194 | global_auth_tok->sig))) { |
199 | ECRYPTFS_VERSION_MAJOR, major); | 195 | printk(KERN_ERR "Could not find valid key in user " |
200 | rc = -EINVAL; | 196 | "session keyring for sig specified in mount " |
201 | goto out; | 197 | "option: [%s]\n", global_auth_tok->sig); |
202 | } | 198 | global_auth_tok->flags |= ECRYPTFS_AUTH_TOK_INVALID; |
203 | if (minor != ECRYPTFS_VERSION_MINOR) { | 199 | rc = 0; |
204 | ecryptfs_printk(KERN_ERR, "Minor version number mismatch. " | 200 | } else |
205 | "Expected [%d]; got [%d]\n", | 201 | global_auth_tok->flags &= ~ECRYPTFS_AUTH_TOK_INVALID; |
206 | ECRYPTFS_VERSION_MINOR, minor); | ||
207 | rc = -EINVAL; | ||
208 | goto out; | ||
209 | } | 202 | } |
210 | out: | ||
211 | return rc; | 203 | return rc; |
212 | } | 204 | } |
213 | 205 | ||
206 | static void ecryptfs_init_mount_crypt_stat( | ||
207 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) | ||
208 | { | ||
209 | memset((void *)mount_crypt_stat, 0, | ||
210 | sizeof(struct ecryptfs_mount_crypt_stat)); | ||
211 | INIT_LIST_HEAD(&mount_crypt_stat->global_auth_tok_list); | ||
212 | mutex_init(&mount_crypt_stat->global_auth_tok_list_mutex); | ||
213 | mount_crypt_stat->flags |= ECRYPTFS_MOUNT_CRYPT_STAT_INITIALIZED; | ||
214 | } | ||
215 | |||
214 | /** | 216 | /** |
215 | * ecryptfs_parse_options | 217 | * ecryptfs_parse_options |
216 | * @sb: The ecryptfs super block | 218 | * @sb: The ecryptfs super block |
@@ -264,14 +266,13 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
264 | case ecryptfs_opt_sig: | 266 | case ecryptfs_opt_sig: |
265 | case ecryptfs_opt_ecryptfs_sig: | 267 | case ecryptfs_opt_ecryptfs_sig: |
266 | sig_src = args[0].from; | 268 | sig_src = args[0].from; |
267 | sig_dst = | 269 | rc = ecryptfs_add_global_auth_tok(mount_crypt_stat, |
268 | mount_crypt_stat->global_auth_tok_sig; | 270 | sig_src); |
269 | memcpy(sig_dst, sig_src, ECRYPTFS_SIG_SIZE_HEX); | 271 | if (rc) { |
270 | sig_dst[ECRYPTFS_SIG_SIZE_HEX] = '\0'; | 272 | printk(KERN_ERR "Error attempting to register " |
271 | ecryptfs_printk(KERN_DEBUG, | 273 | "global sig; rc = [%d]\n", rc); |
272 | "The mount_crypt_stat " | 274 | goto out; |
273 | "global_auth_tok_sig set to: " | 275 | } |
274 | "[%s]\n", sig_dst); | ||
275 | sig_set = 1; | 276 | sig_set = 1; |
276 | break; | 277 | break; |
277 | case ecryptfs_opt_debug: | 278 | case ecryptfs_opt_debug: |
@@ -358,55 +359,21 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
358 | if (!cipher_key_bytes_set) { | 359 | if (!cipher_key_bytes_set) { |
359 | mount_crypt_stat->global_default_cipher_key_size = 0; | 360 | mount_crypt_stat->global_default_cipher_key_size = 0; |
360 | } | 361 | } |
361 | rc = ecryptfs_process_cipher( | 362 | if ((rc = ecryptfs_add_new_key_tfm( |
362 | &mount_crypt_stat->global_key_tfm, | 363 | NULL, mount_crypt_stat->global_default_cipher_name, |
363 | mount_crypt_stat->global_default_cipher_name, | 364 | mount_crypt_stat->global_default_cipher_key_size))) { |
364 | &mount_crypt_stat->global_default_cipher_key_size); | 365 | printk(KERN_ERR "Error attempting to initialize cipher with " |
365 | if (rc) { | 366 | "name = [%s] and key size = [%d]; rc = [%d]\n", |
366 | printk(KERN_ERR "Error attempting to initialize cipher [%s] " | ||
367 | "with key size [%Zd] bytes; rc = [%d]\n", | ||
368 | mount_crypt_stat->global_default_cipher_name, | 367 | mount_crypt_stat->global_default_cipher_name, |
369 | mount_crypt_stat->global_default_cipher_key_size, rc); | 368 | mount_crypt_stat->global_default_cipher_key_size, rc); |
370 | mount_crypt_stat->global_key_tfm = NULL; | ||
371 | mount_crypt_stat->global_auth_tok_key = NULL; | ||
372 | rc = -EINVAL; | ||
373 | goto out; | ||
374 | } | ||
375 | mutex_init(&mount_crypt_stat->global_key_tfm_mutex); | ||
376 | ecryptfs_printk(KERN_DEBUG, "Requesting the key with description: " | ||
377 | "[%s]\n", mount_crypt_stat->global_auth_tok_sig); | ||
378 | /* The reference to this key is held until umount is done The | ||
379 | * call to key_put is done in ecryptfs_put_super() */ | ||
380 | auth_tok_key = request_key(&key_type_user, | ||
381 | mount_crypt_stat->global_auth_tok_sig, | ||
382 | NULL); | ||
383 | if (!auth_tok_key || IS_ERR(auth_tok_key)) { | ||
384 | ecryptfs_printk(KERN_ERR, "Could not find key with " | ||
385 | "description: [%s]\n", | ||
386 | mount_crypt_stat->global_auth_tok_sig); | ||
387 | process_request_key_err(PTR_ERR(auth_tok_key)); | ||
388 | rc = -EINVAL; | 369 | rc = -EINVAL; |
389 | goto out; | 370 | goto out; |
390 | } | 371 | } |
391 | auth_tok = ecryptfs_get_key_payload_data(auth_tok_key); | 372 | if ((rc = ecryptfs_init_global_auth_toks(mount_crypt_stat))) { |
392 | if (ecryptfs_verify_version(auth_tok->version)) { | 373 | printk(KERN_WARNING "One or more global auth toks could not " |
393 | ecryptfs_printk(KERN_ERR, "Data structure version mismatch. " | 374 | "properly register; rc = [%d]\n", rc); |
394 | "Userspace tools must match eCryptfs kernel " | ||
395 | "module with major version [%d] and minor " | ||
396 | "version [%d]\n", ECRYPTFS_VERSION_MAJOR, | ||
397 | ECRYPTFS_VERSION_MINOR); | ||
398 | rc = -EINVAL; | ||
399 | goto out; | ||
400 | } | ||
401 | if (auth_tok->token_type != ECRYPTFS_PASSWORD | ||
402 | && auth_tok->token_type != ECRYPTFS_PRIVATE_KEY) { | ||
403 | ecryptfs_printk(KERN_ERR, "Invalid auth_tok structure " | ||
404 | "returned from key query\n"); | ||
405 | rc = -EINVAL; | ||
406 | goto out; | ||
407 | } | 375 | } |
408 | mount_crypt_stat->global_auth_tok_key = auth_tok_key; | 376 | rc = 0; |
409 | mount_crypt_stat->global_auth_tok = auth_tok; | ||
410 | out: | 377 | out: |
411 | return rc; | 378 | return rc; |
412 | } | 379 | } |