CVE-2019-19319
Target
Linux Kernel Ext4 FileSystem
Linux Version | Availablity |
---|---|
5.0.21 | True |
5.3.11 | False |
5.4.0 | mount fail |
Bug Type
slab-out-of-bounds
Abstract
setxattr operation(after mount crafted image) can cause slab-out-of-bound write vulnerability
Reproduce
gcc -o poc poc_2019_19319.c
mkdir mnt
mount poc_2019_19319.img ./mnt
cp poc ./mnt/
cd mnt
./poc
Details
Debug View
─────────────────────────────────────────────────────────── registers ────
$rax : 0xffff8880684ebbdc → 0x68026258ffff8880 → 0x68026258ffff8880
$rbx : 0xffff8880674ebbd8 → 0x74737973565dbd3e → 0x74737973565dbd3e
$rcx : 0xffffffff81a28fa8 → 0x48f6311824548b48 → 0x48f6311824548b48
$rdx : 0x0000000001000004 → 0x0000000001000004
$rsp : 0xffff88806a25f0a8 → 0xffff88806a25f250 → 0x0000000000000000 → 0x0000000000000000
$rbp : 0xffff88806a25f6b8 → 0xffff8880674eb820 → 0x0000000003d80108 → 0x0000000003d80108
$rsi : 0x0000000000000000 → 0x0000000000000000
$rdi : 0xffff8880674ebbd8 → 0x74737973565dbd3e → 0x74737973565dbd3e
$rip : 0xffffffff81a28fb2 → 0x448b48ffc3fcd9e8 → 0x448b48ffc3fcd9e8
$r8 : 0x0000000000000001 → 0x0000000000000001
$r9 : 0x0000000000000000 → 0x0000000000000000
$r10 : 0x0000000000000000 → 0x0000000000000000
$r11 : 0x0000000000000000 → 0x0000000000000000
$r12 : 0x00000000000003d8 → 0x00000000000003d8
$r13 : 0xdffffc0000000000 → 0xdffffc0000000000
$r14 : 0xffff88806a25f800 → 0xffff88806a25fbdd → 0x584d394e64685964 → 0x584d394e64685964
$r15 : 0xffff8880674eb820 → 0x0000000003d80108 → 0x0000000003d80108
$eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflowresume virtualx86 identification]
$cs: 0x0010 $ss: 0x0018 $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000
─────────────────────────────────────────────────────────────── stack ────
0xffff88806a25f0a8│+0x0000: 0xffff88806a25f250 → 0x0000000000000000 →0x0000000000000000 ← $rsp
0xffff88806a25f0b0│+0x0008: 0xffff88806a25f210 → 0x0000000000000000 →0x0000000000000000
0xffff88806a25f0b8│+0x0010: 0xffffffff00000000 → 0xffffffff00000000
0xffff88806a25f0c0│+0x0018: 0x0000000001000004 → 0x0000000001000004
0xffff88806a25f0c8│+0x0020: 0x0000000000000040 → 0x0000000000000040
0xffff88806a25f0d0│+0x0028: 0xffff8880663b03d8 → 0xffff8880663b03d0 →0xffff8880663b03d0 → [loop detected]
0xffff88806a25f0d8│+0x0030: 0x1ffff1100d44be36 → 0x1ffff1100d44be36
0xffff88806a25f0e0│+0x0038: 0x0000000141b58ab3 → 0x0000000141b58ab3
───────────────────────────────────────────────────────── code:x86:64 ────
0xffffffff81a28fa8 <ext4_xattr_set_entry+7000> mov rdx, QWORD PTR [rsp+0x18]
0xffffffff81a28fad <ext4_xattr_set_entry+7005> xor esi, esi
0xffffffff81a28faf <ext4_xattr_set_entry+7007> mov rdi, rbx
→ 0xffffffff81a28fb2 <ext4_xattr_set_entry+7010> call 0xffffffff81668c90 <memset>
↳ 0xffffffff81668c90 <memset+0> push r12
0xffffffff81668c92 <memset+2> push rbp
0xffffffff81668c93 <memset+3> mov rbp, rdx
0xffffffff81668c96 <memset+6> push rbx
0xffffffff81668c97 <memset+7> mov rcx, QWORD PTR [rsp+0x18]
0xffffffff81668c9c <memset+12> mov rbx, rdi
─────────────────────────────────────────────────────────── arguments ────
memset (
QWORD var_0 = 0xffff8880674ebbd8 → 0x74737973565dbd3e → 0x74737973565dbd3e,
int var_1 = 0x0000000000000000 → 0x0000000000000000,
size_t var_2 = 0x0000000001000004 → 0x0000000001000004
)
───────────────────────────────────────── source:fs/ext4/xattr.c+1706 ────
1701 void *first_val = s->base + min_offs;
1702 size_t offs = le16_to_cpu(here->e_value_offs);
1703 void *val = s->base + offs;
1704
1705 memmove(first_val + old_size, first_val, val - first_val);
→ 1706 memset(first_val, 0, old_size);
1707 min_offs += old_size;
1708
1709 /* Adjust all value offsets. */
1710 last = s->first;
1711 while (!IS_LAST_ENTRY(last)) {
───────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "", stopped, reason: BREAKPOINT
[#1] Id 2, Name: "", stopped, reason: BREAKPOINT
─────────────────────────────────────────────────────────────── trace ────
[#0] 0xffffffff81a28fb2 → ext4_xattr_set_entry(i=0xffff88806a25f800, s=0xffff88806a25f6b8, handle=<optimized out>, inode=<optimized out>, is_block=<optimized out>)
[#1] 0xffffffff81a2b42a → ext4_xattr_block_set(handle=<optimized out>, inode=<optimized out>, i=0xffff88806a25f800, bs=<optimized out>)
[#2] 0xffffffff81a3268f → ext4_xattr_set_handle(handle=<optimized out>, inode=0xffff8880663bea90, name_index=<optimized out>, name=<optimized out>,value=<optimized out>, value_len=<optimized out>, flags=<optimized out>)
[#3] 0xffffffff81a333e9 → ext4_xattr_set(inode=0xffff8880674ebbd8, name_index=<optimized out>, name=<optimized out>, value=<optimized out>, value_len=<optimized out>, flags=<optimized out>)
[#4] 0xffffffff8172502f → __vfs_setxattr(dentry=0xffff8880662bc500, inode=0xffff8880663bea90, name=0xffff88806a25fbdd "dYhdN9MX", value=0xffff88806c4f4180, size=0x3f, flags=0x2)
[#5] 0xffffffff81727761 → __vfs_setxattr_noperm(dentry=0xffff8880674ebbd8, name=0x0 <irq_stack_union>, value=<optimized out>, size=<optimized out>,flags=0x1)
[#6] 0xffffffff81727aad → vfs_setxattr(dentry=0xffff8880662bc500, name=0xffff88806a25fbd8 "user.dYhdN9MX", value=0xffff88806c4f4180, size=0x3f, flags=0x2)
[#7] 0xffffffff81727d13 → setxattr(d=0xffff8880662bc500, name=<optimized out>, value=<optimized out>, size=0x3f, flags=0x2)
[#8] 0xffffffff81727f36 → path_setxattr(pathname=0x7ffc27602615 "foo/z5NkeKcl", name=<optimized out>, value=<optimized out>, size=<optimized out>, flags=<optimized out>, lookup_flags=0x1)
[#9] 0xffffffff8172803b → __do_sys_setxattr(flags=<optimized out>, size=<optimized out>, value=<optimized out>, name=<optimized out>, pathname=<optimized out>)
──────────────────────────────────────────────────────────────────────────
Thread 2 hit Breakpoint 1, 0xffffffff81a28fb2 in ext4_xattr_set_entry (i=0xffff88806a25f800, s=0xffff88806a25f6b8, handle=<optimized out>, inode=<optimized out>, is_block=<optimized out>) at fs/ext4/xattr.c:1706
1706 memset(first_val, 0, old_size);
gef➤
local variable old_size
appears 0x1000004
Bug Causes
fs/ext4/xattr.c:1706 (link)
static int ext4_xattr_set_entry(struct ext4_xattr_info *i,
struct ext4_xattr_search *s,
handle_t *handle, struct inode *inode,
bool is_block)
{
struct ext4_xattr_entry *last, *next;
struct ext4_xattr_entry *here = s->here;
size_t min_offs = s->end - s->base, name_len = strlen(i->name);
int in_inode = i->in_inode;
struct inode *old_ea_inode = NULL;
struct inode *new_ea_inode = NULL;
size_t old_size, new_size;
int ret;
/* Space used by old and new values. */
old_size = (!s->not_found && !here->e_value_inum) ?
[1] EXT4_XATTR_SIZE(le32_to_cpu(here->e_value_size)) : 0;
new_size = (i->value && !in_inode) ? EXT4_XATTR_SIZE(i->value_len) : 0;
/*
* Optimization for the simple case when old and new values have the
* same padded sizes. Not applicable if external inodes are involved.
*/
if (new_size && new_size == old_size) {
size_t offs = le16_to_cpu(here->e_value_offs);
void *val = s->base + offs;
here->e_value_size = cpu_to_le32(i->value_len);
if (i->value == EXT4_ZERO_XATTR_VALUE) {
memset(val, 0, new_size);
} else {
memcpy(val, i->value, i->value_len);
/* Clear padding bytes. */
memset(val + i->value_len, 0, new_size - i->value_len);
}
goto update_hash;
}
/* Compute min_offs and last. */
last = s->first;
for (; !IS_LAST_ENTRY(last); last = next) {
next = EXT4_XATTR_NEXT(last);
if ((void *)next >= s->end) {
EXT4_ERROR_INODE(inode, "corrupted xattr entries");
ret = -EFSCORRUPTED;
goto out;
}
if (!last->e_value_inum && last->e_value_size) {
size_t offs = le16_to_cpu(last->e_value_offs);
if (offs < min_offs)
min_offs = offs;
}
}
/* Check whether we have enough space. */
if (i->value) {
size_t free;
free = min_offs - ((void *)last - s->base) - sizeof(__u32);
if (!s->not_found)
free += EXT4_XATTR_LEN(name_len) + old_size;
if (free < EXT4_XATTR_LEN(name_len) + new_size) {
ret = -ENOSPC;
goto out;
}
/*
* If storing the value in an external inode is an option,
* reserve space for xattr entries/names in the external
* attribute block so that a long value does not occupy the
* whole space and prevent futher entries being added.
*/
if (ext4_has_feature_ea_inode(inode->i_sb) &&
new_size && is_block &&
(min_offs + old_size - new_size) <
EXT4_XATTR_BLOCK_RESERVE(inode)) {
ret = -ENOSPC;
goto out;
}
}
/*
* Getting access to old and new ea inodes is subject to failures.
* Finish that work before doing any modifications to the xattr data.
*/
if (!s->not_found && here->e_value_inum) {
ret = ext4_xattr_inode_iget(inode,
le32_to_cpu(here->e_value_inum),
le32_to_cpu(here->e_hash),
&old_ea_inode);
if (ret) {
old_ea_inode = NULL;
goto out;
}
}
if (i->value && in_inode) {
WARN_ON_ONCE(!i->value_len);
ret = ext4_xattr_inode_alloc_quota(inode, i->value_len);
if (ret)
goto out;
ret = ext4_xattr_inode_lookup_create(handle, inode, i->value,
i->value_len,
&new_ea_inode);
if (ret) {
new_ea_inode = NULL;
ext4_xattr_inode_free_quota(inode, NULL, i->value_len);
goto out;
}
}
if (old_ea_inode) {
/* We are ready to release ref count on the old_ea_inode. */
ret = ext4_xattr_inode_dec_ref(handle, old_ea_inode);
if (ret) {
/* Release newly required ref count on new_ea_inode. */
if (new_ea_inode) {
int err;
err = ext4_xattr_inode_dec_ref(handle,
new_ea_inode);
if (err)
ext4_warning_inode(new_ea_inode,
"dec ref new_ea_inode err=%d",
err);
ext4_xattr_inode_free_quota(inode, new_ea_inode,
i->value_len);
}
goto out;
}
ext4_xattr_inode_free_quota(inode, old_ea_inode,
le32_to_cpu(here->e_value_size));
}
/* No failures allowed past this point. */
if (!s->not_found && here->e_value_size && !here->e_value_inum) {
/* Remove the old value. */
void *first_val = s->base + min_offs;
size_t offs = le16_to_cpu(here->e_value_offs);
void *val = s->base + offs;
memmove(first_val + old_size, first_val, val - first_val);
[2] memset(first_val, 0, old_size);
min_offs += old_size;
...
in [1], set old_size
to huge value, and call memset
with old_size
KASAN logs
[ 610.867441] EXT4-fs (loop0): mounted filesystem with ordered data mode. Opts: (null)
[ 611.627638] cp (1969) used greatest stack depth: 47912 bytes left
[ 611.826655] ==================================================================
[ 611.827411] BUG: KASAN: use-after-free in ext4_xattr_set_entry+0x1b67/0x3550
[ 611.827411] Write of size 16777220 at addr ffff888069becbd8 by task poc/1971
[ 611.827411]
[ 611.827411] CPU: 1 PID: 1971 Comm: poc Not tainted 5.0.21 #1
[ 611.827411] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014
[ 611.827411] Call Trace:
[ 611.827411] dump_stack+0xae/0x14b
[ 611.827411] ? show_regs_print_info+0x5/0x5
[ 611.827411] ? kmsg_dump_rewind_nolock+0xd4/0xd4
[ 611.827411] ? _raw_spin_lock_irqsave+0x9f/0x130
[ 611.827411] ? _raw_write_lock_irqsave+0x130/0x130
[ 611.827411] ? ext4_xattr_set_entry+0x1b67/0x3550
[ 611.827411] print_address_description+0x6e/0x280
[ 611.827411] ? ext4_xattr_set_entry+0x1b67/0x3550
[ 611.827411] ? ext4_xattr_set_entry+0x1b67/0x3550
[ 611.827411] kasan_report+0x149/0x18d
[ 611.827411] ? ext4_xattr_block_set+0x7e1/0x3a00
[ 611.827411] ? ext4_xattr_set_entry+0x1b67/0x3550
[ 611.827411] memset+0x1f/0x40
[ 611.827411] ext4_xattr_set_entry+0x1b67/0x3550
[ 611.827411] ? rcu_is_watching+0x7d/0x130
[ 611.827411] ? entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 611.827411] ? rcu_barrier_trace+0x260/0x260
[ 611.827411] ? add_transaction_credits+0x1c7/0xd50
[ 611.827411] ? ext4_xattr_inode_get+0x8e0/0x8e0
[ 611.827411] ? __kernel_text_address+0x9/0x30
[ 611.827411] ? _raw_spin_lock+0x99/0x130
[ 611.827411] ? __kasan_slab_free+0x143/0x180
[ 611.827411] ? kmem_cache_free+0x70/0x1a0
[ 611.827411] ? mb_cache_entry_delete+0x4f3/0x820
[ 611.827411] ? __mb_cache_entry_free+0x10/0x10
[ 611.827411] ? __find_get_block+0x1a3/0xaf0
[ 611.827411] ? __find_get_block+0x1a3/0xaf0
[ 611.827411] ? __find_get_block+0x1a3/0xaf0
[ 611.827411] ? __jbd2_journal_temp_unlink_buffer+0x530/0x530
[ 611.827411] ? try_to_free_buffers+0x4d0/0x4d0
[ 611.827411] ? rcu_qs+0x2f0/0x2f0
[ 611.827411] ? jbd2_journal_get_write_access+0x3d/0x80
[ 611.827411] ext4_xattr_block_set+0x80a/0x3a00
[ 611.827411] ? __getblk_gfp+0xb0/0x8b0
[ 611.827411] ? _cond_resched+0x12/0x60
[ 611.827411] ? __getblk_gfp+0xb0/0x8b0
[ 611.827411] ? ext4_xattr_ibody_set+0x280/0x280
[ 611.827411] ? __find_get_block+0xaf0/0xaf0
[ 611.827411] ? save_stack+0x89/0xb0
[ 611.827411] ? kmem_cache_alloc+0xa7/0x170
[ 611.827411] ? jbd2__journal_start+0x192/0x860
[ 611.827411] ? __ext4_journal_start_sb+0x103/0x330
[ 611.827411] ? ext4_xattr_set+0x187/0x330
[ 611.827411] ? __vfs_setxattr+0x7f/0xb0
[ 611.827411] ? __vfs_setxattr_noperm+0xe1/0x370
[ 611.827411] ? vfs_setxattr+0xbd/0xd0
[ 611.827411] ? path_setxattr+0x156/0x1a0
[ 611.827411] ? __x64_sys_setxattr+0xbb/0x150
[ 611.827411] ? do_syscall_64+0x12b/0x440
[ 611.827411] ? entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 611.827411] ? __ext4_get_inode_loc+0x368/0xe20
[ 611.827411] ? ext4_sb_bread+0xa9/0x2b0
[ 611.827411] ? xattr_find_entry+0x11b/0x1e0
[ 611.827411] ? ext4_xattr_block_find.isra.22+0x2fc/0x670
[ 611.827411] ext4_xattr_set_handle+0xe5f/0x18a0
[ 611.827411] ? ext4_xattr_ibody_inline_set+0x280/0x280
[ 611.827411] ? kmem_cache_alloc+0xa7/0x170
[ 611.827411] ? jbd2__journal_start+0x350/0x860
[ 611.827411] ? start_this_handle+0x12c0/0x12c0
[ 611.827411] ? ext4_journal_abort_handle.isra.6+0x260/0x260
[ 611.827411] ? ext4_xattr_get_block+0x6e/0x2f0
[ 611.827411] ext4_xattr_set+0x1b9/0x330
[ 611.827411] ? ext4_xattr_set_credits+0x160/0x160
[ 611.827411] ? selinux_secmark_enabled.part.15+0xd0/0xd0
[ 611.827411] __vfs_setxattr+0x7f/0xb0
[ 611.827411] ? down_write+0x5f/0x100
[ 611.827411] __vfs_setxattr_noperm+0xe1/0x370
[ 611.827411] vfs_setxattr+0xbd/0xd0
[ 611.827411] setxattr+0x253/0x320
[ 611.827411] ? vfs_setxattr+0xd0/0xd0
[ 611.827411] ? kmem_cache_free+0x70/0x1a0
[ 611.827411] ? filename_lookup+0x2ce/0x5b0
[ 611.827411] ? filename_parentat+0x770/0x770
[ 611.827411] ? d_move+0xf0/0xf0
[ 611.827411] ? mpi_resize+0x1d0/0x1d0
[ 611.827411] ? __kasan_kmalloc.constprop.4+0xa0/0xd0
[ 611.827411] ? may_umount_tree+0x270/0x270
[ 611.827411] path_setxattr+0x156/0x1a0
[ 611.827411] ? setxattr+0x320/0x320
[ 611.827411] ? do_sys_truncate+0xef/0x110
[ 611.827411] ? vfs_truncate+0x700/0x700
[ 611.827411] __x64_sys_setxattr+0xbb/0x150
[ 611.827411] ? __x64_sys_removexattr+0x50/0x70
[ 611.827411] do_syscall_64+0x12b/0x440
[ 611.827411] ? syscall_return_slowpath+0x2e0/0x2e0
[ 611.827411] ? __do_page_fault+0x970/0x970
[ 611.827411] ? prepare_exit_to_usermode+0x210/0x210
[ 611.827411] ? perf_trace_sys_enter+0x1050/0x1050
[ 611.827411] ? __x64_sys_sigaltstack+0x270/0x270
[ 611.827411] ? __put_user_4+0x1c/0x30
[ 611.827411] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 611.827411] RIP: 0033:0x44b7e9
[ 611.827411] Code: 00 b8 00 01 00 00 eb e1 e8 e4 19 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 c0 ff ff ff f7 d8 64 89 01 48
[ 611.827411] RSP: 002b:00007fff96b862e8 EFLAGS: 00000286 ORIG_RAX: 00000000000000bc
[ 611.827411] RAX: ffffffffffffffda RBX: 0000000000400400 RCX: 000000000044b7e9
[ 611.827411] RDX: 00007fff96b866b0 RSI: 00007fff96b86438 RDI: 00007fff96b863e5
[ 611.827411] RBP: 00007fff96b8aae0 R08: 0000000000000002 R09: 00007fff96b8ac08
[ 611.827411] R10: 000000000000003f R11: 0000000000000286 R12: 0000000000403160
[ 611.827411] R13: 0000000000000000 R14: 00000000006ba018 R15: 0000000000000000
[ 611.827411]
[ 611.827411] The buggy address belongs to the page:
[ 611.827411] page:ffffea0001a6fb00 count:2 mapcount:0 mapping:ffff88806a8c45f8 index:0x810
[ 611.827411] 0xffffffff844b0f40
[ 611.827411] flags: 0x100000000002032(referenced|lru|active|private)
[ 611.827411] raw: 0100000000002032 ffffea00018cc108 ffffea00018c8148 ffff88806a8c45f8
[ 611.827411] raw: 0000000000000810 ffff88806622cb28 00000002ffffffff 0000000000000000
[ 611.827411] page dumped because: kasan: bad access detected
[ 611.827411]
[ 611.827411] Memory state around the buggy address:
[ 611.827411] ffff888069becf00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 611.827411] ffff888069becf80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 611.827411] >ffff888069bed000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 611.827411] ^
[ 611.827411] ffff888069bed080: fb fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc
[ 611.827411] ffff888069bed100: fc fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 611.827411] ==================================================================
[ 611.827411] Disabling lock debugging due to kernel taint
[ 611.872754] BUG: unable to handle kernel paging request at ffff888069c62000
[ 611.872754] #PF error: [PROT] [WRITE]
[ 611.872754] PGD 6401067 P4D 6401067 PUD 6404067 PMD 6978f063 PTE 8000000069c62161
[ 611.872754] Oops: 0003 [#1] SMP KASAN NOPTI
[ 611.872754] CPU: 1 PID: 1971 Comm: poc Tainted: G B 5.0.21 #1
[ 611.872754] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014
[ 611.872754] RIP: 0010:memset_orig+0x46/0xb0
[ 611.872754] Code: 75 70 48 89 d1 48 c1 e9 06 74 39 66 0f 1f 84 00 00 00 00 00 48 ff c9 48 89 07 48 89 47 08 48 89 47 10 48 89 47 18 48 89 47 20 <48> 89 47 28 48 89 47 30 48 89 47 38 48 8d 7f 40 75 d8 0f 1f 84 00
[ 611.872754] RSP: 0018:ffff88806c78f0a0 EFLAGS: 00000216
[ 611.872754] RAX: 0000000000000000 RBX: ffff888069becbd8 RCX: 000000000003e2af
[ 611.872754] RDX: 0000000001000004 RSI: 0000000000000000 RDI: ffff888069c61fd8
[ 611.872754] RBP: ffff88806c78f6b8 R08: ffffed100da2609b R09: 0000000000000000
[ 611.872754] R10: ffff888069becbd8 R11: ffffed100da2609a R12: 00000000000003d8
[ 611.872754] R13: dffffc0000000000 R14: ffff88806c78f800 R15: ffff888069bec820
[ 611.872754] FS: 00000000006be880(0000) GS:ffff88806d100000(0000) knlGS:0000000000000000
[ 611.872754] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 611.872754] CR2: ffff888069c62000 CR3: 00000000677b0000 CR4: 00000000000006e0
[ 611.872754] Call Trace:
[ 611.872754] ext4_xattr_set_entry+0x1b67/0x3550
[ 611.872754] ? rcu_is_watching+0x7d/0x130
[ 611.872754] ? entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 611.872754] ? rcu_barrier_trace+0x260/0x260
[ 611.872754] ? add_transaction_credits+0x1c7/0xd50
[ 611.872754] ? ext4_xattr_inode_get+0x8e0/0x8e0
[ 611.872754] ? __kernel_text_address+0x9/0x30
[ 611.872754] ? _raw_spin_lock+0x99/0x130
[ 611.872754] ? __kasan_slab_free+0x143/0x180
[ 611.872754] ? kmem_cache_free+0x70/0x1a0
[ 611.872754] ? mb_cache_entry_delete+0x4f3/0x820
[ 611.872754] ? __mb_cache_entry_free+0x10/0x10
[ 611.872754] ? __find_get_block+0x1a3/0xaf0
[ 611.872754] ? __find_get_block+0x1a3/0xaf0
[ 611.872754] ? __find_get_block+0x1a3/0xaf0
[ 611.872754] ? __jbd2_journal_temp_unlink_buffer+0x530/0x530
[ 611.872754] ? try_to_free_buffers+0x4d0/0x4d0
[ 611.872754] ? rcu_qs+0x2f0/0x2f0
[ 611.872754] ? jbd2_journal_get_write_access+0x3d/0x80
[ 611.872754] ext4_xattr_block_set+0x80a/0x3a00
[ 611.872754] ? __getblk_gfp+0xb0/0x8b0
[ 611.872754] ? _cond_resched+0x12/0x60
[ 611.872754] ? __getblk_gfp+0xb0/0x8b0
[ 611.872754] ? ext4_xattr_ibody_set+0x280/0x280
[ 611.872754] ? __find_get_block+0xaf0/0xaf0
[ 611.872754] ? save_stack+0x89/0xb0
[ 611.872754] ? kmem_cache_alloc+0xa7/0x170
[ 611.872754] ? jbd2__journal_start+0x192/0x860
[ 611.872754] ? __ext4_journal_start_sb+0x103/0x330
[ 611.872754] ? ext4_xattr_set+0x187/0x330
[ 611.872754] ? __vfs_setxattr+0x7f/0xb0
[ 611.872754] ? __vfs_setxattr_noperm+0xe1/0x370
[ 611.872754] ? vfs_setxattr+0xbd/0xd0
[ 611.872754] ? path_setxattr+0x156/0x1a0
[ 611.872754] ? __x64_sys_setxattr+0xbb/0x150
[ 611.872754] ? do_syscall_64+0x12b/0x440
[ 611.872754] ? entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 611.872754] ? __ext4_get_inode_loc+0x368/0xe20
[ 611.872754] ? ext4_sb_bread+0xa9/0x2b0
[ 611.872754] ? xattr_find_entry+0x11b/0x1e0
[ 611.872754] ? ext4_xattr_block_find.isra.22+0x2fc/0x670
[ 611.872754] ext4_xattr_set_handle+0xe5f/0x18a0
[ 611.872754] ? ext4_xattr_ibody_inline_set+0x280/0x280
[ 611.872754] ? kmem_cache_alloc+0xa7/0x170
[ 611.872754] ? jbd2__journal_start+0x350/0x860
[ 611.872754] ? start_this_handle+0x12c0/0x12c0
[ 611.872754] ? ext4_journal_abort_handle.isra.6+0x260/0x260
[ 611.872754] ? ext4_xattr_get_block+0x6e/0x2f0
[ 611.872754] ext4_xattr_set+0x1b9/0x330
[ 611.872754] ? ext4_xattr_set_credits+0x160/0x160
[ 611.872754] ? selinux_secmark_enabled.part.15+0xd0/0xd0
[ 611.872754] __vfs_setxattr+0x7f/0xb0
[ 611.872754] ? down_write+0x5f/0x100
[ 611.872754] __vfs_setxattr_noperm+0xe1/0x370
[ 611.872754] vfs_setxattr+0xbd/0xd0
[ 611.872754] setxattr+0x253/0x320
[ 611.872754] ? vfs_setxattr+0xd0/0xd0
[ 611.872754] ? kmem_cache_free+0x70/0x1a0
[ 611.872754] ? filename_lookup+0x2ce/0x5b0
[ 611.872754] ? filename_parentat+0x770/0x770
[ 611.872754] ? d_move+0xf0/0xf0
[ 611.872754] ? mpi_resize+0x1d0/0x1d0
[ 611.872754] ? __kasan_kmalloc.constprop.4+0xa0/0xd0
[ 611.872754] ? may_umount_tree+0x270/0x270
[ 611.872754] path_setxattr+0x156/0x1a0
[ 611.872754] ? setxattr+0x320/0x320
[ 611.872754] ? do_sys_truncate+0xef/0x110
[ 611.872754] ? vfs_truncate+0x700/0x700
[ 611.872754] __x64_sys_setxattr+0xbb/0x150
[ 611.872754] ? __x64_sys_removexattr+0x50/0x70
[ 611.872754] do_syscall_64+0x12b/0x440
[ 611.872754] ? syscall_return_slowpath+0x2e0/0x2e0
[ 611.872754] ? __do_page_fault+0x970/0x970
[ 611.872754] ? prepare_exit_to_usermode+0x210/0x210
[ 611.872754] ? perf_trace_sys_enter+0x1050/0x1050
[ 611.872754] ? __x64_sys_sigaltstack+0x270/0x270
[ 611.872754] ? __put_user_4+0x1c/0x30
[ 611.872754] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 611.872754] RIP: 0033:0x44b7e9
[ 611.872754] Code: 00 b8 00 01 00 00 eb e1 e8 e4 19 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 c0 ff ff ff f7 d8 64 89 01 48
[ 611.872754] RSP: 002b:00007fff96b862e8 EFLAGS: 00000286 ORIG_RAX: 00000000000000bc
[ 611.872754] RAX: ffffffffffffffda RBX: 0000000000400400 RCX: 000000000044b7e9
[ 611.872754] RDX: 00007fff96b866b0 RSI: 00007fff96b86438 RDI: 00007fff96b863e5
[ 611.872754] RBP: 00007fff96b8aae0 R08: 0000000000000002 R09: 00007fff96b8ac08
[ 611.872754] R10: 000000000000003f R11: 0000000000000286 R12: 0000000000403160
[ 611.872754] R13: 0000000000000000 R14: 00000000006ba018 R15: 0000000000000000
[ 611.872754] Modules linked in:
[ 611.872754] CR2: ffff888069c62000
[ 611.872754] ---[ end trace 1f7f1665adedcbc6 ]---
[ 611.872754] RIP: 0010:memset_orig+0x46/0xb0
[ 611.872754] Code: 75 70 48 89 d1 48 c1 e9 06 74 39 66 0f 1f 84 00 00 00 00 00 48 ff c9 48 89 07 48 89 47 08 48 89 47 10 48 89 47 18 48 89 47 20 <48> 89 47 28 48 89 47 30 48 89 47 38 48 8d 7f 40 75 d8 0f 1f 84 00
[ 611.872754] RSP: 0018:ffff88806c78f0a0 EFLAGS: 00000216
[ 611.872754] RAX: 0000000000000000 RBX: ffff888069becbd8 RCX: 000000000003e2af
[ 611.872754] RDX: 0000000001000004 RSI: 0000000000000000 RDI: ffff888069c61fd8
[ 611.872754] RBP: ffff88806c78f6b8 R08: ffffed100da2609b R09: 0000000000000000
[ 611.872754] R10: ffff888069becbd8 R11: ffffed100da2609a R12: 00000000000003d8
[ 611.872754] R13: dffffc0000000000 R14: ffff88806c78f800 R15: ffff888069bec820
[ 611.872754] FS: 00000000006be880(0000) GS:ffff88806d100000(0000) knlGS:0000000000000000
[ 611.872754] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 611.872754] CR2: ffff888069c62000 CR3: 00000000677b0000 CR4: 00000000000006e0
[ 611.930088] BUG: Bad rss-counter state mm:000000003787fc2f idx:0 val:297
[ 611.931634] BUG: Bad rss-counter state mm:000000003787fc2f idx:1 val:15
[ 611.931774] BUG: non-zero pgtables_bytes on freeing mm: 24576
Segmentation fault
Conclusion
some operation after mount crafted ext4 image can handle local variable old_size
, it can occur slab-out-of-bounds vulnerability.
it can be lead to rip handling by attacker
Discoverer
Team bobfuzzer