From: ebiederm@xmission.com (Eric W. Biederman)
To: Greg Kroah-Hartman <gregkh@suse.de>
Cc: <linux-kernel@vger.kernel.org>, Tejun Heo <tj@kernel.org>,
Hugh Dickins <hughd@google.com>
Subject: [PATCH 2/2] sysfs: only access bin file vm_ops with the active lock
Date: Mon, 20 Sep 2010 00:57:03 -0700 [thread overview]
Message-ID: <m1vd6026gg.fsf@fess.ebiederm.org> (raw)
In-Reply-To: <m1aanc3l3e.fsf@fess.ebiederm.org> (Eric W. Biederman's message of "Mon, 20 Sep 2010 00:55:33 -0700")
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: Eric W. Biederman <ebiederm@aristanetworks.com>
---
fs/sysfs/bin.c | 42 ++++++++++++++++++++++++++----------------
1 files changed, 26 insertions(+), 16 deletions(-)
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index d31d7b7..a475983 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -179,13 +179,14 @@ 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;
- bb->vm_ops->open(vma);
+ if (bb->vm_ops->open)
+ bb->vm_ops->open(vma);
sysfs_put_active(attr_sd);
}
@@ -197,13 +198,15 @@ 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 = bb->vm_ops->fault(vma, vmf);
+ ret = VM_FAULT_SIGBUS;
+ if (bb->vm_ops->fault)
+ ret = bb->vm_ops->fault(vma, vmf);
sysfs_put_active(attr_sd);
return ret;
@@ -219,13 +222,12 @@ 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 = bb->vm_ops->page_mkwrite(vma, vmf);
+ ret = 0;
+ if (bb->vm_ops->page_mkwrite)
+ ret = bb->vm_ops->page_mkwrite(vma, vmf);
sysfs_put_active(attr_sd);
return ret;
@@ -239,13 +241,15 @@ 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 = bb->vm_ops->access(vma, addr, buf, len, write);
+ ret = -EINVAL;
+ if (bb->vm_ops->access)
+ ret = bb->vm_ops->access(vma, addr, buf, len, write);
sysfs_put_active(attr_sd);
return ret;
@@ -259,13 +263,15 @@ 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 = bb->vm_ops->set_policy(vma, new);
+ ret = 0;
+ if (bb->vm_ops->set_policy)
+ ret = bb->vm_ops->set_policy(vma, new);
sysfs_put_active(attr_sd);
return ret;
@@ -279,13 +285,15 @@ 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 = bb->vm_ops->get_policy(vma, addr);
+ pol = vma->vm_policy;
+ if (bb->vm_ops->get_policy)
+ pol = bb->vm_ops->get_policy(vma, addr);
sysfs_put_active(attr_sd);
return pol;
@@ -299,13 +307,15 @@ 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 = bb->vm_ops->migrate(vma, from, to, flags);
+ ret = 0;
+ if (bb->vm_ops->migrate)
+ ret = bb->vm_ops->migrate(vma, from, to, flags);
sysfs_put_active(attr_sd);
return ret;
--
1.7.2.2
next prev parent reply other threads:[~2010-09-20 7:57 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-09-20 7:55 [PATCH 0/2] Fix mmap bugs with sysfs_remove_bin_file Eric W. Biederman
2010-09-20 7:56 ` [PATCH 1/2] sysfs: Fail bin file mmap if vma close is implemented Eric W. Biederman
2010-09-22 19:31 ` Hugh Dickins
2010-09-22 21:01 ` Eric W. Biederman
2010-09-20 7:57 ` Eric W. Biederman [this message]
2010-09-22 19:49 ` [PATCH 2/2] sysfs: only access bin file vm_ops with the active lock Hugh Dickins
2010-09-22 21:59 ` Eric W. Biederman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m1vd6026gg.fsf@fess.ebiederm.org \
--to=ebiederm@xmission.com \
--cc=gregkh@suse.de \
--cc=hughd@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=tj@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.