diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-12 14:57:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-12 14:57:01 -0400 |
commit | ff812d724254b95df76b7775d1359d856927a840 (patch) | |
tree | fa9dcbb1cc43aa0171a9cbaf4e668d6866d3cd20 | |
parent | 5223161dc0f5e44fbf3d5e42d23697b6796cdf4e (diff) |
vfs: don't copy things to user space holding the rcu readlock
Oops. That wasn't very smart. We don't actually need the RCU lock any
more by the time we copy the cwd string to user space, but I had
stupidly surrounded the whole thing with it.
Introduced by commit 8b19e34188a3 ("vfs: make getcwd() get the root and
pwd path under rcu")
Is-a-big-hairy-idiot: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/dcache.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 99d4d7226203..29d58212aaf0 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -3067,6 +3067,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) | |||
3067 | prepend(&cwd, &buflen, "\0", 1); | 3067 | prepend(&cwd, &buflen, "\0", 1); |
3068 | error = prepend_path(&pwd, &root, &cwd, &buflen); | 3068 | error = prepend_path(&pwd, &root, &cwd, &buflen); |
3069 | br_read_unlock(&vfsmount_lock); | 3069 | br_read_unlock(&vfsmount_lock); |
3070 | rcu_read_unlock(); | ||
3070 | 3071 | ||
3071 | if (error < 0) | 3072 | if (error < 0) |
3072 | goto out; | 3073 | goto out; |
@@ -3087,10 +3088,10 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) | |||
3087 | } | 3088 | } |
3088 | } else { | 3089 | } else { |
3089 | br_read_unlock(&vfsmount_lock); | 3090 | br_read_unlock(&vfsmount_lock); |
3091 | rcu_read_unlock(); | ||
3090 | } | 3092 | } |
3091 | 3093 | ||
3092 | out: | 3094 | out: |
3093 | rcu_read_unlock(); | ||
3094 | free_page((unsigned long) page); | 3095 | free_page((unsigned long) page); |
3095 | return error; | 3096 | return error; |
3096 | } | 3097 | } |