<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux-toradex.git/fs, branch v3.10.78</title>
<subtitle>Linux kernel for Apalis and Colibri modules</subtitle>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/'/>
<entry>
<title>ext4: fix data corruption caused by unwritten and delayed extents</title>
<updated>2015-05-13T12:15:42+00:00</updated>
<author>
<name>Lukas Czerner</name>
<email>lczerner@redhat.com</email>
</author>
<published>2015-05-03T01:36:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=5a7d1e16a425786d8f6f5d4f707bb4dc879499d1'/>
<id>5a7d1e16a425786d8f6f5d4f707bb4dc879499d1</id>
<content type='text'>
commit d2dc317d564a46dfc683978a2e5a4f91434e9711 upstream.

Currently it is possible to lose whole file system block worth of data
when we hit the specific interaction with unwritten and delayed extents
in status extent tree.

The problem is that when we insert delayed extent into extent status
tree the only way to get rid of it is when we write out delayed buffer.
However there is a limitation in the extent status tree implementation
so that when inserting unwritten extent should there be even a single
delayed block the whole unwritten extent would be marked as delayed.

At this point, there is no way to get rid of the delayed extents,
because there are no delayed buffers to write out. So when a we write
into said unwritten extent we will convert it to written, but it still
remains delayed.

When we try to write into that block later ext4_da_map_blocks() will set
the buffer new and delayed and map it to invalid block which causes
the rest of the block to be zeroed loosing already written data.

For now we can fix this by simply not allowing to set delayed status on
written extent in the extent status tree. Also add WARN_ON() to make
sure that we notice if this happens in the future.

This problem can be easily reproduced by running the following xfs_io.

xfs_io -f -c "pwrite -S 0xaa 4096 2048" \
          -c "falloc 0 131072" \
          -c "pwrite -S 0xbb 65536 2048" \
          -c "fsync" /mnt/test/fff

echo 3 &gt; /proc/sys/vm/drop_caches
xfs_io -c "pwrite -S 0xdd 67584 2048" /mnt/test/fff

This can be theoretically also reproduced by at random by running fsx,
but it's not very reliable, though on machines with bigger page size
(like ppc) this can be seen more often (especially xfstest generic/127)

Signed-off-by: Lukas Czerner &lt;lczerner@redhat.com&gt;
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit d2dc317d564a46dfc683978a2e5a4f91434e9711 upstream.

Currently it is possible to lose whole file system block worth of data
when we hit the specific interaction with unwritten and delayed extents
in status extent tree.

The problem is that when we insert delayed extent into extent status
tree the only way to get rid of it is when we write out delayed buffer.
However there is a limitation in the extent status tree implementation
so that when inserting unwritten extent should there be even a single
delayed block the whole unwritten extent would be marked as delayed.

At this point, there is no way to get rid of the delayed extents,
because there are no delayed buffers to write out. So when a we write
into said unwritten extent we will convert it to written, but it still
remains delayed.

When we try to write into that block later ext4_da_map_blocks() will set
the buffer new and delayed and map it to invalid block which causes
the rest of the block to be zeroed loosing already written data.

For now we can fix this by simply not allowing to set delayed status on
written extent in the extent status tree. Also add WARN_ON() to make
sure that we notice if this happens in the future.

This problem can be easily reproduced by running the following xfs_io.

xfs_io -f -c "pwrite -S 0xaa 4096 2048" \
          -c "falloc 0 131072" \
          -c "pwrite -S 0xbb 65536 2048" \
          -c "fsync" /mnt/test/fff

echo 3 &gt; /proc/sys/vm/drop_caches
xfs_io -c "pwrite -S 0xdd 67584 2048" /mnt/test/fff

This can be theoretically also reproduced by at random by running fsx,
but it's not very reliable, though on machines with bigger page size
(like ppc) this can be seen more often (especially xfstest generic/127)

Signed-off-by: Lukas Czerner &lt;lczerner@redhat.com&gt;
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</pre>
</div>
</content>
</entry>
<entry>
<title>RCU pathwalk breakage when running into a symlink overmounting something</title>
<updated>2015-05-06T19:56:27+00:00</updated>
<author>
<name>Al Viro</name>
<email>viro@zeniv.linux.org.uk</email>
</author>
<published>2015-04-24T19:47:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=3b388f33a1fc643f5e9dc496c741eafdf6ebef49'/>
<id>3b388f33a1fc643f5e9dc496c741eafdf6ebef49</id>
<content type='text'>
commit 3cab989afd8d8d1bc3d99fef0e7ed87c31e7b647 upstream.

Calling unlazy_walk() in walk_component() and do_last() when we find
a symlink that needs to be followed doesn't acquire a reference to vfsmount.
That's fine when the symlink is on the same vfsmount as the parent directory
(which is almost always the case), but it's not always true - one _can_
manage to bind a symlink on top of something.  And in such cases we end up
with excessive mntput().

Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 3cab989afd8d8d1bc3d99fef0e7ed87c31e7b647 upstream.

