diff options
| -rw-r--r-- | fs/ecryptfs/main.c | 23 |
1 files changed, 21 insertions, 2 deletions
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; |
