[PATCH 2/5] binderfs: prevent renaming the control dentry

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux