From: Greg Kroah-Hartman Date: Mon, 29 Apr 2019 09:43:15 +0000 (+0200) Subject: 3.18-stable patches X-Git-Tag: v4.9.172~39 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=016f753f5e2eac75f69bf8ad96599deebf92c144;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: ceph-ensure-d_name-stability-in-ceph_dentry_hash.patch sunrpc-don-t-mark-uninitialised-items-as-valid.patch --- diff --git a/queue-3.18/ceph-ensure-d_name-stability-in-ceph_dentry_hash.patch b/queue-3.18/ceph-ensure-d_name-stability-in-ceph_dentry_hash.patch new file mode 100644 index 00000000000..800748343cd --- /dev/null +++ b/queue-3.18/ceph-ensure-d_name-stability-in-ceph_dentry_hash.patch @@ -0,0 +1,44 @@ +From 76a495d666e5043ffc315695f8241f5e94a98849 Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Wed, 17 Apr 2019 12:58:28 -0400 +Subject: ceph: ensure d_name stability in ceph_dentry_hash() + +From: Jeff Layton + +commit 76a495d666e5043ffc315695f8241f5e94a98849 upstream. + +Take the d_lock here to ensure that d_name doesn't change. + +Cc: stable@vger.kernel.org +Signed-off-by: Jeff Layton +Reviewed-by: "Yan, Zheng" +Signed-off-by: Ilya Dryomov +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ceph/dir.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/fs/ceph/dir.c ++++ b/fs/ceph/dir.c +@@ -1308,6 +1308,7 @@ void ceph_dentry_lru_del(struct dentry * + unsigned ceph_dentry_hash(struct inode *dir, struct dentry *dn) + { + struct ceph_inode_info *dci = ceph_inode(dir); ++ unsigned hash; + + switch (dci->i_dir_layout.dl_dir_hash) { + case 0: /* for backward compat */ +@@ -1315,8 +1316,11 @@ unsigned ceph_dentry_hash(struct inode * + return dn->d_name.hash; + + default: +- return ceph_str_hash(dci->i_dir_layout.dl_dir_hash, ++ spin_lock(&dn->d_lock); ++ hash = ceph_str_hash(dci->i_dir_layout.dl_dir_hash, + dn->d_name.name, dn->d_name.len); ++ spin_unlock(&dn->d_lock); ++ return hash; + } + } + diff --git a/queue-3.18/series b/queue-3.18/series index 2013c724830..2b469ffa798 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -1,3 +1,5 @@ mips-scall64-o32-fix-indirect-syscall-number-load.patch trace-fix-preempt_enable_no_resched-abuse.patch sched-numa-fix-a-possible-divide-by-zero.patch +ceph-ensure-d_name-stability-in-ceph_dentry_hash.patch +sunrpc-don-t-mark-uninitialised-items-as-valid.patch diff --git a/queue-3.18/sunrpc-don-t-mark-uninitialised-items-as-valid.patch b/queue-3.18/sunrpc-don-t-mark-uninitialised-items-as-valid.patch new file mode 100644 index 00000000000..32b97f741b8 --- /dev/null +++ b/queue-3.18/sunrpc-don-t-mark-uninitialised-items-as-valid.patch @@ -0,0 +1,57 @@ +From d58431eacb226222430940134d97bfd72f292fcd Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Fri, 5 Apr 2019 11:34:40 +1100 +Subject: sunrpc: don't mark uninitialised items as VALID. + +From: NeilBrown + +commit d58431eacb226222430940134d97bfd72f292fcd upstream. + +A recent commit added a call to cache_fresh_locked() +when an expired item was found. +The call sets the CACHE_VALID flag, so it is important +that the item actually is valid. +There are two ways it could be valid: +1/ If ->update has been called to fill in relevant content +2/ if CACHE_NEGATIVE is set, to say that content doesn't exist. + +An expired item that is waiting for an update will be neither. +Setting CACHE_VALID will mean that a subsequent call to cache_put() +will be likely to dereference uninitialised pointers. + +So we must make sure the item is valid, and we already have code to do +that in try_to_negate_entry(). This takes the hash lock and so cannot +be used directly, so take out the two lines that we need and use them. + +Now cache_fresh_locked() is certain to be called only on +a valid item. + +Cc: stable@kernel.org # 2.6.35 +Fixes: 4ecd55ea0742 ("sunrpc: fix cache_head leak due to queued request") +Signed-off-by: NeilBrown +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + net/sunrpc/cache.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/sunrpc/cache.c ++++ b/net/sunrpc/cache.c +@@ -50,6 +50,7 @@ static void cache_init(struct cache_head + h->last_refresh = now; + } + ++static inline int cache_is_valid(struct cache_head *h); + static void cache_fresh_locked(struct cache_head *head, time_t expiry); + static void cache_fresh_unlocked(struct cache_head *head, + struct cache_detail *detail); +@@ -98,6 +99,8 @@ struct cache_head *sunrpc_cache_lookup(s + *hp = tmp->next; + tmp->next = NULL; + detail->entries --; ++ if (cache_is_valid(tmp) == -EAGAIN) ++ set_bit(CACHE_NEGATIVE, &tmp->flags); + cache_fresh_locked(tmp, 0); + freeme = tmp; + break;