vfs: Don't exchange short filenames unconditionally. (Closes: #763700)
svn path=/dists/sid/linux/; revision=21937
This commit is contained in:
parent
1d43044d99
commit
53daffe22c
|
@ -225,6 +225,8 @@ linux (3.16.5-1) UNRELEASED; urgency=low
|
|||
* radeon: Don't check for installed firmware if driver is built-in
|
||||
(Closes: #763305)
|
||||
* Bump ABI to 3
|
||||
* vfs: fold swapping ->d_name.hash into switch_names()
|
||||
* vfs: Don't exchange "short" filenames unconditionally. (Closes: #763700)
|
||||
|
||||
[ Aurelien Jarno ]
|
||||
* [arm64] Change RTC_DRV_PL031 and RTC_DRV_XGENE from modules to built-ins
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
From: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Date: Wed, 24 Sep 2014 12:27:39 -0700
|
||||
Subject: fold swapping ->d_name.hash into switch_names()
|
||||
Origin: https://git.kernel.org/linus/a28ddb87cdddb0db57466ba7f59f831002f4340c
|
||||
|
||||
and do it along with ->d_name.len there
|
||||
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
||||
[bwh: Backported to 3.16: change __d_materialise_dentry() as well]
|
||||
---
|
||||
fs/dcache.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
--- a/fs/dcache.c
|
||||
+++ b/fs/dcache.c
|
||||
@@ -2441,7 +2441,7 @@ static void switch_names(struct dentry *
|
||||
}
|
||||
}
|
||||
}
|
||||
- swap(dentry->d_name.len, target->d_name.len);
|
||||
+ swap(dentry->d_name.hash_len, target->d_name.hash_len);
|
||||
}
|
||||
|
||||
static void dentry_lock_for_move(struct dentry *dentry, struct dentry *target)
|
||||
@@ -2540,7 +2540,6 @@ static void __d_move(struct dentry *dent
|
||||
|
||||
/* Switch the names.. */
|
||||
switch_names(dentry, target);
|
||||
- swap(dentry->d_name.hash, target->d_name.hash);
|
||||
|
||||
/* ... and switch the parents */
|
||||
if (IS_ROOT(dentry)) {
|
||||
@@ -2679,7 +2678,6 @@ static void __d_materialise_dentry(struc
|
||||
dparent = dentry->d_parent;
|
||||
|
||||
switch_names(dentry, anon);
|
||||
- swap(dentry->d_name.hash, anon->d_name.hash);
|
||||
|
||||
dentry->d_parent = dentry;
|
||||
list_del_init(&dentry->d_u.d_child);
|
115
debian/patches/bugfix/all/vfs-Don-t-exchange-short-filenames-unconditionally.patch
vendored
Normal file
115
debian/patches/bugfix/all/vfs-Don-t-exchange-short-filenames-unconditionally.patch
vendored
Normal file
|
@ -0,0 +1,115 @@
|
|||
From: Mikhail Efremov <sem@altlinux.org>
|
||||
Date: Wed, 24 Sep 2014 22:14:33 +0400
|
||||
Subject: vfs: Don't exchange "short" filenames unconditionally.
|
||||
Origin: https://git.kernel.org/linus/d2fa4a8476b911782f7e5167db18770222ac40c3
|
||||
|
||||
Only exchange source and destination filenames
|
||||
if flags contain RENAME_EXCHANGE.
|
||||
In case if executable file was running and replaced by
|
||||
other file /proc/PID/exe should still show correct file name,
|
||||
not the old name of the file by which it was replaced.
|
||||
|
||||
The scenario when this bug manifests itself was like this:
|
||||
* ALT Linux uses rpm and start-stop-daemon;
|
||||
* during a package upgrade rpm creates a temporary file
|
||||
for an executable to rename it upon successful unpacking;
|
||||
* start-stop-daemon is run subsequently and it obtains
|
||||
the (nonexistant) temporary filename via /proc/PID/exe
|
||||
thus failing to identify the running process.
|
||||
|
||||
Note that "long" filenames (> DNAiME_INLINE_LEN) are still
|
||||
exchanged without RENAME_EXCHANGE and this behaviour exists
|
||||
long enough (should be fixed too apparently).
|
||||
So this patch is just an interim workaround that restores
|
||||
behavior for "short" names as it was before changes
|
||||
introduced by commit da1ce0670c14 ("vfs: add cross-rename").
|
||||
|
||||
See https://lkml.org/lkml/2014/9/7/6 for details.
|
||||
|
||||
AV: the comments about being more careful with ->d_name.hash
|
||||
than with ->d_name.name are from back in 2.3.40s; they
|
||||
became obsolete by 2.3.60s, when we started to unhash the
|
||||
target instead of swapping hash chain positions followed
|
||||
by d_delete() as we used to do when dcache was first
|
||||
introduced.
|
||||
|
||||
Acked-by: Miklos Szeredi <mszeredi@suse.cz>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
|
||||
Cc: linux-fsdevel@vger.kernel.org
|
||||
Cc: stable@vger.kernel.org
|
||||
Fixes: da1ce0670c14 "vfs: add cross-rename"
|
||||
Signed-off-by: Mikhail Efremov <sem@altlinux.org>
|
||||
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
||||
[bwh: Backported to 3.16:
|
||||
- Adjust context
|
||||
- Change __d_materialise_dentry() as well]
|
||||
---
|
||||
fs/dcache.c | 27 ++++++++++++++++++---------
|
||||
1 file changed, 18 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/fs/dcache.c
|
||||
+++ b/fs/dcache.c
|
||||
@@ -2401,7 +2401,8 @@ void dentry_update_name_case(struct dent
|
||||
}
|
||||
EXPORT_SYMBOL(dentry_update_name_case);
|
||||
|
||||
-static void switch_names(struct dentry *dentry, struct dentry *target)
|
||||
+static void switch_names(struct dentry *dentry, struct dentry *target,
|
||||
+ bool exchange)
|
||||
{
|
||||
if (dname_external(target)) {
|
||||
if (dname_external(dentry)) {
|
||||
@@ -2435,6 +2436,12 @@ static void switch_names(struct dentry *
|
||||
*/
|
||||
unsigned int i;
|
||||
BUILD_BUG_ON(!IS_ALIGNED(DNAME_INLINE_LEN, sizeof(long)));
|
||||
+ if (!exchange) {
|
||||
+ memcpy(dentry->d_iname, target->d_name.name,
|
||||
+ target->d_name.len + 1);
|
||||
+ dentry->d_name.hash_len = target->d_name.hash_len;
|
||||
+ return;
|
||||
+ }
|
||||
for (i = 0; i < DNAME_INLINE_LEN / sizeof(long); i++) {
|
||||
swap(((long *) &dentry->d_iname)[i],
|
||||
((long *) &target->d_iname)[i]);
|
||||
@@ -2484,12 +2491,15 @@ static void dentry_unlock_parents_for_mo
|
||||
* When switching names, the actual string doesn't strictly have to
|
||||
* be preserved in the target - because we're dropping the target
|
||||
* anyway. As such, we can just do a simple memcpy() to copy over
|
||||
- * the new name before we switch.
|
||||
- *
|
||||
- * Note that we have to be a lot more careful about getting the hash
|
||||
- * switched - we have to switch the hash value properly even if it
|
||||
- * then no longer matches the actual (corrupted) string of the target.
|
||||
- * The hash value has to match the hash queue that the dentry is on..
|
||||
+ * the new name before we switch, unless we are going to rehash
|
||||
+ * it. Note that if we *do* unhash the target, we are not allowed
|
||||
+ * to rehash it without giving it a new name/hash key - whether
|
||||
+ * we swap or overwrite the names here, resulting name won't match
|
||||
+ * the reality in filesystem; it's only there for d_path() purposes.
|
||||
+ * Note that all of this is happening under rename_lock, so the
|
||||
+ * any hash lookup seeing it in the middle of manipulations will
|
||||
+ * be discarded anyway. So we do not care what happens to the hash
|
||||
+ * key in that case.
|
||||
*/
|
||||
/*
|
||||
* __d_move - move a dentry
|
||||
@@ -2539,7 +2549,7 @@ static void __d_move(struct dentry *dent
|
||||
list_del(&target->d_u.d_child);
|
||||
|
||||
/* Switch the names.. */
|
||||
- switch_names(dentry, target);
|
||||
+ switch_names(dentry, target, exchange);
|
||||
|
||||
/* ... and switch the parents */
|
||||
if (IS_ROOT(dentry)) {
|
||||
@@ -2677,7 +2687,7 @@ static void __d_materialise_dentry(struc
|
||||
|
||||
dparent = dentry->d_parent;
|
||||
|
||||
- switch_names(dentry, anon);
|
||||
+ switch_names(dentry, anon, false);
|
||||
|
||||
dentry->d_parent = dentry;
|
||||
list_del_init(&dentry->d_u.d_child);
|
|
@ -135,3 +135,5 @@ debian/revert-staging-sm7xxfb-remove-driver.patch
|
|||
features/all/sfc-Adding-PCI-ID-for-Solarflare-7000-series-40G-net.patch
|
||||
features/all/sfc-Add-40G-link-capability-decoding.patch
|
||||
bugfix/s390/s390-3215-fix-tty-output-containing-tabs.patch
|
||||
bugfix/all/fold-swapping-d_name.hash-into-switch_names.patch
|
||||
bugfix/all/vfs-Don-t-exchange-short-filenames-unconditionally.patch
|
||||
|
|
Loading…
Reference in New Issue