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

Commit 8aa09a50 authored by Miklos Szeredi's avatar Miklos Szeredi
Browse files

[fuse] fix race between checking and setting file->private_data



BKL does not protect against races if the task may sleep between
checking and setting a value.  So move checking of file->private_data
near to setting it in fuse_fill_super().

Found by Al Viro.

Signed-off-by: default avatarMiklos Szeredi <miklos@szeredi.hu>
parent 6dbbcb12
Loading
Loading
Loading
Loading
+8 −5
Original line number Original line Diff line number Diff line
@@ -500,11 +500,6 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
	if (file->f_op != &fuse_dev_operations)
	if (file->f_op != &fuse_dev_operations)
		return -EINVAL;
		return -EINVAL;


	/* Setting file->private_data can't race with other mount()
	   instances, since BKL is held for ->get_sb() */
	if (file->private_data)
		return -EINVAL;

	fc = new_conn();
	fc = new_conn();
	if (!fc)
	if (!fc)
		return -ENOMEM;
		return -ENOMEM;
@@ -540,6 +535,12 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
	if (err)
	if (err)
		goto err_free_req;
		goto err_free_req;


	/* Setting file->private_data can't race with other mount()
	   instances, since BKL is held for ->get_sb() */
	err = -EINVAL;
	if (file->private_data)
		goto err_kobject_del;

	sb->s_root = root_dentry;
	sb->s_root = root_dentry;
	fc->mounted = 1;
	fc->mounted = 1;
	fc->connected = 1;
	fc->connected = 1;
@@ -556,6 +557,8 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)


	return 0;
	return 0;


 err_kobject_del:
	kobject_del(&fc->kobj);
 err_free_req:
 err_free_req:
	fuse_request_free(init_req);
	fuse_request_free(init_req);
 err_put_root:
 err_put_root: