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

Commit 38f49a51 authored by Eric W. Biederman's avatar Eric W. Biederman Committed by Greg Kroah-Hartman
Browse files

sysfs: only access bin file vm_ops with the active lock



bb->vm_ops is a cached copy of the vm_ops of the underlying
sysfs bin file, which means that after sysfs_bin_remove_file
completes it is only longer valid to deference bb->vm_ops.

So move all of the tests of bb->vm_ops inside of where
we hold the sysfs active lock.

Signed-off-by: default avatarEric W. Biederman <ebiederm@aristanetworks.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent a6849fa1
Loading
Loading
Loading
Loading
+26 −16
Original line number Diff line number Diff line
@@ -179,12 +179,13 @@ static void bin_vma_open(struct vm_area_struct *vma)
	struct bin_buffer *bb = file->private_data;
	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;

	if (!bb->vm_ops || !bb->vm_ops->open)
	if (!bb->vm_ops)
		return;

	if (!sysfs_get_active(attr_sd))
		return;

	if (bb->vm_ops->open)
		bb->vm_ops->open(vma);

	sysfs_put_active(attr_sd);
@@ -197,12 +198,14 @@ static int bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
	int ret;

	if (!bb->vm_ops || !bb->vm_ops->fault)
	if (!bb->vm_ops)
		return VM_FAULT_SIGBUS;

	if (!sysfs_get_active(attr_sd))
		return VM_FAULT_SIGBUS;

	ret = VM_FAULT_SIGBUS;
	if (bb->vm_ops->fault)
		ret = bb->vm_ops->fault(vma, vmf);

	sysfs_put_active(attr_sd);
@@ -219,12 +222,11 @@ static int bin_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
	if (!bb->vm_ops)
		return VM_FAULT_SIGBUS;

	if (!bb->vm_ops->page_mkwrite)
		return 0;

	if (!sysfs_get_active(attr_sd))
		return VM_FAULT_SIGBUS;

	ret = 0;
	if (bb->vm_ops->page_mkwrite)
		ret = bb->vm_ops->page_mkwrite(vma, vmf);

	sysfs_put_active(attr_sd);
@@ -239,12 +241,14 @@ static int bin_access(struct vm_area_struct *vma, unsigned long addr,
	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
	int ret;

	if (!bb->vm_ops || !bb->vm_ops->access)
	if (!bb->vm_ops)
		return -EINVAL;

	if (!sysfs_get_active(attr_sd))
		return -EINVAL;

	ret = -EINVAL;
	if (bb->vm_ops->access)
		ret = bb->vm_ops->access(vma, addr, buf, len, write);

	sysfs_put_active(attr_sd);
@@ -259,12 +263,14 @@ static int bin_set_policy(struct vm_area_struct *vma, struct mempolicy *new)
	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
	int ret;

	if (!bb->vm_ops || !bb->vm_ops->set_policy)
	if (!bb->vm_ops)
		return 0;

	if (!sysfs_get_active(attr_sd))
		return -EINVAL;

	ret = 0;
	if (bb->vm_ops->set_policy)
		ret = bb->vm_ops->set_policy(vma, new);

	sysfs_put_active(attr_sd);
@@ -279,12 +285,14 @@ static struct mempolicy *bin_get_policy(struct vm_area_struct *vma,
	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
	struct mempolicy *pol;

	if (!bb->vm_ops || !bb->vm_ops->get_policy)
	if (!bb->vm_ops)
		return vma->vm_policy;

	if (!sysfs_get_active(attr_sd))
		return vma->vm_policy;

	pol = vma->vm_policy;
	if (bb->vm_ops->get_policy)
		pol = bb->vm_ops->get_policy(vma, addr);

	sysfs_put_active(attr_sd);
@@ -299,12 +307,14 @@ static int bin_migrate(struct vm_area_struct *vma, const nodemask_t *from,
	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
	int ret;

	if (!bb->vm_ops || !bb->vm_ops->migrate)
	if (!bb->vm_ops)
		return 0;

	if (!sysfs_get_active(attr_sd))
		return 0;

	ret = 0;
	if (bb->vm_ops->migrate)
		ret = bb->vm_ops->migrate(vma, from, to, flags);

	sysfs_put_active(attr_sd);