We don't allow to unlink it since it is crucial for binderfs to be useable but if we allow to rename it we make the unlink trivial to bypass. So prevent renaming too and simply treat the control dentry as immutable. Take the opportunity and turn the check for the control dentry into a separate helper is_binderfs_control_device() since it's now used in two places. Additionally, replace the custom rename dance we did with call to simple_rename(). Suggested-by: Al Viro <viro@xxxxxxxxxxxxxxxxxx> Signed-off-by: Christian Brauner <christian@xxxxxxxxxx> --- drivers/android/binderfs.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/drivers/android/binderfs.c b/drivers/android/binderfs.c index 898d847f8505..02c96b5edfa9 100644 --- a/drivers/android/binderfs.c +++ b/drivers/android/binderfs.c @@ -346,34 +346,33 @@ static const struct super_operations binderfs_super_ops = { .statfs = simple_statfs, }; +static inline bool is_binderfs_control_device(const struct inode *inode, + const struct dentry *dentry) +{ + return BINDERFS_I(inode)->control_dentry == dentry; +} + static int binderfs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) { - struct inode *inode = d_inode(old_dentry); - - /* binderfs doesn't support directories. */ - if (d_is_dir(old_dentry)) - return -EPERM; + const struct inode *inode = d_inode(old_dentry); - if (flags & ~RENAME_NOREPLACE) - return -EINVAL; - - if (!simple_empty(new_dentry)) - return -ENOTEMPTY; - - if (d_really_is_positive(new_dentry)) - simple_unlink(new_dir, new_dentry); + if (is_binderfs_device(d_inode(old_dentry))) + inode = d_inode(old_dentry); + else + inode = d_inode(new_dentry); - old_dir->i_ctime = old_dir->i_mtime = new_dir->i_ctime = - new_dir->i_mtime = inode->i_ctime = current_time(old_dir); + if (is_binderfs_control_device(inode, old_dentry) || + is_binderfs_control_device(inode, new_dentry)) + return -EPERM; - return 0; + return simple_rename(old_dir, old_dentry, new_dir, new_dentry, flags); } static int binderfs_unlink(struct inode *dir, struct dentry *dentry) { - if (BINDERFS_I(dir)->control_dentry == dentry) + if (is_binderfs_control_device(dir, dentry)) return -EPERM; return simple_unlink(dir, dentry); -- 2.19.1 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel