<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux-stable.git/fs/ext4, branch v3.18.35</title>
<subtitle>Linux kernel stable tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/'/>
<entry>
<title>ext4: silence UBSAN in ext4_mb_init()</title>
<updated>2016-06-03T15:30:36+00:00</updated>
<author>
<name>Nicolai Stange</name>
<email>nicstange@gmail.com</email>
</author>
<published>2016-05-05T23:46:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=aee24401991708c95e7b3189119fc917f1fc16b8'/>
<id>aee24401991708c95e7b3189119fc917f1fc16b8</id>
<content type='text'>
[ Upstream commit 935244cd54b86ca46e69bc6604d2adfb1aec2d42 ]

Currently, in ext4_mb_init(), there's a loop like the following:

  do {
    ...
    offset += 1 &lt;&lt; (sb-&gt;s_blocksize_bits - i);
    i++;
  } while (i &lt;= sb-&gt;s_blocksize_bits + 1);

Note that the updated offset is used in the loop's next iteration only.

However, at the last iteration, that is at i == sb-&gt;s_blocksize_bits + 1,
the shift count becomes equal to (unsigned)-1 &gt; 31 (c.f. C99 6.5.7(3))
and UBSAN reports

  UBSAN: Undefined behaviour in fs/ext4/mballoc.c:2621:15
  shift exponent 4294967295 is too large for 32-bit type 'int'
  [...]
  Call Trace:
   [&lt;ffffffff818c4d25&gt;] dump_stack+0xbc/0x117
   [&lt;ffffffff818c4c69&gt;] ? _atomic_dec_and_lock+0x169/0x169
   [&lt;ffffffff819411ab&gt;] ubsan_epilogue+0xd/0x4e
   [&lt;ffffffff81941cac&gt;] __ubsan_handle_shift_out_of_bounds+0x1fb/0x254
   [&lt;ffffffff81941ab1&gt;] ? __ubsan_handle_load_invalid_value+0x158/0x158
   [&lt;ffffffff814b6dc1&gt;] ? kmem_cache_alloc+0x101/0x390
   [&lt;ffffffff816fc13b&gt;] ? ext4_mb_init+0x13b/0xfd0
   [&lt;ffffffff814293c7&gt;] ? create_cache+0x57/0x1f0
   [&lt;ffffffff8142948a&gt;] ? create_cache+0x11a/0x1f0
   [&lt;ffffffff821c2168&gt;] ? mutex_lock+0x38/0x60
   [&lt;ffffffff821c23ab&gt;] ? mutex_unlock+0x1b/0x50
   [&lt;ffffffff814c26ab&gt;] ? put_online_mems+0x5b/0xc0
   [&lt;ffffffff81429677&gt;] ? kmem_cache_create+0x117/0x2c0
   [&lt;ffffffff816fcc49&gt;] ext4_mb_init+0xc49/0xfd0
   [...]

Observe that the mentioned shift exponent, 4294967295, equals (unsigned)-1.

Unless compilers start to do some fancy transformations (which at least
GCC 6.0.0 doesn't currently do), the issue is of cosmetic nature only: the
such calculated value of offset is never used again.

Silence UBSAN by introducing another variable, offset_incr, holding the
next increment to apply to offset and adjust that one by right shifting it
by one position per loop iteration.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=114701
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=112161

Cc: stable@vger.kernel.org
Signed-off-by: Nicolai Stange &lt;nicstange@gmail.com&gt;
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 935244cd54b86ca46e69bc6604d2adfb1aec2d42 ]

Currently, in ext4_mb_init(), there's a loop like the following:

  do {
    ...
    offset += 1 &lt;&lt; (sb-&gt;s_blocksize_bits - i);
    i++;
  } while (i &lt;= sb-&gt;s_blocksize_bits + 1);

Note that the updated offset is used in the loop's next iteration only.

