Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 87c091ea authored by Christian Brauner's avatar Christian Brauner Committed by Hridya Valsaraju
Browse files

UPSTREAM: binderfs: rework binderfs_binder_device_create()



- switch from d_alloc_name() + d_lookup() to lookup_one_len():
  Instead of using d_alloc_name() and then doing a d_lookup() with the
  allocated dentry to find whether a device with the name we're trying to
  create already exists switch to using lookup_one_len().  The latter will
  either return the existing dentry or a new one.

- switch from kmalloc() + strscpy() to kmemdup():
  Use a more idiomatic way to copy the name for the new dentry that
  userspace gave us.

Suggested-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarChristian Brauner <christian@brauner.io>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>

Bug: 136497735
(cherry picked from commit 01b3f1fc568352a1ffdcd3ee82a0297f16cc9bd9)
Change-Id: I993a7dfa2f48bc6deb305852ff4085dc8dcaae4d
Signed-off-by: default avatarHridya Valsaraju <hridya@google.com>
parent 34ffb8ef
Loading
Loading
Loading
Loading
+19 −20
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include <linux/kdev_t.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/namei.h>
#include <linux/magic.h>
#include <linux/major.h>
#include <linux/miscdevice.h>
@@ -106,7 +107,7 @@ bool is_binderfs_device(const struct inode *inode)
 * @userp:     buffer to copy information about new device for userspace to
 * @req:       struct binderfs_device as copied from userspace
 *
 * This function allocated a new binder_device and reserves a new minor
 * This function allocates a new binder_device and reserves a new minor
 * number for it.
 * Minor numbers are limited and tracked globally in binderfs_minors. The
 * function will stash a struct binder_device for the specific binder
@@ -122,10 +123,10 @@ static int binderfs_binder_device_create(struct inode *ref_inode,
					 struct binderfs_device *req)
{
	int minor, ret;
	struct dentry *dentry, *dup, *root;
	struct dentry *dentry, *root;
	struct binder_device *device;
	size_t name_len = BINDERFS_MAX_NAME + 1;
	char *name = NULL;
	size_t name_len;
	struct inode *inode = NULL;
	struct super_block *sb = ref_inode->i_sb;
	struct binderfs_info *info = sb->s_fs_info;
@@ -168,12 +169,13 @@ static int binderfs_binder_device_create(struct inode *ref_inode,
	inode->i_uid = info->root_uid;
	inode->i_gid = info->root_gid;

	name = kmalloc(name_len, GFP_KERNEL);
	req->name[BINDERFS_MAX_NAME] = '\0'; /* NUL-terminate */
	name_len = strlen(req->name);
	/* Make sure to include terminating NUL byte */
	name = kmemdup(req->name, name_len + 1, GFP_KERNEL);
	if (!name)
		goto err;

	strscpy(name, req->name, name_len);

	device->binderfs_inode = inode;
	device->context.binder_context_mgr_uid = INVALID_UID;
	device->context.name = name;
@@ -192,25 +194,22 @@ static int binderfs_binder_device_create(struct inode *ref_inode,

	root = sb->s_root;
	inode_lock(d_inode(root));
	dentry = d_alloc_name(root, name);
	if (!dentry) {

	/* look it up */
	dentry = lookup_one_len(name, root, name_len);
	if (IS_ERR(dentry)) {
		inode_unlock(d_inode(root));
		ret = -ENOMEM;
		ret = PTR_ERR(dentry);
		goto err;
	}

	/* Verify that the name userspace gave us is not already in use. */
	dup = d_lookup(root, &dentry->d_name);
	if (dup) {
		if (d_really_is_positive(dup)) {
			dput(dup);
	if (d_really_is_positive(dentry)) {
		/* already exists */
		dput(dentry);
		inode_unlock(d_inode(root));
		ret = -EEXIST;
		goto err;
	}
		dput(dup);
	}

	inode->i_private = device;
	d_add(dentry, inode);