Home Home > GIT Browse > openSUSE-15.0
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2011-07-14 14:47:44 +0200
committerJan Kara <jack@suse.cz>2011-07-14 14:47:44 +0200
commit7da281afbd78855773911f3b44d7d45efa04ec20 (patch)
treecea944498431af94f4118cfa08e5bb6d3b14b3c6
parente5cac1e7b72d9752ee2ed17462f9beb7a200dc11 (diff)
parent1f1e5e88f7c81a0e4936349731910655ccf51ff8 (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.changes6
-rw-r--r--patches.fixes/fs-d_validate-fixes.patch80
-rw-r--r--series.conf1
3 files changed, 87 insertions, 0 deletions
diff --git a/kernel-source.changes b/kernel-source.changes
index 2f99b491f3..ef7cbe4a3e 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 0000000000..d5b89b51c9
--- /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 4bedecc39b..573e14d964 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