However, at the last iteration, that is at i == sb-&gt;s_blocksize_bits + 1,
the shift count becomes equal to (unsigned)-1 &gt; 31 (c.f. C99 6.5.7(3))
and UBSAN reports

  UBSAN: Undefined behaviour in fs/ext4/mballoc.c:2621:15
  shift exponent 4294967295 is too large for 32-bit type 'int'
  [...]
  Call Trace:
   [&lt;ffffffff818c4d25&gt;] dump_stack+0xbc/0x117
   [&lt;ffffffff818c4c69&gt;] ? _atomic_dec_and_lock+0x169/0x169
   [&lt;ffffffff819411ab&gt;] ubsan_epilogue+0xd/0x4e
   [&lt;ffffffff81941cac&gt;] __ubsan_handle_shift_out_of_bounds+0x1fb/0x254
   [&lt;ffffffff81941ab1&gt;] ? __ubsan_handle_load_invalid_value+0x158/0x158
   [&lt;ffffffff814b6dc1&gt;] ? kmem_cache_alloc+0x101/0x390
   [&lt;ffffffff816fc13b&gt;] ? ext4_mb_init+0x13b/0xfd0
   [&lt;ffffffff814293c7&gt;] ? create_cache+0x57/0x1f0
   [&lt;ffffffff8142948a&gt;] ? create_cache+0x11a/0x1f0
   [&lt;ffffffff821c2168&gt;] ? mutex_lock+0x38/0x60
   [&lt;ffffffff821c23ab&gt;] ? mutex_unlock+0x1b/0x50
   [&lt;ffffffff814c26ab&gt;] ? put_online_mems+0x5b/0xc0
   [&lt;ffffffff81429677&gt;] ? kmem_cache_create+0x117/0x2c0
   [&lt;ffffffff816fcc49&gt;] ext4_mb_init+0xc49/0xfd0
   [...]

Observe that the mentioned shift exponent, 4294967295, equals (unsigned)-1.

Unless compilers start to do some fancy transformations (which at least
GCC 6.0.0 doesn't currently do), the issue is of cosmetic nature only: the
such calculated value of offset is never used again.

Silence UBSAN by introducing another variable, offset_incr, holding the
next increment to apply to offset and adjust that one by right shifting it
by one position per loop iteration.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=114701
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=112161

Cc: stable@vger.kernel.org
Signed-off-by: Nicolai Stange &lt;nicstange@gmail.com&gt;
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ext4: address UBSAN warning in mb_find_order_for_block()</title>
<updated>2016-06-03T15:30:36+00:00</updated>
<author>
<name>Nicolai Stange</name>
<email>nicstange@gmail.com</email>
</author>
<published>2016-05-05T21:38:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=c7f9091d2cbaa803ba4e5f8cc12022523c387bd4'/>
<id>c7f9091d2cbaa803ba4e5f8cc12022523c387bd4</id>
<content type='text'>
[ Upstream commit b5cb316cdf3a3f5f6125412b0f6065185240cfdc ]

Currently, in mb_find_order_for_block(), there's a loop like the following:

  while (order &lt;= e4b-&gt;bd_blkbits + 1) {
    ...
    bb += 1 &lt;&lt; (e4b-&gt;bd_blkbits - order);
  }

Note that the updated bb is used in the loop's next iteration only.

However, at the last iteration, that is at order == e4b-&gt;bd_blkbits + 1,
the shift count becomes negative (c.f. C99 6.5.7(3)) and UBSAN reports

  UBSAN: Undefined behaviour in fs/ext4/mballoc.c:1281:11
  shift exponent -1 is negative
  [...]
  Call Trace:
   [&lt;ffffffff818c4d35&gt;] dump_stack+0xbc/0x117
   [&lt;ffffffff818c4c79&gt;] ? _atomic_dec_and_lock+0x169/0x169
   [&lt;ffffffff819411bb&gt;] ubsan_epilogue+0xd/0x4e
   [&lt;ffffffff81941cbc&gt;] __ubsan_handle_shift_out_of_bounds+0x1fb/0x254
   [&lt;ffffffff81941ac1&gt;] ? __ubsan_handle_load_invalid_value+0x158/0x158
   [&lt;ffffffff816e93a0&gt;] ? ext4_mb_generate_from_pa+0x590/0x590
   [&lt;ffffffff816502c8&gt;] ? ext4_read_block_bitmap_nowait+0x598/0xe80
   [&lt;ffffffff816e7b7e&gt;] mb_find_order_for_block+0x1ce/0x240
   [...]

Unless compilers start to do some fancy transformations (which at least
GCC 6.0.0 doesn't currently do), the issue is of cosmetic nature only: the
such calculated value of bb is never used again.

Silence UBSAN by introducing another variable, bb_incr, holding the next
increment to apply to bb and adjust that one by right shifting it by one
position per loop iteration.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=114701
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=112161

Cc: stable@vger.kernel.org
Signed-off-by: Nicolai Stange &lt;nicstange@gmail.com&gt;
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit b5cb316cdf3a3f5f6125412b0f6065185240cfdc ]

Currently, in mb_find_order_for_block(), there's a loop like the following:

  while (order &lt;= e4b-&gt;bd_blkbits + 1) {
    ...
    bb += 1 &lt;&lt; (e4b-&gt;bd_blkbits - order);
  }

Note that the updated bb is used in the loop's next iteration only.

However, at the last iteration, that is at order == e4b-&gt;bd_blkbits + 1,
the shift count becomes negative (c.f. C99 6.5.7(3)) and UBSAN reports

  UBSAN: Undefined behaviour in fs/ext4/mballoc.c:1281:11
  shift exponent -1 is negative
  [...]
  Call Trace:
   [&lt;ffffffff818c4d35&gt;] dump_stack+0xbc/0x117
   [&lt;ffffffff818c4c79&gt;] ? _atomic_dec_and_lock+0x169/0x169
   [&lt;ffffffff819411bb&gt;] ubsan_epilogue+0xd/0x4e
   [&lt;ffffffff81941cbc&gt;] __ubsan_handle_shift_out_of_bounds+0x1fb/0x254
   [&lt;ffffffff81941ac1&gt;] ? __ubsan_handle_load_invalid_value+0x158/0x158
   [&lt;ffffffff816e93a0&gt;] ? ext4_mb_generate_from_pa+0x590/0x590
   [&lt;ffffffff816502c8&gt;] ? ext4_read_block_bitmap_nowait+0x598/0xe80
   [&lt;ffffffff816e7b7e&gt;] mb_find_order_for_block+0x1ce/0x240
   [...]

Unless compilers start to do some fancy transformations (which at least
GCC 6.0.0 doesn't currently do), the issue is of cosmetic nature only: the
such calculated value of bb is never used again.

Silence UBSAN by introducing another variable, bb_incr, holding the next
increment to apply to bb and adjust that one by right shifting it by one
position per loop iteration.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=114701
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=112161

Cc: stable@vger.kernel.org
Signed-off-by: Nicolai Stange &lt;nicstange@gmail.com&gt;
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ext4: fix oops on corrupted filesystem</title>
<updated>2016-06-03T15:30:36+00:00</updated>
<author>
<name>Jan Kara</name>
<email>jack@suse.cz</email>
</author>
<published>2016-05-05T15:10:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=2cf9b776270bb9f9a5c7827a57e4d544acce573e'/>
<id>2cf9b776270bb9f9a5c7827a57e4d544acce573e</id>
<content type='text'>
[ Upstream commit 74177f55b70e2f2be770dd28684dd6d17106a4ba ]

When filesystem is corrupted in the right way, it can happen
ext4_mark_iloc_dirty() in ext4_orphan_add() returns error and we
subsequently remove inode from the in-memory orphan list. However this
deletion is done with list_del(&amp;EXT4_I(inode)-&gt;i_orphan) and thus we
leave i_orphan list_head with a stale content. Later we can look at this
content causing list corruption, oops, or other issues. The reported
trace looked like:

WARNING: CPU: 0 PID: 46 at lib/list_debug.c:53 __list_del_entry+0x6b/0x100()
list_del corruption, 0000000061c1d6e0-&gt;next is LIST_POISON1
0000000000100100)
CPU: 0 PID: 46 Comm: ext4.exe Not tainted 4.1.0-rc4+ #250
Stack:
 60462947 62219960 602ede24 62219960
 602ede24 603ca293 622198f0 602f02eb
 62219950 6002c12c 62219900 601b4d6b
Call Trace:
 [&lt;6005769c&gt;] ? vprintk_emit+0x2dc/0x5c0
 [&lt;602ede24&gt;] ? printk+0x0/0x94
 [&lt;600190bc&gt;] show_stack+0xdc/0x1a0
 [&lt;602ede24&gt;] ? printk+0x0/0x94
 [&lt;602ede24&gt;] ? printk+0x0/0x94
 [&lt;602f02eb&gt;] dump_stack+0x2a/0x2c
 [&lt;6002c12c&gt;] warn_slowpath_common+0x9c/0xf0
 [&lt;601b4d6b&gt;] ? __list_del_entry+0x6b/0x100
 [&lt;6002c254&gt;] warn_slowpath_fmt+0x94/0xa0
 [&lt;602f4d09&gt;] ? __mutex_lock_slowpath+0x239/0x3a0
 [&lt;6002c1c0&gt;] ? warn_slowpath_fmt+0x0/0xa0
 [&lt;60023ebf&gt;] ? set_signals+0x3f/0x50
 [&lt;600a205a&gt;] ? kmem_cache_free+0x10a/0x180
 [&lt;602f4e88&gt;] ? mutex_lock+0x18/0x30
 [&lt;601b4d6b&gt;] __list_del_entry+0x6b/0x100
 [&lt;601177ec&gt;] ext4_orphan_del+0x22c/0x2f0
 [&lt;6012f27c&gt;] ? __ext4_journal_start_sb+0x2c/0xa0
 [&lt;6010b973&gt;] ? ext4_truncate+0x383/0x390
 [&lt;6010bc8b&gt;] ext4_write_begin+0x30b/0x4b0
 [&lt;6001bb50&gt;] ? copy_from_user+0x0/0xb0
 [&lt;601aa840&gt;] ? iov_iter_fault_in_readable+0xa0/0xc0
 [&lt;60072c4f&gt;] generic_perform_write+0xaf/0x1e0
 [&lt;600c4166&gt;] ? file_update_time+0x46/0x110
 [&lt;60072f0f&gt;] __generic_file_write_iter+0x18f/0x1b0
 [&lt;6010030f&gt;] ext4_file_write_iter+0x15f/0x470
 [&lt;60094e10&gt;] ? unlink_file_vma+0x0/0x70
 [&lt;6009b180&gt;] ? unlink_anon_vmas+0x0/0x260
 [&lt;6008f169&gt;] ? free_pgtables+0xb9/0x100
 [&lt;600a6030&gt;] __vfs_write+0xb0/0x130
 [&lt;600a61d5&gt;] vfs_write+0xa5/0x170
 [&lt;600a63d6&gt;] SyS_write+0x56/0xe0
 [&lt;6029fcb0&gt;] ? __libc_waitpid+0x0/0xa0
 [&lt;6001b698&gt;] handle_syscall+0x68/0x90
 [&lt;6002633d&gt;] userspace+0x4fd/0x600
 [&lt;6002274f&gt;] ? save_registers+0x1f/0x40
 [&lt;60028bd7&gt;] ? arch_prctl+0x177/0x1b0
 [&lt;60017bd5&gt;] fork_handler+0x85/0x90

Fix the problem by using list_del_init() as we always should with
i_orphan list.

CC: stable@vger.kernel.org
Reported-by: Vegard Nossum &lt;vegard.nossum@oracle.com&gt;
Signed-off-by: Jan Kara &lt;jack@suse.cz&gt;
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 74177f55b70e2f2be770dd28684dd6d17106a4ba ]

When filesystem is corrupted in the right way, it can happen
ext4_mark_iloc_dirty() in ext4_orphan_add() returns error and we
subsequently remove inode from the in-memory orphan list. However this
deletion is done with list_del(&amp;EXT4_I(inode)-&gt;i_orphan) and thus we
leave i_orphan list_head with a stale content. Later we can look at this
content causing list corruption, oops, or other issues. The reported
trace looked like:

WARNING: CPU: 0 PID: 46 at lib/list_debug.c:53 __list_del_entry+0x6b/0x100()
list_del corruption, 0000000061c1d6e0-&gt;next is LIST_POISON1
0000000000100100)
CPU: 0 PID: 46 Comm: ext4.exe Not tainted 4.1.0-rc4+ #250
Stack:
 60462947 62219960 602ede24 62219960
 602ede24 603ca293 622198f0 602f02eb
 62219950 6002c12c 62219900 601b4d6b
Call Trace:
 [&lt;6005769c&gt;] ? vprintk_emit+0x2dc/0x5c0
 [&lt;602ede24&gt;] ? printk+0x0/0x94
 [&lt;600190bc&gt;] show_stack+0xdc/0x1a0
 [&lt;602ede24&gt;] ? printk+0x0/0x94
 [&lt;602ede24&gt;] ? printk+0x0/0x94
 [&lt;602f02eb&gt;] dump_stack+0x2a/0x2c
 [&lt;6002c12c&gt;] warn_slowpath_common+0x9c/0xf0
 [&lt;601b4d6b&gt;] ? __list_del_entry+0x6b/0x100
 [&lt;6002c254&gt;] warn_slowpath_fmt+0x94/0xa0
 [&lt;602f4d09&gt;] ? __mutex_lock_slowpath+0x239/0x3a0
 [&lt;6002c1c0&gt;] ? warn_slowpath_fmt+0x0/0xa0
 [&lt;60023ebf&gt;] ? set_signals+0x3f/0x50
 [&lt;600a205a&gt;] ? kmem_cache_free+0x10a/0x180
 [&lt;602f4e88&gt;] ? mutex_lock+0x18/0x30
 [&lt;601b4d6b&gt;] __list_del_entry+0x6b/0x100
 [&lt;601177ec&gt;] ext4_orphan_del+0x22c/0x2f0
 [&lt;6012f27c&gt;] ? __ext4_journal_start_sb+0x2c/0xa0
 [&lt;6010b973&gt;] ? ext4_truncate+0x383/0x390
 [&lt;6010bc8b&gt;] ext4_write_begin+0x30b/0x4b0
 [&lt;6001bb50&gt;] ? copy_from_user+0x0/0xb0
 [&lt;601aa840&gt;] ? iov_iter_fault_in_readable+0xa0/0xc0
 [&lt;60072c4f&gt;] generic_perform_write+0xaf/0x1e0
 [&lt;600c4166&gt;] ? file_update_time+0x46/0x110
 [&lt;60072f0f&gt;] __generic_file_write_iter+0x18f/0x1b0
 [&lt;6010030f&gt;] ext4_file_write_iter+0x15f/0x470
 [&lt;60094e10&gt;] ? unlink_file_vma+0x0/0x70
 [&lt;6009b180&gt;] ? unlink_anon_vmas+0x0/0x260
 [&lt;6008f169&gt;] ? free_pgtables+0xb9/0x100
 [&lt;600a6030&gt;] __vfs_write+0xb0/0x130
 [&lt;600a61d5&gt;] vfs_write+0xa5/0x170
 [&lt;600a63d6&gt;] SyS_write+0x56/0xe0
 [&lt;6029fcb0&gt;] ? __libc_waitpid+0x0/0xa0
 [&lt;6001b698&gt;] handle_syscall+0x68/0x90
 [&lt;6002633d&gt;] userspace+0x4fd/0x600
 [&lt;6002274f&gt;] ? save_registers+0x1f/0x40
 [&lt;60028bd7&gt;] ? arch_prctl+0x177/0x1b0
 [&lt;60017bd5&gt;] fork_handler+0x85/0x90