Calling unlazy_walk() in walk_component() and do_last() when we find
a symlink that needs to be followed doesn't acquire a reference to vfsmount.
That's fine when the symlink is on the same vfsmount as the parent directory
(which is almost always the case), but it's not always true - one _can_
manage to bind a symlink on top of something.  And in such cases we end up
with excessive mntput().

Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</pre>
</div>
</content>
</entry>
<entry>
<title>ext4: make fsync to sync parent dir in no-journal for real this time</title>
<updated>2015-05-06T19:56:25+00:00</updated>
<author>
<name>Lukas Czerner</name>
<email>lczerner@redhat.com</email>
</author>
<published>2015-04-03T14:46:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=72a2c0394991ca2785f4fda903aeec82d578376a'/>
<id>72a2c0394991ca2785f4fda903aeec82d578376a</id>
<content type='text'>
commit e12fb97222fc41e8442896934f76d39ef99b590a upstream.

Previously commit 14ece1028b3ed53ffec1b1213ffc6acaf79ad77c added a
support for for syncing parent directory of newly created inodes to
make sure that the inode is not lost after a power failure in
no-journal mode.

However this does not work in majority of cases, namely:
 - if the directory has inline data
 - if the directory is already indexed
 - if the directory already has at least one block and:
	- the new entry fits into it
	- or we've successfully converted it to indexed

So in those cases we might lose the inode entirely even after fsync in
the no-journal mode. This also includes ext2 default mode obviously.

I've noticed this while running xfstest generic/321 and even though the
test should fail (we need to run fsck after a crash in no-journal mode)
I could not find a newly created entries even when if it was fsynced
before.

Fix this by adjusting the ext4_add_entry() successful exit paths to set
the inode EXT4_STATE_NEWENTRY so that fsync has the chance to fsync the
parent directory as well.

Signed-off-by: Lukas Czerner &lt;lczerner@redhat.com&gt;
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Reviewed-by: Jan Kara &lt;jack@suse.cz&gt;
Cc: Frank Mayhar &lt;fmayhar@google.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit e12fb97222fc41e8442896934f76d39ef99b590a upstream.

Previously commit 14ece1028b3ed53ffec1b1213ffc6acaf79ad77c added a
support for for syncing parent directory of newly created inodes to
make sure that the inode is not lost after a power failure in
no-journal mode.

However this does not work in majority of cases, namely:
 - if the directory has inline data
 - if the directory is already indexed
 - if the directory already has at least one block and:
	- the new entry fits into it
	- or we've successfully converted it to indexed

So in those cases we might lose the inode entirely even after fsync in
the no-journal mode. This also includes ext2 default mode obviously.

I've noticed this while running xfstest generic/321 and even though the
test should fail (we need to run fsck after a crash in no-journal mode)
I could not find a newly created entries even when if it was fsynced
before.

Fix this by adjusting the ext4_add_entry() successful exit paths to set
the inode EXT4_STATE_NEWENTRY so that fsync has the chance to fsync the
parent directory as well.

Signed-off-by: Lukas Czerner &lt;lczerner@redhat.com&gt;
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Reviewed-by: Jan Kara &lt;jack@suse.cz&gt;
Cc: Frank Mayhar &lt;fmayhar@google.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</pre>
</div>
</content>
</entry>
<entry>
<title>fs/binfmt_elf.c: fix bug in loading of PIE binaries</title>
<updated>2015-05-06T19:56:24+00:00</updated>
<author>
<name>Michael Davidson</name>
<email>md@google.com</email>
</author>
<published>2015-04-14T22:47:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=00c65c8a660bd5b5d4228137ff5be2654dd1840a'/>
<id>00c65c8a660bd5b5d4228137ff5be2654dd1840a</id>
<content type='text'>
commit a87938b2e246b81b4fb713edb371a9fa3c5c3c86 upstream.

With CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE enabled, and a normal top-down
address allocation strategy, load_elf_binary() will attempt to map a PIE
binary into an address range immediately below mm-&gt;mmap_base.

Unfortunately, load_elf_ binary() does not take account of the need to
allocate sufficient space for the entire binary which means that, while
the first PT_LOAD segment is mapped below mm-&gt;mmap_base, the subsequent
PT_LOAD segment(s) end up being mapped above mm-&gt;mmap_base into the are
that is supposed to be the "gap" between the stack and the binary.

Since the size of the "gap" on x86_64 is only guaranteed to be 128MB this
means that binaries with large data segments &gt; 128MB can end up mapping
part of their data segment over their stack resulting in corruption of the
stack (and the data segment once the binary starts to run).

Any PIE binary with a data segment &gt; 128MB is vulnerable to this although
address randomization means that the actual gap between the stack and the
end of the binary is normally greater than 128MB.  The larger the data
segment of the binary the higher the probability of failure.

Fix this by calculating the total size of the binary in the same way as
load_elf_interp().

Signed-off-by: Michael Davidson &lt;md@google.com&gt;
Cc: Alexander Viro &lt;viro@zeniv.linux.org.uk&gt;
Cc: Jiri Kosina &lt;jkosina@suse.cz&gt;
Cc: Kees Cook &lt;keescook@chromium.org&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit a87938b2e246b81b4fb713edb371a9fa3c5c3c86 upstream.

With CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE enabled, and a normal top-down
address allocation strategy, load_elf_binary() will attempt to map a PIE
binary into an address range immediately below mm-&gt;mmap_base.

Unfortunately, load_elf_ binary() does not take account of the need to
allocate sufficient space for the entire binary which means that, while
the first PT_LOAD segment is mapped below mm-&gt;mmap_base, the subsequent
PT_LOAD segment(s) end up being mapped above mm-&gt;mmap_base into the are
that is supposed to be the "gap" between the stack and the binary.

Since the size of the "gap" on x86_64 is only guaranteed to be 128MB this
means that binaries with large data segments &gt; 128MB can end up mapping
part of their data segment over their stack resulting in corruption of the
stack (and the data segment once the binary starts to run).

Any PIE binary with a data segment &gt; 128MB is vulnerable to this although
address randomization means that the actual gap between the stack and the
end of the binary is normally greater than 128MB.  The larger the data
segment of the binary the higher the probability of failure.

Fix this by calculating the total size of the binary in the same way as
load_elf_interp().

Signed-off-by: Michael Davidson &lt;md@google.com&gt;
Cc: Alexander Viro &lt;viro@zeniv.linux.org.uk&gt;
Cc: Jiri Kosina &lt;jkosina@suse.cz&gt;
Cc: Kees Cook &lt;keescook@chromium.org&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</pre>
</div>
</content>
</entry>
<entry>
<title>Btrfs: fix inode eviction infinite loop after cloning into it</title>
<updated>2015-05-06T19:56:21+00:00</updated>
<author>
<name>Filipe Manana</name>
<email>fdmanana@suse.com</email>
</author>
<published>2015-03-30T17:23:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=6073c4162289fcae16b359f8e105d60343a209ca'/>
<id>6073c4162289fcae16b359f8e105d60343a209ca</id>
<content type='text'>
commit ccccf3d67294714af2d72a6fd6fd7d73b01c9329 upstream.

If we attempt to clone a 0 length region into a file we can end up
inserting a range in the inode's extent_io tree with a start offset
that is greater then the end offset, which triggers immediately the
following warning:

[ 3914.619057] WARNING: CPU: 17 PID: 4199 at fs/btrfs/extent_io.c:435 insert_state+0x4b/0x10b [btrfs]()
[ 3914.620886] BTRFS: end &lt; start 4095 4096
(...)
[ 3914.638093] Call Trace:
[ 3914.638636]  [&lt;ffffffff81425fd9&gt;] dump_stack+0x4c/0x65
[ 3914.639620]  [&lt;ffffffff81045390&gt;] warn_slowpath_common+0xa1/0xbb
[ 3914.640789]  [&lt;ffffffffa03ca44f&gt;] ? insert_state+0x4b/0x10b [btrfs]
[ 3914.642041]  [&lt;ffffffff810453f0&gt;] warn_slowpath_fmt+0x46/0x48
[ 3914.643236]  [&lt;ffffffffa03ca44f&gt;] insert_state+0x4b/0x10b [btrfs]
[ 3914.644441]  [&lt;ffffffffa03ca729&gt;] __set_extent_bit+0x107/0x3f4 [btrfs]
[ 3914.645711]  [&lt;ffffffffa03cb256&gt;] lock_extent_bits+0x65/0x1bf [btrfs]
[ 3914.646914]  [&lt;ffffffff8142b2fb&gt;] ? _raw_spin_unlock+0x28/0x33
[ 3914.648058]  [&lt;ffffffffa03cbac4&gt;] ? test_range_bit+0xcc/0xde [btrfs]
[ 3914.650105]  [&lt;ffffffffa03cb3c3&gt;] lock_extent+0x13/0x15 [btrfs]
[ 3914.651361]  [&lt;ffffffffa03db39e&gt;] lock_extent_range+0x3d/0xcd [btrfs]
[ 3914.652761]  [&lt;ffffffffa03de1fe&gt;] btrfs_ioctl_clone+0x278/0x388 [btrfs]
[ 3914.654128]  [&lt;ffffffff811226dd&gt;] ? might_fault+0x58/0xb5
[ 3914.655320]  [&lt;ffffffffa03e0909&gt;] btrfs_ioctl+0xb51/0x2195 [btrfs]
(...)
[ 3914.669271] ---[ end trace 14843d3e2e622fc1 ]---

This later makes the inode eviction handler enter an infinite loop that
keeps dumping the following warning over and over:

