Skip to content

Commit 7643554

Browse files
John JohansenTyler Hicks
John Johansen
authored and
Tyler Hicks
committed
Ecryptfs: Add mount option to check uid of device being mounted = expect uid
Close a TOCTOU race for mounts done via ecryptfs-mount-private. The mount source (device) can be raced when the ownership test is done in userspace. Provide Ecryptfs a means to force the uid check at mount time. Signed-off-by: John Johansen <[email protected]> Cc: <[email protected]> Signed-off-by: Tyler Hicks <[email protected]>
1 parent 99b373f commit 7643554

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

fs/ecryptfs/main.c

+21-2
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig,
175175
ecryptfs_opt_encrypted_view, ecryptfs_opt_fnek_sig,
176176
ecryptfs_opt_fn_cipher, ecryptfs_opt_fn_cipher_key_bytes,
177177
ecryptfs_opt_unlink_sigs, ecryptfs_opt_mount_auth_tok_only,
178+
ecryptfs_opt_check_dev_ruid,
178179
ecryptfs_opt_err };
179180

180181
static const match_table_t tokens = {
@@ -191,6 +192,7 @@ static const match_table_t tokens = {
191192
{ecryptfs_opt_fn_cipher_key_bytes, "ecryptfs_fn_key_bytes=%u"},
192193
{ecryptfs_opt_unlink_sigs, "ecryptfs_unlink_sigs"},
193194
{ecryptfs_opt_mount_auth_tok_only, "ecryptfs_mount_auth_tok_only"},
195+
{ecryptfs_opt_check_dev_ruid, "ecryptfs_check_dev_ruid"},
194196
{ecryptfs_opt_err, NULL}
195197
};
196198

@@ -236,6 +238,7 @@ static void ecryptfs_init_mount_crypt_stat(
236238
* ecryptfs_parse_options
237239
* @sb: The ecryptfs super block
238240
* @options: The options passed to the kernel
241+
* @check_ruid: set to 1 if device uid should be checked against the ruid
239242
*
240243
* Parse mount options:
241244
* debug=N - ecryptfs_verbosity level for debug output
@@ -251,7 +254,8 @@ static void ecryptfs_init_mount_crypt_stat(
251254
*
252255
* Returns zero on success; non-zero on error
253256
*/
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)
255259
{
256260
char *p;
257261
int rc = 0;
@@ -276,6 +280,8 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options)
276280
char *cipher_key_bytes_src;
277281
char *fn_cipher_key_bytes_src;
278282

283+
*check_ruid = 0;
284+
279285
if (!options) {
280286
rc = -EINVAL;
281287
goto out;
@@ -380,6 +386,9 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options)
380386
mount_crypt_stat->flags |=
381387
ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY;
382388
break;
389+
case ecryptfs_opt_check_dev_ruid:
390+
*check_ruid = 1;
391+
break;
383392
case ecryptfs_opt_err:
384393
default:
385394
printk(KERN_WARNING
@@ -475,6 +484,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
475484
const char *err = "Getting sb failed";
476485
struct inode *inode;
477486
struct path path;
487+
uid_t check_ruid;
478488
int rc;
479489

480490
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
483493
goto out;
484494
}
485495

486-
rc = ecryptfs_parse_options(sbi, raw_data);
496+
rc = ecryptfs_parse_options(sbi, raw_data, &check_ruid);
487497
if (rc) {
488498
err = "Error parsing options";
489499
goto out;
@@ -521,6 +531,15 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
521531
"known incompatibilities\n");
522532
goto out_free;
523533
}
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+
524543
ecryptfs_set_superblock_lower(s, path.dentry->d_sb);
525544
s->s_maxbytes = path.dentry->d_sb->s_maxbytes;
526545
s->s_blocksize = path.dentry->d_sb->s_blocksize;

0 commit comments

Comments
 (0)