Fix the problem by using list_del_init() as we always should with
i_orphan list.

CC: stable@vger.kernel.org
Reported-by: Vegard Nossum &lt;vegard.nossum@oracle.com&gt;
Signed-off-by: Jan Kara &lt;jack@suse.cz&gt;
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ext4: clean up error handling when orphan list is corrupted</title>
<updated>2016-06-03T15:30:31+00:00</updated>
<author>
<name>Theodore Ts'o</name>
<email>tytso@mit.edu</email>
</author>
<published>2016-04-30T04:49:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=d503e0124b441905360fc98cb7d42a1f1e8fb15d'/>
<id>d503e0124b441905360fc98cb7d42a1f1e8fb15d</id>
<content type='text'>
[ Upstream commit 7827a7f6ebfcb7f388dc47fddd48567a314701ba ]

Instead of just printing warning messages, if the orphan list is
corrupted, declare the file system is corrupted.  If there are any
reserved inodes in the orphaned inode list, declare the file system
corrupted and stop right away to avoid doing more potential damage to
the file system.

Cc: stable@vger.kernel.org
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 7827a7f6ebfcb7f388dc47fddd48567a314701ba ]

Instead of just printing warning messages, if the orphan list is
corrupted, declare the file system is corrupted.  If there are any
reserved inodes in the orphaned inode list, declare the file system
corrupted and stop right away to avoid doing more potential damage to
the file system.

Cc: stable@vger.kernel.org
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ext4: fix hang when processing corrupted orphaned inode list</title>
<updated>2016-06-03T15:30:31+00:00</updated>
<author>
<name>Theodore Ts'o</name>
<email>tytso@mit.edu</email>
</author>
<published>2016-04-30T04:48:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=424a4c24ee0a9fab85e450c1f69439af2d7d7a51'/>
<id>424a4c24ee0a9fab85e450c1f69439af2d7d7a51</id>
<content type='text'>
[ Upstream commit c9eb13a9105e2e418f72e46a2b6da3f49e696902 ]