[ 3915.117629] WARNING: CPU: 22 PID: 4228 at fs/btrfs/extent_io.c:435 insert_state+0x4b/0x10b [btrfs]()
[ 3915.119913] BTRFS: end &lt; start 4095 4096
(...)
[ 3915.137394] Call Trace:
[ 3915.137913]  [&lt;ffffffff81425fd9&gt;] dump_stack+0x4c/0x65
[ 3915.139154]  [&lt;ffffffff81045390&gt;] warn_slowpath_common+0xa1/0xbb
[ 3915.140316]  [&lt;ffffffffa03ca44f&gt;] ? insert_state+0x4b/0x10b [btrfs]
[ 3915.141505]  [&lt;ffffffff810453f0&gt;] warn_slowpath_fmt+0x46/0x48
[ 3915.142709]  [&lt;ffffffffa03ca44f&gt;] insert_state+0x4b/0x10b [btrfs]
[ 3915.143849]  [&lt;ffffffffa03ca729&gt;] __set_extent_bit+0x107/0x3f4 [btrfs]
[ 3915.145120]  [&lt;ffffffffa038c1e3&gt;] ? btrfs_kill_super+0x17/0x23 [btrfs]
[ 3915.146352]  [&lt;ffffffff811548f6&gt;] ? deactivate_locked_super+0x3b/0x50
[ 3915.147565]  [&lt;ffffffffa03cb256&gt;] lock_extent_bits+0x65/0x1bf [btrfs]
[ 3915.148785]  [&lt;ffffffff8142b7e2&gt;] ? _raw_write_unlock+0x28/0x33
[ 3915.149931]  [&lt;ffffffffa03bc325&gt;] btrfs_evict_inode+0x196/0x482 [btrfs]
[ 3915.151154]  [&lt;ffffffff81168904&gt;] evict+0xa0/0x148
[ 3915.152094]  [&lt;ffffffff811689e5&gt;] dispose_list+0x39/0x43
[ 3915.153081]  [&lt;ffffffff81169564&gt;] evict_inodes+0xdc/0xeb
[ 3915.154062]  [&lt;ffffffff81154418&gt;] generic_shutdown_super+0x49/0xef
[ 3915.155193]  [&lt;ffffffff811546d1&gt;] kill_anon_super+0x13/0x1e
[ 3915.156274]  [&lt;ffffffffa038c1e3&gt;] btrfs_kill_super+0x17/0x23 [btrfs]
(...)
[ 3915.167404] ---[ end trace 14843d3e2e622fc2 ]---

So just bail out of the clone ioctl if the length of the region to clone
is zero, without locking any extent range, in order to prevent this issue
(same behaviour as a pwrite with a 0 length for example).

This is trivial to reproduce. For example, the steps for the test I just
made for fstests:

  mkfs.btrfs -f SCRATCH_DEV
  mount SCRATCH_DEV $SCRATCH_MNT

  touch $SCRATCH_MNT/foo
  touch $SCRATCH_MNT/bar

  $CLONER_PROG -s 0 -d 4096 -l 0 $SCRATCH_MNT/foo $SCRATCH_MNT/bar
  umount $SCRATCH_MNT

A test case for fstests follows soon.

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Reviewed-by: Omar Sandoval &lt;osandov@osandov.com&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit ccccf3d67294714af2d72a6fd6fd7d73b01c9329 upstream.

If we attempt to clone a 0 length region into a file we can end up
inserting a range in the inode's extent_io tree with a start offset
that is greater then the end offset, which triggers immediately the
following warning:

[ 3914.619057] WARNING: CPU: 17 PID: 4199 at fs/btrfs/extent_io.c:435 insert_state+0x4b/0x10b [btrfs]()
[ 3914.620886] BTRFS: end &lt; start 4095 4096
(...)
[ 3914.638093] Call Trace:
[ 3914.638636]  [&lt;ffffffff81425fd9&gt;] dump_stack+0x4c/0x65
[ 3914.639620]  [&lt;ffffffff81045390&gt;] warn_slowpath_common+0xa1/0xbb
[ 3914.640789]  [&lt;ffffffffa03ca44f&gt;] ? insert_state+0x4b/0x10b [btrfs]
[ 3914.642041]  [&lt;ffffffff810453f0&gt;] warn_slowpath_fmt+0x46/0x48
[ 3914.643236]  [&lt;ffffffffa03ca44f&gt;] insert_state+0x4b/0x10b [btrfs]
[ 3914.644441]  [&lt;ffffffffa03ca729&gt;] __set_extent_bit+0x107/0x3f4 [btrfs]
[ 3914.645711]  [&lt;ffffffffa03cb256&gt;] lock_extent_bits+0x65/0x1bf [btrfs]
[ 3914.646914]  [&lt;ffffffff8142b2fb&gt;] ? _raw_spin_unlock+0x28/0x33
[ 3914.648058]  [&lt;ffffffffa03cbac4&gt;] ? test_range_bit+0xcc/0xde [btrfs]
[ 3914.650105]  [&lt;ffffffffa03cb3c3&gt;] lock_extent+0x13/0x15 [btrfs]
[ 3914.651361]  [&lt;ffffffffa03db39e&gt;] lock_extent_range+0x3d/0xcd [btrfs]
[ 3914.652761]  [&lt;ffffffffa03de1fe&gt;] btrfs_ioctl_clone+0x278/0x388 [btrfs]
[ 3914.654128]  [&lt;ffffffff811226dd&gt;] ? might_fault+0x58/0xb5
[ 3914.655320]  [&lt;ffffffffa03e0909&gt;] btrfs_ioctl+0xb51/0x2195 [btrfs]
(...)
[ 3914.669271] ---[ end trace 14843d3e2e622fc1 ]---

