| summaryrefslogtreecommitdiff |
| author | Jan Kara <jack@suse.cz> | 2011-07-14 12:47:44 (GMT) |
|---|---|---|
| committer | Jan Kara <jack@suse.cz> | 2011-07-14 12:47:44 (GMT) |
| commit | 7da281afbd78855773911f3b44d7d45efa04ec20 (patch) (side-by-side diff) | |
| tree | cea944498431af94f4118cfa08e5bb6d3b14b3c6 | |
| parent | e5cac1e7b72d9752ee2ed17462f9beb7a200dc11 (diff) | |
| parent | 1f1e5e88f7c81a0e4936349731910655ccf51ff8 (diff) | |
Merge branch 'SLE11-SP1' of ssh://kerncvs.suse.de/home/git/kernel-source into SLE11-SP1rpm-2.6.32.43-0.4
Conflicts:
series.conf
| -rw-r--r-- | kernel-source.changes | 6 | ||||
| -rw-r--r-- | patches.fixes/fs-d_validate-fixes.patch | 80 | ||||
| -rw-r--r-- | series.conf | 1 |
3 files changed, 87 insertions, 0 deletions
diff --git a/kernel-source.changes b/kernel-source.changes index 2f99b49..ef7cbe4 100644 --- a/kernel-source.changes +++ b/kernel-source.changes @@ -1,4 +1,10 @@ ------------------------------------------------------------------- +Thu Jul 14 14:25:48 CEST 2011 - mszeredi@suse.cz + +- patches.fixes/fs-d_validate-fixes.patch: fs: d_validate fixes + (bnc#701170). + +------------------------------------------------------------------- Thu Jul 14 14:16:46 CEST 2011 - jack@suse.cz - Disable: diff --git a/patches.fixes/fs-d_validate-fixes.patch b/patches.fixes/fs-d_validate-fixes.patch new file mode 100644 index 0000000..d5b89b5 --- a/dev/null +++ b/patches.fixes/fs-d_validate-fixes.patch @@ -0,0 +1,80 @@ +From 786a5e15b613a9cee4fc9139fc3113a5ab0fde79 Mon Sep 17 00:00:00 2001 +From: Nick Piggin <npiggin@kernel.dk> +Date: Fri, 7 Jan 2011 17:49:16 +1100 +Subject: [PATCH] fs: d_validate fixes +Patch-mainline: 2.6.38 +References: bnc#701170 + +d_validate has been broken for a long time. + +kmem_ptr_validate does not guarantee that a pointer can be dereferenced +if it can go away at any time. Even rcu_read_lock doesn't help, because +the pointer might be queued in RCU callbacks but not executed yet. + +So the parent cannot be checked, nor the name hashed. The dentry pointer +can not be touched until it can be verified under lock. Hashing simply +cannot be used. + +Instead, verify the parent/child relationship by traversing parent's +d_child list. It's slow, but only ncpfs and the destaged smbfs care +about it, at this point. + +Signed-off-by: Nick Piggin <npiggin@kernel.dk> +Acked-by: Miklos Szeredi <mszeredi@suse.cz> +--- + fs/dcache.c | 25 +++++++------------------ + 1 file changed, 7 insertions(+), 18 deletions(-) + +Index: linux-2.6.32-SLE11-SP1/fs/dcache.c +=================================================================== +--- linux-2.6.32-SLE11-SP1.orig/fs/dcache.c 2011-07-14 14:16:58.000000000 +0200 ++++ linux-2.6.32-SLE11-SP1/fs/dcache.c 2011-07-14 14:22:17.000000000 +0200 +@@ -1448,41 +1448,30 @@ struct dentry *d_hash_and_lookup(struct + } + + /** +- * d_validate - verify dentry provided from insecure source ++ * d_validate - verify dentry provided from insecure source (deprecated) + * @dentry: The dentry alleged to be valid child of @dparent + * @dparent: The parent dentry (known to be valid) + * + * An insecure source has sent us a dentry, here we verify it and dget() it. + * This is used by ncpfs in its readdir implementation. + * Zero is returned in the dentry is invalid. ++ * ++ * This function is slow for big directories, and deprecated, do not use it. + */ +- + int d_validate(struct dentry *dentry, struct dentry *dparent) + { +- struct hlist_head *base; +- struct hlist_node *lhp; +- +- /* Check whether the ptr might be valid at all.. */ +- if (!kmem_ptr_validate(dentry_cache, dentry)) +- goto out; +- +- if (dentry->d_parent != dparent) +- goto out; ++ struct dentry *child; + + spin_lock(&dcache_lock); +- base = d_hash(dparent, dentry->d_name.hash); +- hlist_for_each(lhp,base) { +- /* hlist_for_each_entry_rcu() not required for d_hash list +- * as it is parsed under dcache_lock +- */ +- if (dentry == hlist_entry(lhp, struct dentry, d_hash)) { ++ list_for_each_entry(child, &dparent->d_subdirs, d_u.d_child) { ++ if (dentry == child) { + __dget_locked(dentry); + spin_unlock(&dcache_lock); + return 1; + } + } + spin_unlock(&dcache_lock); +-out: ++ + return 0; + } + diff --git a/series.conf b/series.conf index 4bedecc..573e14d 100644 --- a/series.conf +++ b/series.conf @@ -1443,6 +1443,7 @@ - patches.fixes/writeback-stop-background-for-other-work.diff - patches.fixes/writeback-avoid-new-file-livelock.diff - patches.fixes/writeback-avoid-WB_SYNC_ALL-livelock.diff + patches.fixes/fs-d_validate-fixes.patch ######################################################## # Swap-over-NFS |