If the orphaned inode list contains inode #5, ext4_iget() returns a
bad inode (since the bootloader inode should never be referenced
directly).  Because of the bad inode, we end up processing the inode
repeatedly and this hangs the machine.

This can be reproduced via:

   mke2fs -t ext4 /tmp/foo.img 100
   debugfs -w -R "ssv last_orphan 5" /tmp/foo.img
   mount -o loop /tmp/foo.img /mnt

(But don't do this if you are using an unpatched kernel if you care
about the system staying functional.  :-)

This bug was found by the port of American Fuzzy Lop into the kernel
to find file system problems[1].  (Since it *only* happens if inode #5
shows up on the orphan list --- 3, 7, 8, etc. won't do it, it's not
surprising that AFL needed two hours before it found it.)

[1] http://events.linuxfoundation.org/sites/events/files/slides/AFL%20filesystem%20fuzzing%2C%20Vault%202016_0.pdf

Cc: stable@vger.kernel.org
Reported by: Vegard Nossum &lt;vegard.nossum@oracle.com&gt;
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;

Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit c9eb13a9105e2e418f72e46a2b6da3f49e696902 ]

If the orphaned inode list contains inode #5, ext4_iget() returns a
bad inode (since the bootloader inode should never be referenced
directly).  Because of the bad inode, we end up processing the inode
repeatedly and this hangs the machine.

This can be reproduced via:

   mke2fs -t ext4 /tmp/foo.img 100
   debugfs -w -R "ssv last_orphan 5" /tmp/foo.img
   mount -o loop /tmp/foo.img /mnt

(But don't do this if you are using an unpatched kernel if you care
about the system staying functional.  :-)

This bug was found by the port of American Fuzzy Lop into the kernel
to find file system problems[1].  (Since it *only* happens if inode #5
shows up on the orphan list --- 3, 7, 8, etc. won't do it, it's not
surprising that AFL needed two hours before it found it.)

[1] http://events.linuxfoundation.org/sites/events/files/slides/AFL%20filesystem%20fuzzing%2C%20Vault%202016_0.pdf

Cc: stable@vger.kernel.org
Reported by: Vegard Nossum &lt;vegard.nossum@oracle.com&gt;
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;

Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ext4: ignore quota mount options if the quota feature is enabled</title>
<updated>2016-04-20T05:27:48+00:00</updated>
<author>
<name>Theodore Ts'o</name>
<email>tytso@mit.edu</email>
</author>
<published>2016-04-03T21:03:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=3c853788bdd85e73e9eb5bb8d3f40201a933ad93'/>
<id>3c853788bdd85e73e9eb5bb8d3f40201a933ad93</id>
<content type='text'>
[ Upstream commit c325a67c72903e1cc30e990a15ce745bda0dbfde ]

Previously, ext4 would fail the mount if the file system had the quota
feature enabled and quota mount options (used for the older quota
setups) were present.  This broke xfstests, since xfs silently ignores
the usrquote and grpquota mount options if they are specified.  This
commit changes things so that we are consistent with xfs; having the
mount options specified is harmless, so no sense break users by
forbidding them.

Cc: stable@vger.kernel.org
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit c325a67c72903e1cc30e990a15ce745bda0dbfde ]

Previously, ext4 would fail the mount if the file system had the quota
feature enabled and quota mount options (used for the older quota
setups) were present.  This broke xfstests, since xfs silently ignores
the usrquote and grpquota mount options if they are specified.  This
commit changes things so that we are consistent with xfs; having the
mount options specified is harmless, so no sense break users by
forbidding them.

Cc: stable@vger.kernel.org
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ext4: add lockdep annotations for i_data_sem</title>
<updated>2016-04-20T05:27:37+00:00</updated>
<author>
<name>Theodore Ts'o</name>
<email>tytso@mit.edu</email>
</author>
<published>2016-04-01T05:31:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=4fcac08014394972bfb9b63e10e841770ad34b8e'/>
<id>4fcac08014394972bfb9b63e10e841770ad34b8e</id>
<content type='text'>
[ Upstream commit daf647d2dd58cec59570d7698a45b98e580f2076 ]

