f2fs: fix to do sanity check with reserved blkaddr of inline inode (CVE-2018-13099)

This commit is contained in:
Salvatore Bonaccorso 2018-09-22 17:26:30 +02:00
parent f46ed6ff17
commit 310f694a6b
3 changed files with 158 additions and 0 deletions

2
debian/changelog vendored
View File

@ -25,6 +25,8 @@ linux (4.18.8-2) UNRELEASED; urgency=medium
[ Salvatore Bonaccorso ]
* floppy: Do not copy a kernel pointer to user memory in FDGETPRM ioctl
(CVE-2018-7755)
* f2fs: fix to do sanity check with reserved blkaddr of inline inode
(CVE-2018-13099)
-- Vagrant Cascadian <vagrant@debian.org> Tue, 18 Sep 2018 10:13:18 -0700

View File

@ -0,0 +1,155 @@
From: Chao Yu <yuchao0@huawei.com>
Date: Sat, 30 Jun 2018 18:13:40 +0800
Subject: f2fs: fix to do sanity check with reserved blkaddr of inline inode
Origin: https://git.kernel.org/linus/4dbe38dc386910c668c75ae616b99b823b59f3eb
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2018-13099
As Wen Xu reported in bugzilla, after image was injected with random data
by fuzzing, inline inode would contain invalid reserved blkaddr, then
during inline conversion, we will encounter illegal memory accessing
reported by KASAN, the root cause of this is when writing out converted
inline page, we will use invalid reserved blkaddr to update sit bitmap,
result in accessing memory beyond sit bitmap boundary.
In order to fix this issue, let's do sanity check with reserved block
address of inline inode to avoid above condition.
https://bugzilla.kernel.org/show_bug.cgi?id=200179
[ 1428.846352] BUG: KASAN: use-after-free in update_sit_entry+0x80/0x7f0
[ 1428.846618] Read of size 4 at addr ffff880194483540 by task a.out/2741
[ 1428.846855] CPU: 0 PID: 2741 Comm: a.out Tainted: G W 4.17.0+ #1
[ 1428.846858] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
[ 1428.846860] Call Trace:
[ 1428.846868] dump_stack+0x71/0xab
[ 1428.846875] print_address_description+0x6b/0x290
[ 1428.846881] kasan_report+0x28e/0x390
[ 1428.846888] ? update_sit_entry+0x80/0x7f0
[ 1428.846898] update_sit_entry+0x80/0x7f0
[ 1428.846906] f2fs_allocate_data_block+0x6db/0xc70
[ 1428.846914] ? f2fs_get_node_info+0x14f/0x590
[ 1428.846920] do_write_page+0xc8/0x150
[ 1428.846928] f2fs_outplace_write_data+0xfe/0x210
[ 1428.846935] ? f2fs_do_write_node_page+0x170/0x170
[ 1428.846941] ? radix_tree_tag_clear+0xff/0x130
[ 1428.846946] ? __mod_node_page_state+0x22/0xa0
[ 1428.846951] ? inc_zone_page_state+0x54/0x100
[ 1428.846956] ? __test_set_page_writeback+0x336/0x5d0
[ 1428.846964] f2fs_convert_inline_page+0x407/0x6d0
[ 1428.846971] ? f2fs_read_inline_data+0x3b0/0x3b0
[ 1428.846978] ? __get_node_page+0x335/0x6b0
[ 1428.846987] f2fs_convert_inline_inode+0x41b/0x500
[ 1428.846994] ? f2fs_convert_inline_page+0x6d0/0x6d0
[ 1428.847000] ? kasan_unpoison_shadow+0x31/0x40
[ 1428.847005] ? kasan_kmalloc+0xa6/0xd0
[ 1428.847024] f2fs_file_mmap+0x79/0xc0
[ 1428.847029] mmap_region+0x58b/0x880
[ 1428.847037] ? arch_get_unmapped_area+0x370/0x370
[ 1428.847042] do_mmap+0x55b/0x7a0
[ 1428.847048] vm_mmap_pgoff+0x16f/0x1c0
[ 1428.847055] ? vma_is_stack_for_current+0x50/0x50
[ 1428.847062] ? __fsnotify_update_child_dentry_flags.part.1+0x160/0x160
[ 1428.847068] ? do_sys_open+0x206/0x2a0
[ 1428.847073] ? __fget+0xb4/0x100
[ 1428.847079] ksys_mmap_pgoff+0x278/0x360
[ 1428.847085] ? find_mergeable_anon_vma+0x50/0x50
[ 1428.847091] do_syscall_64+0x73/0x160
[ 1428.847098] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 1428.847102] RIP: 0033:0x7fb1430766ba
[ 1428.847103] Code: 89 f5 41 54 49 89 fc 55 53 74 35 49 63 e8 48 63 da 4d 89 f9 49 89 e8 4d 63 d6 48 89 da 4c 89 ee 4c 89 e7 b8 09 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 56 5b 5d 41 5c 41 5d 41 5e 41 5f c3 0f 1f 00
[ 1428.847162] RSP: 002b:00007ffc651d9388 EFLAGS: 00000246 ORIG_RAX: 0000000000000009
[ 1428.847167] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007fb1430766ba
[ 1428.847170] RDX: 0000000000000001 RSI: 0000000000001000 RDI: 0000000000000000
[ 1428.847173] RBP: 0000000000000003 R08: 0000000000000003 R09: 0000000000000000
[ 1428.847176] R10: 0000000000008002 R11: 0000000000000246 R12: 0000000000000000
[ 1428.847179] R13: 0000000000001000 R14: 0000000000008002 R15: 0000000000000000
[ 1428.847252] Allocated by task 2683:
[ 1428.847372] kasan_kmalloc+0xa6/0xd0
[ 1428.847380] kmem_cache_alloc+0xc8/0x1e0
[ 1428.847385] getname_flags+0x73/0x2b0
[ 1428.847390] user_path_at_empty+0x1d/0x40
[ 1428.847395] vfs_statx+0xc1/0x150
[ 1428.847401] __do_sys_newlstat+0x7e/0xd0
[ 1428.847405] do_syscall_64+0x73/0x160
[ 1428.847411] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 1428.847466] Freed by task 2683:
[ 1428.847566] __kasan_slab_free+0x137/0x190
[ 1428.847571] kmem_cache_free+0x85/0x1e0
[ 1428.847575] filename_lookup+0x191/0x280
[ 1428.847580] vfs_statx+0xc1/0x150
[ 1428.847585] __do_sys_newlstat+0x7e/0xd0
[ 1428.847590] do_syscall_64+0x73/0x160
[ 1428.847596] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 1428.847648] The buggy address belongs to the object at ffff880194483300
which belongs to the cache names_cache of size 4096
[ 1428.847946] The buggy address is located 576 bytes inside of
4096-byte region [ffff880194483300, ffff880194484300)
[ 1428.848234] The buggy address belongs to the page:
[ 1428.848366] page:ffffea0006512000 count:1 mapcount:0 mapping:ffff8801f3586380 index:0x0 compound_mapcount: 0
[ 1428.848606] flags: 0x17fff8000008100(slab|head)
[ 1428.848737] raw: 017fff8000008100 dead000000000100 dead000000000200 ffff8801f3586380
[ 1428.848931] raw: 0000000000000000 0000000000070007 00000001ffffffff 0000000000000000
[ 1428.849122] page dumped because: kasan: bad access detected
[ 1428.849305] Memory state around the buggy address:
[ 1428.849436] ffff880194483400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 1428.849620] ffff880194483480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 1428.849804] >ffff880194483500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 1428.849985] ^
[ 1428.850120] ffff880194483580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 1428.850303] ffff880194483600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 1428.850498] ==================================================================
Reported-by: Wen Xu <wen.xu@gatech.edu>
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fs/f2fs/inline.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
index 9a245d2d5b7c..2bcb2d36f024 100644
--- a/fs/f2fs/inline.c
+++ b/fs/f2fs/inline.c
@@ -130,6 +130,16 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page)
if (err)
return err;
+ if (unlikely(dn->data_blkaddr != NEW_ADDR)) {
+ f2fs_put_dnode(dn);
+ set_sbi_flag(fio.sbi, SBI_NEED_FSCK);
+ f2fs_msg(fio.sbi->sb, KERN_WARNING,
+ "%s: corrupted inline inode ino=%lx, i_addr[0]:0x%x, "
+ "run fsck to fix.",
+ __func__, dn->inode->i_ino, dn->data_blkaddr);
+ return -EINVAL;
+ }
+
f2fs_bug_on(F2FS_P_SB(page), PageWriteback(page));
f2fs_do_read_inline_data(page, dn->inode_page);
@@ -363,6 +373,17 @@ static int f2fs_move_inline_dirents(struct inode *dir, struct page *ipage,
if (err)
goto out;
+ if (unlikely(dn.data_blkaddr != NEW_ADDR)) {
+ f2fs_put_dnode(&dn);
+ set_sbi_flag(F2FS_P_SB(page), SBI_NEED_FSCK);
+ f2fs_msg(F2FS_P_SB(page)->sb, KERN_WARNING,
+ "%s: corrupted inline inode ino=%lx, i_addr[0]:0x%x, "
+ "run fsck to fix.",
+ __func__, dir->i_ino, dn.data_blkaddr);
+ err = -EINVAL;
+ goto out;
+ }
+
f2fs_wait_on_page_writeback(page, DATA, true);
dentry_blk = page_address(page);
--
2.11.0

View File

@ -144,6 +144,7 @@ features/all/lockdown/arm64-add-kernel-config-option-to-lock-down-when.patch
debian/i386-686-pae-pci-set-pci-nobios-by-default.patch
bugfix/all/Revert-net-increase-fragment-memory-usage-limits.patch
bugfix/all/floppy-Do-not-copy-a-kernel-pointer-to-user-memory-i.patch
bugfix/all/f2fs-fix-to-do-sanity-check-with-reserved-blkaddr-of.patch
# Fix exported symbol versions
bugfix/all/module-disable-matching-missing-version-crc.patch