This later makes the inode eviction handler enter an infinite loop that
keeps dumping the following warning over and over:

[ 3915.117629] WARNING: CPU: 22 PID: 4228 at fs/btrfs/extent_io.c:435 insert_state+0x4b/0x10b [btrfs]()
[ 3915.119913] BTRFS: end &lt; start 4095 4096
(...)
[ 3915.137394] Call Trace:
[ 3915.137913]  [&lt;ffffffff81425fd9&gt;] dump_stack+0x4c/0x65
[ 3915.139154]  [&lt;ffffffff81045390&gt;] warn_slowpath_common+0xa1/0xbb
[ 3915.140316]  [&lt;ffffffffa03ca44f&gt;] ? insert_state+0x4b/0x10b [btrfs]
[ 3915.141505]  [&lt;ffffffff810453f0&gt;] warn_slowpath_fmt+0x46/0x48
[ 3915.142709]  [&lt;ffffffffa03ca44f&gt;] insert_state+0x4b/0x10b [btrfs]
[ 3915.143849]  [&lt;ffffffffa03ca729&gt;] __set_extent_bit+0x107/0x3f4 [btrfs]
[ 3915.145120]  [&lt;ffffffffa038c1e3&gt;] ? btrfs_kill_super+0x17/0x23 [btrfs]
[ 3915.146352]  [&lt;ffffffff811548f6&gt;] ? deactivate_locked_super+0x3b/0x50
[ 3915.147565]  [&lt;ffffffffa03cb256&gt;] lock_extent_bits+0x65/0x1bf [btrfs]
[ 3915.148785]  [&lt;ffffffff8142b7e2&gt;] ? _raw_write_unlock+0x28/0x33
[ 3915.149931]  [&lt;ffffffffa03bc325&gt;] btrfs_evict_inode+0x196/0x482 [btrfs]
[ 3915.151154]  [&lt;ffffffff81168904&gt;] evict+0xa0/0x148
[ 3915.152094]  [&lt;ffffffff811689e5&gt;] dispose_list+0x39/0x43
[ 3915.153081]  [&lt;ffffffff81169564&gt;] evict_inodes+0xdc/0xeb
[ 3915.154062]  [&lt;ffffffff81154418&gt;] generic_shutdown_super+0x49/0xef
[ 3915.155193]  [&lt;ffffffff811546d1&gt;] kill_anon_super+0x13/0x1e
[ 3915.156274]  [&lt;ffffffffa038c1e3&gt;] btrfs_kill_super+0x17/0x23 [btrfs]
(...)
[ 3915.167404] ---[ end trace 14843d3e2e622fc2 ]---

So just bail out of the clone ioctl if the length of the region to clone
is zero, without locking any extent range, in order to prevent this issue
(same behaviour as a pwrite with a 0 length for example).

This is trivial to reproduce. For example, the steps for the test I just
made for fstests:

  mkfs.btrfs -f SCRATCH_DEV
  mount SCRATCH_DEV $SCRATCH_MNT

  touch $SCRATCH_MNT/foo
  touch $SCRATCH_MNT/bar

  $CLONER_PROG -s 0 -d 4096 -l 0 $SCRATCH_MNT/foo $SCRATCH_MNT/bar
  umount $SCRATCH_MNT

A test case for fstests follows soon.

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Reviewed-by: Omar Sandoval &lt;osandov@osandov.com&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</pre>
</div>
</content>
</entry>
<entry>
<title>Btrfs: fix log tree corruption when fs mounted with -o discard</title>
<updated>2015-05-06T19:56:21+00:00</updated>
<author>
<name>Filipe Manana</name>
<email>fdmanana@suse.com</email>
</author>
<published>2015-03-23T14:07:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=bf339141f604388ace1c3f97b9297683f45170dd'/>
<id>bf339141f604388ace1c3f97b9297683f45170dd</id>
<content type='text'>
commit dcc82f4783ad91d4ab654f89f37ae9291cdc846a upstream.

While committing a transaction we free the log roots before we write the
new super block. Freeing the log roots implies marking the disk location
of every node/leaf (metadata extent) as pinned before the new super block
is written. This is to prevent the disk location of log metadata extents
from being reused before the new super block is written, otherwise we
would have a corrupted log tree if before the new super block is written
a crash/reboot happens and the location of any log tree metadata extent
ended up being reused and rewritten.

Even though we pinned the log tree's metadata extents, we were issuing a
discard against them if the fs was mounted with the -o discard option,
resulting in corruption of the log tree if a crash/reboot happened before
writing the new super block - the next time the fs was mounted, during
the log replay process we would find nodes/leafs of the log btree with
a content full of zeroes, causing the process to fail and require the
use of the tool btrfs-zero-log to wipeout the log tree (and all data
previously fsynced becoming lost forever).

Fix this by not doing a discard when pinning an extent. The discard will
be done later when it's safe (after the new super block is committed) at
extent-tree.c:btrfs_finish_extent_commit().