With the internal Quota feature, mke2fs creates empty quota inodes and
quota usage tracking is enabled as soon as the file system is mounted.
Since quotacheck is no longer preallocating all of the blocks in the
quota inode that are likely needed to be written to, we are now seeing
a lockdep false positive caused by needing to allocate a quota block
from inside ext4_map_blocks(), while holding i_data_sem for a data
inode.  This results in this complaint:

  Possible unsafe locking scenario:

        CPU0                    CPU1
        ----                    ----
   lock(&amp;ei-&gt;i_data_sem);
                                lock(&amp;s-&gt;s_dquot.dqio_mutex);
                                lock(&amp;ei-&gt;i_data_sem);
   lock(&amp;s-&gt;s_dquot.dqio_mutex);

Google-Bug-Id: 27907753

Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit daf647d2dd58cec59570d7698a45b98e580f2076 ]

With the internal Quota feature, mke2fs creates empty quota inodes and
quota usage tracking is enabled as soon as the file system is mounted.
Since quotacheck is no longer preallocating all of the blocks in the
quota inode that are likely needed to be written to, we are now seeing
a lockdep false positive caused by needing to allocate a quota block
from inside ext4_map_blocks(), while holding i_data_sem for a data
inode.  This results in this complaint:

  Possible unsafe locking scenario:

        CPU0                    CPU1
        ----                    ----
   lock(&amp;ei-&gt;i_data_sem);
                                lock(&amp;s-&gt;s_dquot.dqio_mutex);
                                lock(&amp;ei-&gt;i_data_sem);
   lock(&amp;s-&gt;s_dquot.dqio_mutex);

Google-Bug-Id: 27907753

Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ext4: iterate over buffer heads correctly in move_extent_per_page()</title>
<updated>2016-04-18T12:49:16+00:00</updated>
<author>
<name>Eryu Guan</name>
<email>guaneryu@gmail.com</email>
</author>
<published>2016-02-21T23:38:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=d3b9f52c79ea65d9256e7a49a1c9c259bae2bd68'/>
<id>d3b9f52c79ea65d9256e7a49a1c9c259bae2bd68</id>
<content type='text'>
[ Upstream commit 87f9a031af48defee9f34c6aaf06d6f1988c244d ]

In commit bcff24887d00 ("ext4: don't read blocks from disk after extents
being swapped") bh is not updated correctly in the for loop and wrong
data has been written to disk. generic/324 catches this on sub-page
block size ext4.

Fixes: bcff24887d00 ("ext4: don't read blocks from disk after extentsbeing swapped")
Signed-off-by: Eryu Guan &lt;guaneryu@gmail.com&gt;
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 87f9a031af48defee9f34c6aaf06d6f1988c244d ]

In commit bcff24887d00 ("ext4: don't read blocks from disk after extents
being swapped") bh is not updated correctly in the for loop and wrong
data has been written to disk. generic/324 catches this on sub-page
block size ext4.

Fixes: bcff24887d00 ("ext4: don't read blocks from disk after extentsbeing swapped")
Signed-off-by: Eryu Guan &lt;guaneryu@gmail.com&gt;
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ext4: fix crashes in dioread_nolock mode</title>
<updated>2016-03-04T15:18:43+00:00</updated>
<author>
<name>Jan Kara</name>
<email>jack@suse.cz</email>
</author>
<published>2016-02-19T05:33:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=2bc4fc8104b15fc237204165d5c35f9bb069680a'/>
<id>2bc4fc8104b15fc237204165d5c35f9bb069680a</id>
<content type='text'>
[ Upstream commit 74dae4278546b897eb81784fdfcce872ddd8b2b8 ]

Competing overwrite DIO in dioread_nolock mode will just overwrite
pointer to io_end in the inode. This may result in data corruption or
extent conversion happening from IO completion interrupt because we
don't properly set buffer_defer_completion() when unlocked DIO races
with locked DIO to unwritten extent.

Since unlocked DIO doesn't need io_end for anything, just avoid
allocating it and corrupting pointer from inode for locked DIO.
A cleaner fix would be to avoid these games with io_end pointer from the
inode but that requires more intrusive changes so we leave that for
later.

Cc: stable@vger.kernel.org
Signed-off-by: Jan Kara &lt;jack@suse.cz&gt;
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 74dae4278546b897eb81784fdfcce872ddd8b2b8 ]

Competing overwrite DIO in dioread_nolock mode will just overwrite
pointer to io_end in the inode. This may result in data corruption or
extent conversion happening from IO completion interrupt because we
don't properly set buffer_defer_completion() when unlocked DIO races
with locked DIO to unwritten extent.

Since unlocked DIO doesn't need io_end for anything, just avoid
allocating it and corrupting pointer from inode for locked DIO.
A cleaner fix would be to avoid these games with io_end pointer from the
inode but that requires more intrusive changes so we leave that for
later.

