Commit d55140ce3a7b36241171bd78c75a5ee85de20439
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ecryptfs/ecryptfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ecryptfs/ecryptfs-2.6: Ecryptfs: Add mount option to check uid of device being mounted = expect uid eCryptfs: Fix payload_len unitialized variable warning eCryptfs: fix compile error eCryptfs: Return error when lower file pointer is NULL
Showing 4 changed files Side-by-side Diff
fs/ecryptfs/Kconfig
fs/ecryptfs/keystore.c
fs/ecryptfs/main.c
... | ... | @@ -175,6 +175,7 @@ |
175 | 175 | ecryptfs_opt_encrypted_view, ecryptfs_opt_fnek_sig, |
176 | 176 | ecryptfs_opt_fn_cipher, ecryptfs_opt_fn_cipher_key_bytes, |
177 | 177 | ecryptfs_opt_unlink_sigs, ecryptfs_opt_mount_auth_tok_only, |
178 | + ecryptfs_opt_check_dev_ruid, | |
178 | 179 | ecryptfs_opt_err }; |
179 | 180 | |
180 | 181 | static const match_table_t tokens = { |
... | ... | @@ -191,6 +192,7 @@ |
191 | 192 | {ecryptfs_opt_fn_cipher_key_bytes, "ecryptfs_fn_key_bytes=%u"}, |
192 | 193 | {ecryptfs_opt_unlink_sigs, "ecryptfs_unlink_sigs"}, |
193 | 194 | {ecryptfs_opt_mount_auth_tok_only, "ecryptfs_mount_auth_tok_only"}, |
195 | + {ecryptfs_opt_check_dev_ruid, "ecryptfs_check_dev_ruid"}, | |
194 | 196 | {ecryptfs_opt_err, NULL} |
195 | 197 | }; |
196 | 198 | |
... | ... | @@ -236,6 +238,7 @@ |
236 | 238 | * ecryptfs_parse_options |
237 | 239 | * @sb: The ecryptfs super block |
238 | 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 | 243 | * Parse mount options: |
241 | 244 | * debug=N - ecryptfs_verbosity level for debug output |
... | ... | @@ -251,7 +254,8 @@ |
251 | 254 | * |
252 | 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 | 260 | char *p; |
257 | 261 | int rc = 0; |
... | ... | @@ -276,6 +280,8 @@ |
276 | 280 | char *cipher_key_bytes_src; |
277 | 281 | char *fn_cipher_key_bytes_src; |
278 | 282 | |
283 | + *check_ruid = 0; | |
284 | + | |
279 | 285 | if (!options) { |
280 | 286 | rc = -EINVAL; |
281 | 287 | goto out; |
... | ... | @@ -380,6 +386,9 @@ |
380 | 386 | mount_crypt_stat->flags |= |
381 | 387 | ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY; |
382 | 388 | break; |
389 | + case ecryptfs_opt_check_dev_ruid: | |
390 | + *check_ruid = 1; | |
391 | + break; | |
383 | 392 | case ecryptfs_opt_err: |
384 | 393 | default: |
385 | 394 | printk(KERN_WARNING |
... | ... | @@ -475,6 +484,7 @@ |
475 | 484 | const char *err = "Getting sb failed"; |
476 | 485 | struct inode *inode; |
477 | 486 | struct path path; |
487 | + uid_t check_ruid; | |
478 | 488 | int rc; |
479 | 489 | |
480 | 490 | sbi = kmem_cache_zalloc(ecryptfs_sb_info_cache, GFP_KERNEL); |
... | ... | @@ -483,7 +493,7 @@ |
483 | 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 | 497 | if (rc) { |
488 | 498 | err = "Error parsing options"; |
489 | 499 | goto out; |
... | ... | @@ -521,6 +531,15 @@ |
521 | 531 | "known incompatibilities\n"); |
522 | 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 | 543 | ecryptfs_set_superblock_lower(s, path.dentry->d_sb); |
525 | 544 | s->s_maxbytes = path.dentry->d_sb->s_maxbytes; |
526 | 545 | s->s_blocksize = path.dentry->d_sb->s_blocksize; |
fs/ecryptfs/read_write.c
... | ... | @@ -39,15 +39,16 @@ |
39 | 39 | int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, |
40 | 40 | loff_t offset, size_t size) |
41 | 41 | { |
42 | - struct ecryptfs_inode_info *inode_info; | |
42 | + struct file *lower_file; | |
43 | 43 | mm_segment_t fs_save; |
44 | 44 | ssize_t rc; |
45 | 45 | |
46 | - inode_info = ecryptfs_inode_to_private(ecryptfs_inode); | |
47 | - BUG_ON(!inode_info->lower_file); | |
46 | + lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file; | |
47 | + if (!lower_file) | |
48 | + return -EIO; | |
48 | 49 | fs_save = get_fs(); |
49 | 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 | 52 | set_fs(fs_save); |
52 | 53 | mark_inode_dirty_sync(ecryptfs_inode); |
53 | 54 | return rc; |
54 | 55 | |
55 | 56 | |
... | ... | @@ -225,15 +226,16 @@ |
225 | 226 | int ecryptfs_read_lower(char *data, loff_t offset, size_t size, |
226 | 227 | struct inode *ecryptfs_inode) |
227 | 228 | { |
228 | - struct ecryptfs_inode_info *inode_info = | |
229 | - ecryptfs_inode_to_private(ecryptfs_inode); | |
229 | + struct file *lower_file; | |
230 | 230 | mm_segment_t fs_save; |
231 | 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 | 236 | fs_save = get_fs(); |
235 | 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 | 239 | set_fs(fs_save); |
238 | 240 | return rc; |
239 | 241 | } |