Fixes: e688b7252f78 (Btrfs: fix extent pinning bugs in the tree log)
Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit dcc82f4783ad91d4ab654f89f37ae9291cdc846a upstream.

While committing a transaction we free the log roots before we write the
new super block. Freeing the log roots implies marking the disk location
of every node/leaf (metadata extent) as pinned before the new super block
is written. This is to prevent the disk location of log metadata extents
from being reused before the new super block is written, otherwise we
would have a corrupted log tree if before the new super block is written
a crash/reboot happens and the location of any log tree metadata extent
ended up being reused and rewritten.

Even though we pinned the log tree's metadata extents, we were issuing a
discard against them if the fs was mounted with the -o discard option,
resulting in corruption of the log tree if a crash/reboot happened before
writing the new super block - the next time the fs was mounted, during
the log replay process we would find nodes/leafs of the log btree with
a content full of zeroes, causing the process to fail and require the
use of the tool btrfs-zero-log to wipeout the log tree (and all data
previously fsynced becoming lost forever).

Fix this by not doing a discard when pinning an extent. The discard will
be done later when it's safe (after the new super block is committed) at
extent-tree.c:btrfs_finish_extent_commit().

Fixes: e688b7252f78 (Btrfs: fix extent pinning bugs in the tree log)
Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Signed-off-by: Chris Mason &lt;clm@fb.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</pre>
</div>
</content>
</entry>
<entry>
<title>dcache: Fix locking bugs in backported "deal with deadlock in d_walk()"</title>
<updated>2015-04-29T08:34:02+00:00</updated>
<author>
<name>Ben Hutchings</name>
<email>ben@decadent.org.uk</email>
</author>
<published>2015-02-11T03:16:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=c190d250d8db5620218d5d56999580ed8488ec24'/>
<id>c190d250d8db5620218d5d56999580ed8488ec24</id>
<content type='text'>
commit 20defcec264ceab2630356fb9d397f3d237b5e6d upstream in 3.2-stable

Steven Rostedt reported:
&gt; Porting -rt to the latest 3.2 stable tree I triggered this bug:
&gt;
&gt; =====================================
&gt; [ BUG: bad unlock balance detected! ]
&gt; -------------------------------------
&gt; rm/1638 is trying to release lock (rcu_read_lock) at:
&gt; [&lt;c04fde6c&gt;] rcu_read_unlock+0x0/0x23
&gt; but there are no more locks to release!
&gt;
&gt; other info that might help us debug this:
&gt; 2 locks held by rm/1638:
&gt;  #0:  (&amp;sb-&gt;s_type-&gt;i_mutex_key#9/1){+.+.+.}, at: [&lt;c04f93eb&gt;] do_rmdir+0x5f/0xd2
&gt;  #1:  (&amp;sb-&gt;s_type-&gt;i_mutex_key#9){+.+.+.}, at: [&lt;c04f9329&gt;] vfs_rmdir+0x49/0xac
&gt;
&gt; stack backtrace:
&gt; Pid: 1638, comm: rm Not tainted 3.2.66-test-rt96+ #2
&gt; Call Trace:
&gt;  [&lt;c083f390&gt;] ? printk+0x1d/0x1f
&gt;  [&lt;c0463cdf&gt;] print_unlock_inbalance_bug+0xc3/0xcd
&gt;  [&lt;c04653a8&gt;] lock_release_non_nested+0x98/0x1ec
&gt;  [&lt;c046228d&gt;] ? trace_hardirqs_off_caller+0x18/0x90
&gt;  [&lt;c0456f1c&gt;] ? local_clock+0x2d/0x50
&gt;  [&lt;c04fde6c&gt;] ? d_hash+0x2f/0x2f
&gt;  [&lt;c04fde6c&gt;] ? d_hash+0x2f/0x2f
&gt;  [&lt;c046568e&gt;] lock_release+0x192/0x1ad
&gt;  [&lt;c04fde83&gt;] rcu_read_unlock+0x17/0x23
&gt;  [&lt;c04ff344&gt;] shrink_dcache_parent+0x227/0x270
&gt;  [&lt;c04f9348&gt;] vfs_rmdir+0x68/0xac
&gt;  [&lt;c04f9424&gt;] do_rmdir+0x98/0xd2
&gt;  [&lt;c04f03ad&gt;] ? fput+0x1a3/0x1ab
&gt;  [&lt;c084dd42&gt;] ? sysenter_exit+0xf/0x1a
&gt;  [&lt;c0465b58&gt;] ? trace_hardirqs_on_caller+0x118/0x149
&gt;  [&lt;c04fa3e0&gt;] sys_unlinkat+0x2b/0x35
&gt;  [&lt;c084dd13&gt;] sysenter_do_call+0x12/0x12
&gt;
&gt;
&gt;
&gt;
&gt; There's a path to calling rcu_read_unlock() without calling
&gt; rcu_read_lock() in have_submounts().
&gt;
&gt; 	goto positive;
&gt;
&gt; positive:
&gt; 	if (!locked &amp;&amp; read_seqretry(&amp;rename_lock, seq))
&gt; 		goto rename_retry;
&gt;
&gt; rename_retry:
&gt; 	rcu_read_unlock();
&gt;
&gt; in the above path, rcu_read_lock() is never done before calling
&gt; rcu_read_unlock();