Cc: stable@vger.kernel.org
Signed-off-by: Jan Kara &lt;jack@suse.cz&gt;
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ext4: don't read blocks from disk after extents being swapped</title>
<updated>2016-03-04T15:18:41+00:00</updated>
<author>
<name>Eryu Guan</name>
<email>guaneryu@gmail.com</email>
</author>
<published>2016-02-12T06:20:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=b42e89beb60b3b618b180349a0e3b02ae3d4657e'/>
<id>b42e89beb60b3b618b180349a0e3b02ae3d4657e</id>
<content type='text'>
[ Upstream commit bcff24887d00bce102e0857d7b0a8c44a40f53d1 ]

I notice ext4/307 fails occasionally on ppc64 host, reporting md5
checksum mismatch after moving data from original file to donor file.

The reason is that move_extent_per_page() calls __block_write_begin()
and block_commit_write() to write saved data from original inode blocks
to donor inode blocks, but __block_write_begin() not only maps buffer
heads but also reads block content from disk if the size is not block
size aligned.  At this time the physical block number in mapped buffer
head is pointing to the donor file not the original file, and that
results in reading wrong data to page, which get written to disk in
following block_commit_write call.

This also can be reproduced by the following script on 1k block size ext4
on x86_64 host:

    mnt=/mnt/ext4
    donorfile=$mnt/donor
    testfile=$mnt/testfile
    e4compact=~/xfstests/src/e4compact

    rm -f $donorfile $testfile

    # reserve space for donor file, written by 0xaa and sync to disk to
    # avoid EBUSY on EXT4_IOC_MOVE_EXT
    xfs_io -fc "pwrite -S 0xaa 0 1m" -c "fsync" $donorfile

    # create test file written by 0xbb
    xfs_io -fc "pwrite -S 0xbb 0 1023" -c "fsync" $testfile

    # compute initial md5sum
    md5sum $testfile | tee md5sum.txt
    # drop cache, force e4compact to read data from disk
    echo 3 &gt; /proc/sys/vm/drop_caches

    # test defrag
    echo "$testfile" | $e4compact -i -v -f $donorfile
    # check md5sum
    md5sum -c md5sum.txt

Fix it by creating &amp; mapping buffer heads only but not reading blocks
from disk, because all the data in page is guaranteed to be up-to-date
in mext_page_mkuptodate().

Cc: stable@vger.kernel.org
Signed-off-by: Eryu Guan &lt;guaneryu@gmail.com&gt;
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit bcff24887d00bce102e0857d7b0a8c44a40f53d1 ]

I notice ext4/307 fails occasionally on ppc64 host, reporting md5
checksum mismatch after moving data from original file to donor file.

The reason is that move_extent_per_page() calls __block_write_begin()
and block_commit_write() to write saved data from original inode blocks
to donor inode blocks, but __block_write_begin() not only maps buffer
heads but also reads block content from disk if the size is not block
size aligned.  At this time the physical block number in mapped buffer
head is pointing to the donor file not the original file, and that
results in reading wrong data to page, which get written to disk in
following block_commit_write call.

This also can be reproduced by the following script on 1k block size ext4
on x86_64 host:

    mnt=/mnt/ext4
    donorfile=$mnt/donor
    testfile=$mnt/testfile
    e4compact=~/xfstests/src/e4compact

    rm -f $donorfile $testfile

    # reserve space for donor file, written by 0xaa and sync to disk to
    # avoid EBUSY on EXT4_IOC_MOVE_EXT
    xfs_io -fc "pwrite -S 0xaa 0 1m" -c "fsync" $donorfile

    # create test file written by 0xbb
    xfs_io -fc "pwrite -S 0xbb 0 1023" -c "fsync" $testfile

    # compute initial md5sum
    md5sum $testfile | tee md5sum.txt
    # drop cache, force e4compact to read data from disk
    echo 3 &gt; /proc/sys/vm/drop_caches

    # test defrag
    echo "$testfile" | $e4compact -i -v -f $donorfile
    # check md5sum
    md5sum -c md5sum.txt

Fix it by creating &amp; mapping buffer heads only but not reading blocks
from disk, because all the data in page is guaranteed to be up-to-date
in mext_page_mkuptodate().

Cc: stable@vger.kernel.org
Signed-off-by: Eryu Guan &lt;guaneryu@gmail.com&gt;
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
