diff options
| -rw-r--r-- | fs/ecryptfs/Kconfig | 2 | ||||
| -rw-r--r-- | fs/ecryptfs/keystore.c | 2 | ||||
| -rw-r--r-- | fs/ecryptfs/main.c | 23 | ||||
| -rw-r--r-- | fs/ecryptfs/read_write.c | 18 |
4 files changed, 33 insertions, 12 deletions
diff --git a/fs/ecryptfs/Kconfig b/fs/ecryptfs/Kconfig index 1cd6d9d3e29a..cc16562654de 100644 --- a/fs/ecryptfs/Kconfig +++ b/fs/ecryptfs/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config ECRYPT_FS | 1 | config ECRYPT_FS |
| 2 | tristate "eCrypt filesystem layer support (EXPERIMENTAL)" | 2 | tristate "eCrypt filesystem layer support (EXPERIMENTAL)" |
| 3 | depends on EXPERIMENTAL && KEYS && CRYPTO | 3 | depends on EXPERIMENTAL && KEYS && CRYPTO && (ENCRYPTED_KEYS || ENCRYPTED_KEYS=n) |
| 4 | select CRYPTO_ECB | 4 | select CRYPTO_ECB |
| 5 | select CRYPTO_CBC | 5 | select CRYPTO_CBC |
| 6 | select CRYPTO_MD5 | 6 | select CRYPTO_MD5 |
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index 08a2b52bf565..ac1ad48c2376 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
| @@ -1973,7 +1973,7 @@ pki_encrypt_session_key(struct key *auth_tok_key, | |||
| 1973 | { | 1973 | { |
| 1974 | struct ecryptfs_msg_ctx *msg_ctx = NULL; | 1974 | struct ecryptfs_msg_ctx *msg_ctx = NULL; |
| 1975 | char *payload = NULL; | 1975 | char *payload = NULL; |
| 1976 | size_t payload_len; | 1976 | size_t payload_len = 0; |
| 1977 | struct ecryptfs_message *msg; | 1977 | struct ecryptfs_message *msg; |
| 1978 | int rc; | 1978 | int rc; |
| 1979 | 1979 | ||
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 9f1bb747d77d..b4a6befb1216 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
| @@ -175,6 +175,7 @@ enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, | |||
| 175 | ecryptfs_opt_encrypted_view, ecryptfs_opt_fnek_sig, | 175 | ecryptfs_opt_encrypted_view, ecryptfs_opt_fnek_sig, |
| 176 | ecryptfs_opt_fn_cipher, ecryptfs_opt_fn_cipher_key_bytes, | 176 | ecryptfs_opt_fn_cipher, ecryptfs_opt_fn_cipher_key_bytes, |
| 177 | ecryptfs_opt_unlink_sigs, ecryptfs_opt_mount_auth_tok_only, | 177 | ecryptfs_opt_unlink_sigs, ecryptfs_opt_mount_auth_tok_only, |
| 178 | ecryptfs_opt_check_dev_ruid, | ||
| 178 | ecryptfs_opt_err }; | 179 | ecryptfs_opt_err }; |
| 179 | 180 | ||
| 180 | static const match_table_t tokens = { | 181 | static const match_table_t tokens = { |
| @@ -191,6 +192,7 @@ static const match_table_t tokens = { | |||
| 191 | {ecryptfs_opt_fn_cipher_key_bytes, "ecryptfs_fn_key_bytes=%u"}, | 192 | {ecryptfs_opt_fn_cipher_key_bytes, "ecryptfs_fn_key_bytes=%u"}, |
| 192 | {ecryptfs_opt_unlink_sigs, "ecryptfs_unlink_sigs"}, | 193 | {ecryptfs_opt_unlink_sigs, "ecryptfs_unlink_sigs"}, |
| 193 | {ecryptfs_opt_mount_auth_tok_only, "ecryptfs_mount_auth_tok_only"}, | 194 | {ecryptfs_opt_mount_auth_tok_only, "ecryptfs_mount_auth_tok_only"}, |
| 195 | {ecryptfs_opt_check_dev_ruid, "ecryptfs_check_dev_ruid"}, | ||
| 194 | {ecryptfs_opt_err, NULL} | 196 | {ecryptfs_opt_err, NULL} |
| 195 | }; | 197 | }; |
| 196 | 198 | ||
| @@ -236,6 +238,7 @@ static void ecryptfs_init_mount_crypt_stat( | |||
| 236 | * ecryptfs_parse_options | 238 | * ecryptfs_parse_options |
| 237 | * @sb: The ecryptfs super block | 239 | * @sb: The ecryptfs super block |
| 238 | * @options: The options passed to the kernel | 240 | * @options: The options passed to the kernel |
| 241 | * @check_ruid: set to 1 if device uid should be checked against the ruid | ||
| 239 | * | 242 | * |
| 240 | * Parse mount options: | 243 | * Parse mount options: |
| 241 | * debug=N - ecryptfs_verbosity level for debug output | 244 | * debug=N - ecryptfs_verbosity level for debug output |
| @@ -251,7 +254,8 @@ static void ecryptfs_init_mount_crypt_stat( | |||
| 251 | * | 254 | * |
| 252 | * Returns zero on success; non-zero on error | 255 | * Returns zero on success; non-zero on error |
| 253 | */ | 256 | */ |
| 254 | static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) | 257 | static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, |
| 258 | uid_t *check_ruid) | ||
| 255 | { | 259 | { |
| 256 | char *p; | 260 | char *p; |
| 257 | int rc = 0; | 261 | int rc = 0; |
| @@ -276,6 +280,8 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) | |||
| 276 | char *cipher_key_bytes_src; | 280 | char *cipher_key_bytes_src; |
| 277 | char *fn_cipher_key_bytes_src; | 281 | char *fn_cipher_key_bytes_src; |
| 278 | 282 | ||
| 283 | *check_ruid = 0; | ||
| 284 | |||
| 279 | if (!options) { | 285 | if (!options) { |
| 280 | rc = -EINVAL; | 286 | rc = -EINVAL; |
| 281 | goto out; | 287 | goto out; |
| @@ -380,6 +386,9 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) | |||
| 380 | mount_crypt_stat->flags |= | 386 | mount_crypt_stat->flags |= |
| 381 | ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY; | 387 | ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY; |
| 382 | break; | 388 | break; |
| 389 | case ecryptfs_opt_check_dev_ruid: | ||
| 390 | *check_ruid = 1; | ||
| 391 | break; | ||
| 383 | case ecryptfs_opt_err: | 392 | case ecryptfs_opt_err: |
| 384 | default: | 393 | default: |
| 385 | printk(KERN_WARNING | 394 | printk(KERN_WARNING |
| @@ -475,6 +484,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags | |||
| 475 | const char *err = "Getting sb failed"; | 484 | const char *err = "Getting sb failed"; |
| 476 | struct inode *inode; | 485 | struct inode *inode; |
| 477 | struct path path; | 486 | struct path path; |
| 487 | uid_t check_ruid; | ||
| 478 | int rc; | 488 | int rc; |
| 479 | 489 | ||
| 480 | sbi = kmem_cache_zalloc(ecryptfs_sb_info_cache, GFP_KERNEL); | 490 | sbi = kmem_cache_zalloc(ecryptfs_sb_info_cache, GFP_KERNEL); |
| @@ -483,7 +493,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags | |||
| 483 | goto out; | 493 | goto out; |
| 484 | } | 494 | } |
| 485 | 495 | ||
| 486 | rc = ecryptfs_parse_options(sbi, raw_data); | 496 | rc = ecryptfs_parse_options(sbi, raw_data, &check_ruid); |
| 487 | if (rc) { | 497 | if (rc) { |
| 488 | err = "Error parsing options"; | 498 | err = "Error parsing options"; |
| 489 | goto out; | 499 | goto out; |
| @@ -521,6 +531,15 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags | |||
| 521 | "known incompatibilities\n"); | 531 | "known incompatibilities\n"); |
| 522 | goto out_free; | 532 | goto out_free; |
| 523 | } | 533 | } |
| 534 | |||
| 535 | if (check_ruid && path.dentry->d_inode->i_uid != current_uid()) { | ||
| 536 | rc = -EPERM; | ||
| 537 | printk(KERN_ERR "Mount of device (uid: %d) not owned by " | ||
| 538 | "requested user (uid: %d)\n", | ||
| 539 | path.dentry->d_inode->i_uid, current_uid()); | ||
| 540 | goto out_free; | ||
| 541 | } | ||
| 542 | |||
| 524 | ecryptfs_set_superblock_lower(s, path.dentry->d_sb); | 543 | ecryptfs_set_superblock_lower(s, path.dentry->d_sb); |
| 525 | s->s_maxbytes = path.dentry->d_sb->s_maxbytes; | 544 | s->s_maxbytes = path.dentry->d_sb->s_maxbytes; |
| 526 | s->s_blocksize = path.dentry->d_sb->s_blocksize; | 545 | s->s_blocksize = path.dentry->d_sb->s_blocksize; |
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c index 85d430963116..3745f7c2b9c2 100644 --- a/fs/ecryptfs/read_write.c +++ b/fs/ecryptfs/read_write.c | |||
| @@ -39,15 +39,16 @@ | |||
| 39 | int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, | 39 | int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, |
| 40 | loff_t offset, size_t size) | 40 | loff_t offset, size_t size) |
| 41 | { | 41 | { |
| 42 | struct ecryptfs_inode_info *inode_info; | 42 | struct file *lower_file; |
| 43 | mm_segment_t fs_save; | 43 | mm_segment_t fs_save; |
| 44 | ssize_t rc; | 44 | ssize_t rc; |
| 45 | 45 | ||
| 46 | inode_info = ecryptfs_inode_to_private(ecryptfs_inode); | 46 | lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file; |
| 47 | BUG_ON(!inode_info->lower_file); | 47 | if (!lower_file) |
| 48 | return -EIO; | ||
| 48 | fs_save = get_fs(); | 49 | fs_save = get_fs(); |
| 49 | set_fs(get_ds()); | 50 | set_fs(get_ds()); |
| 50 | rc = vfs_write(inode_info->lower_file, data, size, &offset); | 51 | rc = vfs_write(lower_file, data, size, &offset); |
| 51 | set_fs(fs_save); | 52 | set_fs(fs_save); |
| 52 | mark_inode_dirty_sync(ecryptfs_inode); | 53 | mark_inode_dirty_sync(ecryptfs_inode); |
| 53 | return rc; | 54 | return rc; |
| @@ -225,15 +226,16 @@ out: | |||
| 225 | int ecryptfs_read_lower(char *data, loff_t offset, size_t size, | 226 | int ecryptfs_read_lower(char *data, loff_t offset, size_t size, |
| 226 | struct inode *ecryptfs_inode) | 227 | struct inode *ecryptfs_inode) |
| 227 | { | 228 | { |
| 228 | struct ecryptfs_inode_info *inode_info = | 229 | struct file *lower_file; |
| 229 | ecryptfs_inode_to_private(ecryptfs_inode); | ||
| 230 | mm_segment_t fs_save; | 230 | mm_segment_t fs_save; |
| 231 | ssize_t rc; | 231 | ssize_t rc; |
| 232 | 232 | ||
| 233 | BUG_ON(!inode_info->lower_file); | 233 | lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file; |
| 234 | if (!lower_file) | ||
| 235 | return -EIO; | ||
| 234 | fs_save = get_fs(); | 236 | fs_save = get_fs(); |
| 235 | set_fs(get_ds()); | 237 | set_fs(get_ds()); |
| 236 | rc = vfs_read(inode_info->lower_file, data, size, &offset); | 238 | rc = vfs_read(lower_file, data, size, &offset); |
| 237 | set_fs(fs_save); | 239 | set_fs(fs_save); |
| 238 | return rc; | 240 | return rc; |
| 239 | } | 241 | } |
