Skip to content

Commit 6521f89

Browse files
author
Christian Brauner
committed
namei: prepare for idmapped mounts
The various vfs_*() helpers are called by filesystems or by the vfs itself to perform core operations such as create, link, mkdir, mknod, rename, rmdir, tmpfile and unlink. Enable them to handle idmapped mounts. If the inode is accessed through an idmapped mount map it into the mount's user namespace and pass it down. Afterwards the checks and operations are identical to non-idmapped mounts. If the initial user namespace is passed nothing changes so non-idmapped mounts will see identical behavior as before. Link: https://lore.kernel.org/r/[email protected] Cc: Christoph Hellwig <[email protected]> Cc: David Howells <[email protected]> Cc: Al Viro <[email protected]> Cc: [email protected] Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent 9fe6145 commit 6521f89

File tree

12 files changed

+279
-105
lines changed

12 files changed

+279
-105
lines changed

drivers/base/devtmpfs.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ static int dev_mkdir(const char *name, umode_t mode)
162162
if (IS_ERR(dentry))
163163
return PTR_ERR(dentry);
164164

165-
err = vfs_mkdir(d_inode(path.dentry), dentry, mode);
165+
err = vfs_mkdir(&init_user_ns, d_inode(path.dentry), dentry, mode);
166166
if (!err)
167167
/* mark as kernel-created inode */
168168
d_inode(dentry)->i_private = &thread;
@@ -212,7 +212,8 @@ static int handle_create(const char *nodename, umode_t mode, kuid_t uid,
212212
if (IS_ERR(dentry))
213213
return PTR_ERR(dentry);
214214

215-
err = vfs_mknod(d_inode(path.dentry), dentry, mode, dev->devt);
215+
err = vfs_mknod(&init_user_ns, d_inode(path.dentry), dentry, mode,
216+
dev->devt);
216217
if (!err) {
217218
struct iattr newattrs;
218219

@@ -242,7 +243,8 @@ static int dev_rmdir(const char *name)
242243
return PTR_ERR(dentry);
243244
if (d_really_is_positive(dentry)) {
244245
if (d_inode(dentry)->i_private == &thread)
245-
err = vfs_rmdir(d_inode(parent.dentry), dentry);
246+
err = vfs_rmdir(&init_user_ns, d_inode(parent.dentry),
247+
dentry);
246248
else
247249
err = -EPERM;
248250
} else {
@@ -330,7 +332,8 @@ static int handle_remove(const char *nodename, struct device *dev)
330332
inode_lock(d_inode(dentry));
331333
notify_change(&init_user_ns, dentry, &newattrs, NULL);
332334
inode_unlock(d_inode(dentry));
333-
err = vfs_unlink(d_inode(parent.dentry), dentry, NULL);
335+
err = vfs_unlink(&init_user_ns, d_inode(parent.dentry),
336+
dentry, NULL);
334337
if (!err || err == -ENOENT)
335338
deleted = 1;
336339
}

fs/cachefiles/namei.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,8 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
311311
cachefiles_io_error(cache, "Unlink security error");
312312
} else {
313313
trace_cachefiles_unlink(object, rep, why);
314-
ret = vfs_unlink(d_inode(dir), rep, NULL);
314+
ret = vfs_unlink(&init_user_ns, d_inode(dir), rep,
315+
NULL);
315316

316317
if (preemptive)
317318
cachefiles_mark_object_buried(cache, rep, why);
@@ -413,8 +414,10 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
413414
cachefiles_io_error(cache, "Rename security error %d", ret);
414415
} else {
415416
struct renamedata rd = {
417+
.old_mnt_userns = &init_user_ns,
416418
.old_dir = d_inode(dir),
417419
.old_dentry = rep,
420+
.new_mnt_userns = &init_user_ns,
418421
.new_dir = d_inode(cache->graveyard),
419422
.new_dentry = grave,
420423
};
@@ -566,7 +569,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
566569
if (ret < 0)
567570
goto create_error;
568571
start = jiffies;
569-
ret = vfs_mkdir(d_inode(dir), next, 0);
572+
ret = vfs_mkdir(&init_user_ns, d_inode(dir), next, 0);
570573
cachefiles_hist(cachefiles_mkdir_histogram, start);
571574
if (!key)
572575
trace_cachefiles_mkdir(object, next, ret);
@@ -602,7 +605,8 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
602605
if (ret < 0)
603606
goto create_error;
604607
start = jiffies;
605-
ret = vfs_create(d_inode(dir), next, S_IFREG, true);
608+
ret = vfs_create(&init_user_ns, d_inode(dir), next,
609+
S_IFREG, true);
606610
cachefiles_hist(cachefiles_create_histogram, start);
607611
trace_cachefiles_create(object, next, ret);
608612
if (ret < 0)
@@ -796,7 +800,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
796800
ret = security_path_mkdir(&path, subdir, 0700);
797801
if (ret < 0)
798802
goto mkdir_error;
799-
ret = vfs_mkdir(d_inode(dir), subdir, 0700);
803+
ret = vfs_mkdir(&init_user_ns, d_inode(dir), subdir, 0700);
800804
if (ret < 0)
801805
goto mkdir_error;
802806

fs/ecryptfs/inode.c

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry,
141141
else if (d_unhashed(lower_dentry))
142142
rc = -EINVAL;
143143
else
144-
rc = vfs_unlink(lower_dir_inode, lower_dentry, NULL);
144+
rc = vfs_unlink(&init_user_ns, lower_dir_inode, lower_dentry,
145+
NULL);
145146
if (rc) {
146147
printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
147148
goto out_unlock;
@@ -180,7 +181,8 @@ ecryptfs_do_create(struct inode *directory_inode,
180181

181182
lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
182183
lower_dir_dentry = lock_parent(lower_dentry);
183-
rc = vfs_create(d_inode(lower_dir_dentry), lower_dentry, mode, true);
184+
rc = vfs_create(&init_user_ns, d_inode(lower_dir_dentry), lower_dentry,
185+
mode, true);
184186
if (rc) {
185187
printk(KERN_ERR "%s: Failure to create dentry in lower fs; "
186188
"rc = [%d]\n", __func__, rc);
@@ -190,7 +192,8 @@ ecryptfs_do_create(struct inode *directory_inode,
190192
inode = __ecryptfs_get_inode(d_inode(lower_dentry),
191193
directory_inode->i_sb);
192194
if (IS_ERR(inode)) {
193-
vfs_unlink(d_inode(lower_dir_dentry), lower_dentry, NULL);
195+
vfs_unlink(&init_user_ns, d_inode(lower_dir_dentry),
196+
lower_dentry, NULL);
194197
goto out_lock;
195198
}
196199
fsstack_copy_attr_times(directory_inode, d_inode(lower_dir_dentry));
@@ -436,8 +439,8 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir,
436439
dget(lower_old_dentry);
437440
dget(lower_new_dentry);
438441
lower_dir_dentry = lock_parent(lower_new_dentry);
439-
rc = vfs_link(lower_old_dentry, d_inode(lower_dir_dentry),
440-
lower_new_dentry, NULL);
442+
rc = vfs_link(lower_old_dentry, &init_user_ns,
443+
d_inode(lower_dir_dentry), lower_new_dentry, NULL);
441444
if (rc || d_really_is_negative(lower_new_dentry))
442445
goto out_lock;
443446
rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb);
@@ -481,7 +484,7 @@ static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry,
481484
strlen(symname));
482485
if (rc)
483486
goto out_lock;
484-
rc = vfs_symlink(d_inode(lower_dir_dentry), lower_dentry,
487+
rc = vfs_symlink(&init_user_ns, d_inode(lower_dir_dentry), lower_dentry,
485488
encoded_symname);
486489
kfree(encoded_symname);
487490
if (rc || d_really_is_negative(lower_dentry))
@@ -507,7 +510,8 @@ static int ecryptfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
507510

508511
lower_dentry = ecryptfs_dentry_to_lower(dentry);
509512
lower_dir_dentry = lock_parent(lower_dentry);
510-
rc = vfs_mkdir(d_inode(lower_dir_dentry), lower_dentry, mode);
513+
rc = vfs_mkdir(&init_user_ns, d_inode(lower_dir_dentry), lower_dentry,
514+
mode);
511515
if (rc || d_really_is_negative(lower_dentry))
512516
goto out;
513517
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
@@ -541,7 +545,7 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
541545
else if (d_unhashed(lower_dentry))
542546
rc = -EINVAL;
543547
else
544-
rc = vfs_rmdir(lower_dir_inode, lower_dentry);
548+
rc = vfs_rmdir(&init_user_ns, lower_dir_inode, lower_dentry);
545549
if (!rc) {
546550
clear_nlink(d_inode(dentry));
547551
fsstack_copy_attr_times(dir, lower_dir_inode);
@@ -563,7 +567,8 @@ ecryptfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev
563567

564568
lower_dentry = ecryptfs_dentry_to_lower(dentry);
565569
lower_dir_dentry = lock_parent(lower_dentry);
566-
rc = vfs_mknod(d_inode(lower_dir_dentry), lower_dentry, mode, dev);
570+
rc = vfs_mknod(&init_user_ns, d_inode(lower_dir_dentry), lower_dentry,
571+
mode, dev);
567572
if (rc || d_really_is_negative(lower_dentry))
568573
goto out;
569574
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
@@ -621,10 +626,12 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
621626
goto out_lock;
622627
}
623628

624-
rd.old_dir = d_inode(lower_old_dir_dentry);
625-
rd.old_dentry = lower_old_dentry;
626-
rd.new_dir = d_inode(lower_new_dir_dentry);
627-
rd.new_dentry = lower_new_dentry;
629+
rd.old_mnt_userns = &init_user_ns;
630+
rd.old_dir = d_inode(lower_old_dir_dentry);
631+
rd.old_dentry = lower_old_dentry;
632+
rd.new_mnt_userns = &init_user_ns;
633+
rd.new_dir = d_inode(lower_new_dir_dentry);
634+
rd.new_dentry = lower_new_dentry;
628635
rc = vfs_rename(&rd);
629636
if (rc)
630637
goto out_lock;

fs/init.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,8 @@ int __init init_mknod(const char *filename, umode_t mode, unsigned int dev)
157157
mode &= ~current_umask();
158158
error = security_path_mknod(&path, dentry, mode, dev);
159159
if (!error)
160-
error = vfs_mknod(path.dentry->d_inode, dentry, mode,
161-
new_decode_dev(dev));
160+
error = vfs_mknod(&init_user_ns, path.dentry->d_inode, dentry,
161+
mode, new_decode_dev(dev));
162162
done_path_create(&path, dentry);
163163
return error;
164164
}
@@ -187,8 +187,8 @@ int __init init_link(const char *oldname, const char *newname)
187187
error = security_path_link(old_path.dentry, &new_path, new_dentry);
188188
if (error)
189189
goto out_dput;
190-
error = vfs_link(old_path.dentry, new_path.dentry->d_inode, new_dentry,
191-
NULL);
190+
error = vfs_link(old_path.dentry, &init_user_ns,
191+
new_path.dentry->d_inode, new_dentry, NULL);
192192
out_dput:
193193
done_path_create(&new_path, new_dentry);
194194
out:
@@ -207,7 +207,8 @@ int __init init_symlink(const char *oldname, const char *newname)
207207
return PTR_ERR(dentry);
208208
error = security_path_symlink(&path, dentry, oldname);
209209
if (!error)
210-
error = vfs_symlink(path.dentry->d_inode, dentry, oldname);
210+
error = vfs_symlink(&init_user_ns, path.dentry->d_inode, dentry,
211+
oldname);
211212
done_path_create(&path, dentry);
212213
return error;
213214
}
@@ -230,7 +231,8 @@ int __init init_mkdir(const char *pathname, umode_t mode)
230231
mode &= ~current_umask();
231232
error = security_path_mkdir(&path, dentry, mode);
232233
if (!error)
233-
error = vfs_mkdir(path.dentry->d_inode, dentry, mode);
234+
error = vfs_mkdir(&init_user_ns, path.dentry->d_inode, dentry,
235+
mode);
234236
done_path_create(&path, dentry);
235237
return error;
236238
}

0 commit comments

Comments
 (0)