I reviewed locking contexts in all three functions that I changed when
backporting "deal with deadlock in d_walk()".  It's actually worse
than this:

- We don't hold this_parent-&gt;d_lock at the 'positive' label in
  have_submounts(), but it is unlocked after 'rename_retry'.
- There is an rcu_read_unlock() after the 'out' label in
  select_parent(), but it's not held at the 'goto out'.

Fix all three lock imbalances.

Reported-by: Steven Rostedt &lt;rostedt@goodmis.org&gt;
Signed-off-by: Ben Hutchings &lt;ben@decadent.org.uk&gt;
Tested-by: Steven Rostedt &lt;rostedt@goodmis.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 20defcec264ceab2630356fb9d397f3d237b5e6d upstream in 3.2-stable

Steven Rostedt reported:
&gt; Porting -rt to the latest 3.2 stable tree I triggered this bug:
&gt;
&gt; =====================================
&gt; [ BUG: bad unlock balance detected! ]
&gt; -------------------------------------
&gt; rm/1638 is trying to release lock (rcu_read_lock) at:
&gt; [&lt;c04fde6c&gt;] rcu_read_unlock+0x0/0x23
&gt; but there are no more locks to release!
&gt;
&gt; other info that might help us debug this:
&gt; 2 locks held by rm/1638:
&gt;  #0:  (&amp;sb-&gt;s_type-&gt;i_mutex_key#9/1){+.+.+.}, at: [&lt;c04f93eb&gt;] do_rmdir+0x5f/0xd2
&gt;  #1:  (&amp;sb-&gt;s_type-&gt;i_mutex_key#9){+.+.+.}, at: [&lt;c04f9329&gt;] vfs_rmdir+0x49/0xac
&gt;
&gt; stack backtrace:
&gt; Pid: 1638, comm: rm Not tainted 3.2.66-test-rt96+ #2
&gt; Call Trace:
&gt;  [&lt;c083f390&gt;] ? printk+0x1d/0x1f
&gt;  [&lt;c0463cdf&gt;] print_unlock_inbalance_bug+0xc3/0xcd
&gt;  [&lt;c04653a8&gt;] lock_release_non_nested+0x98/0x1ec
&gt;  [&lt;c046228d&gt;] ? trace_hardirqs_off_caller+0x18/0x90
&gt;  [&lt;c0456f1c&gt;] ? local_clock+0x2d/0x50
&gt;  [&lt;c04fde6c&gt;] ? d_hash+0x2f/0x2f
&gt;  [&lt;c04fde6c&gt;] ? d_hash+0x2f/0x2f
&gt;  [&lt;c046568e&gt;] lock_release+0x192/0x1ad
&gt;  [&lt;c04fde83&gt;] rcu_read_unlock+0x17/0x23
&gt;  [&lt;c04ff344&gt;] shrink_dcache_parent+0x227/0x270
&gt;  [&lt;c04f9348&gt;] vfs_rmdir+0x68/0xac
&gt;  [&lt;c04f9424&gt;] do_rmdir+0x98/0xd2
&gt;  [&lt;c04f03ad&gt;] ? fput+0x1a3/0x1ab
&gt;  [&lt;c084dd42&gt;] ? sysenter_exit+0xf/0x1a
&gt;  [&lt;c0465b58&gt;] ? trace_hardirqs_on_caller+0x118/0x149
&gt;  [&lt;c04fa3e0&gt;] sys_unlinkat+0x2b/0x35
&gt;  [&lt;c084dd13&gt;] sysenter_do_call+0x12/0x12
&gt;
&gt;
&gt;
&gt;
&gt; There's a path to calling rcu_read_unlock() without calling
&gt; rcu_read_lock() in have_submounts().
&gt;
&gt; 	goto positive;
&gt;
&gt; positive:
&gt; 	if (!locked &amp;&amp; read_seqretry(&amp;rename_lock, seq))
&gt; 		goto rename_retry;
&gt;
&gt; rename_retry:
&gt; 	rcu_read_unlock();
&gt;
&gt; in the above path, rcu_read_lock() is never done before calling
&gt; rcu_read_unlock();

I reviewed locking contexts in all three functions that I changed when
backporting "deal with deadlock in d_walk()".  It's actually worse
than this:

- We don't hold this_parent-&gt;d_lock at the 'positive' label in
  have_submounts(), but it is unlocked after 'rename_retry'.
- There is an rcu_read_unlock() after the 'out' label in
  select_parent(), but it's not held at the 'goto out'.

Fix all three lock imbalances.

Reported-by: Steven Rostedt &lt;rostedt@goodmis.org&gt;
Signed-off-by: Ben Hutchings &lt;ben@decadent.org.uk&gt;
Tested-by: Steven Rostedt &lt;rostedt@goodmis.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</pre>
</div>
</content>
</entry>
<entry>
<title>deal with deadlock in d_walk()</title>
<updated>2015-04-29T08:34:00+00:00</updated>
<author>
<name>Al Viro</name>
<email>viro@zeniv.linux.org.uk</email>
</author>
<published>2014-10-26T23:31:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=5f03ac13d87590b0ee879c77e68df63a3d9b3e07'/>
<id>5f03ac13d87590b0ee879c77e68df63a3d9b3e07</id>
<content type='text'>
commit ca5358ef75fc69fee5322a38a340f5739d997c10 upstream.

... by not hitting rename_retry for reasons other than rename having
happened.  In other words, do _not_ restart when finding that
between unlocking the child and locking the parent the former got
into __dentry_kill().  Skip the killed siblings instead...

Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Cc: Ben Hutchings &lt;ben@decadent.org.uk&gt;
[hujianyang: Backported to 3.10 refer to the work of Ben Hutchings in 3.2:
 - As we only have try_to_ascend() and not d_walk(), apply this
   change to all callers of try_to_ascend()
 - Adjust context to make __dentry_kill() apply to d_kill()]
Signed-off-by: hujianyang &lt;hujianyang@huawei.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit ca5358ef75fc69fee5322a38a340f5739d997c10 upstream.

... by not hitting rename_retry for reasons other than rename having
happened.  In other words, do _not_ restart when finding that
between unlocking the child and locking the parent the former got
into __dentry_kill().  Skip the killed siblings instead...

Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Cc: Ben Hutchings &lt;ben@decadent.org.uk&gt;
[hujianyang: Backported to 3.10 refer to the work of Ben Hutchings in 3.2:
 - As we only have try_to_ascend() and not d_walk(), apply this
   change to all callers of try_to_ascend()
 - Adjust context to make __dentry_kill() apply to d_kill()]
Signed-off-by: hujianyang &lt;hujianyang@huawei.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>move d_rcu from overlapping d_child to overlapping d_alias</title>
<updated>2015-04-29T08:34:00+00:00</updated>
<author>
<name>Al Viro</name>
<email>viro@zeniv.linux.org.uk</email>
</author>
<published>2014-10-26T23:19:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=6637ecd306a94a03dd5b8e4e8d3f260d9877c5b0'/>
<id>6637ecd306a94a03dd5b8e4e8d3f260d9877c5b0</id>
<content type='text'>
commit 946e51f2bf37f1656916eb75bd0742ba33983c28 upstream.

Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Cc: Ben Hutchings &lt;ben@decadent.org.uk&gt;
[hujianyang: Backported to 3.10 refer to the work of Ben Hutchings in 3.2:
 - Apply name changes in all the different places we use d_alias and d_child
 - Move the WARN_ON() in __d_free() to d_free() as we don't have dentry_free()]
Signed-off-by: hujianyang &lt;hujianyang@huawei.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 946e51f2bf37f1656916eb75bd0742ba33983c28 upstream.

Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Cc: Ben Hutchings &lt;ben@decadent.org.uk&gt;
[hujianyang: Backported to 3.10 refer to the work of Ben Hutchings in 3.2:
 - Apply name changes in all the different places we use d_alias and d_child
 - Move the WARN_ON() in __d_free() to d_free() as we don't have dentry_free()]
Signed-off-by: hujianyang &lt;hujianyang@huawei.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>splice: Apply generic position and size checks to each write</title>
<updated>2015-04-29T08:33:57+00:00</updated>
<author>
<name>Ben Hutchings</name>
<email>ben@decadent.org.uk</email>
</author>
<published>2015-01-29T02:50:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=13d32f27d15c5c53254ed88e3d2042c34de1bfaa'/>
<id>13d32f27d15c5c53254ed88e3d2042c34de1bfaa</id>
<content type='text'>
commit 894c6350eaad7e613ae267504014a456e00a3e2a from the 3.2-stable branch.

We need to check the position and size of file writes against various
limits, using generic_write_check().  This was not being done for
the splice write path.  It was fixed upstream by commit 8d0207652cbe
("-&gt;splice_write() via -&gt;write_iter()") but we can't apply that.

CVE-2014-7822

Signed-off-by: Ben Hutchings &lt;ben@decadent.org.uk&gt;
[Ben fixed it in 3.2 stable, i ported it to 3.10 stable]
Signed-off-by: Zhang Zhen &lt;zhenzhang.zhang@huawei.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 894c6350eaad7e613ae267504014a456e00a3e2a from the 3.2-stable branch.

We need to check the position and size of file writes against various
limits, using generic_write_check().  This was not being done for
the splice write path.  It was fixed upstream by commit 8d0207652cbe
("-&gt;splice_write() via -&gt;write_iter()") but we can't apply that.

CVE-2014-7822

Signed-off-by: Ben Hutchings &lt;ben@decadent.org.uk&gt;
[Ben fixed it in 3.2 stable, i ported it to 3.10 stable]
Signed-off-by: Zhang Zhen &lt;zhenzhang.zhang@huawei.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</pre>
</div>
</content>
</entry>
</feed>
