Bug 214785

Summary: ubifs: Read out-of-bounds in ubifs_jnl_write_inode()
Product: File System Reporter: Zhihao Cheng (chengzhihao1)
Component: OtherAssignee: fs_other
Status: NEW ---    
Severity: normal    
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 5.15-rc5 Subsystem:
Regression: No Bisected commit-id:
Attachments: print.patch
write_symlink.sh

Description Zhihao Cheng 2021-10-21 02:25:54 UTC
[  306.068429] ==================================================================
[  306.070451] BUG: KASAN: slab-out-of-bounds in ecc_sw_hamming_calculate+0x1dc/0x7d0
[  306.072514] Read of size 4 at addr ffff888105594ff8 by task kworker/u8:4/128
[  306.074424] 
[  306.074865] CPU: 1 PID: 128 Comm: kworker/u8:4 Not tainted 5.15.0-rc5-00262-g31ff383cb277-dirty #141
[  306.077308] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20190727_073836-buildvm-ppc64le-16.ppc.fedoraproject.org-3.fc31 04/01/2014
[  306.080848] Workqueue: writeback wb_workfn (flush-ubifs_0_0)
[  306.082143] Call Trace:
[  306.082492]  ? dump_stack_lvl+0x73/0x9f
[  306.083028]  ? print_address_description.constprop.0+0x2f/0x250
[  306.083840]  ? ecc_sw_hamming_calculate+0x1dc/0x7d0
[  306.084508]  ? ecc_sw_hamming_calculate+0x1dc/0x7d0
[  306.085179]  ? kasan_report.cold+0x81/0x165
[  306.085768]  ? nand_lp_exec_read_page_op+0x3f0/0x4d0
[  306.086458]  ? ecc_sw_hamming_calculate+0x1dc/0x7d0
[  306.087129]  ? __asan_load4+0x77/0x120
[  306.087647]  ? ecc_sw_hamming_calculate+0x1dc/0x7d0
[  306.088317]  ? nand_ecc_sw_hamming_calculate+0x6c/0x80
[  306.089022]  ? rawnand_sw_hamming_calculate+0x12/0x20
[  306.089721]  ? nand_write_page_swecc+0xa9/0x160
[  306.090347]  ? nand_do_write_ops+0x3d5/0x880
[  306.090942]  ? ubifs_jnl_write_inode+0x627/0x960 [ubifs]
[  306.091761]  ? nand_write_oob+0x78/0x100
[  306.092303]  ? mtd_write_oob_std+0xe2/0x160
[  306.092884]  ? mtd_write_oob+0xec/0x1b0
[  306.093424]  ? mtd_write+0x92/0xf0
[  306.093899]  ? mtd_write_oob+0x1b0/0x1b0
[  306.094440]  ? ubi_self_check_all_ff+0x82/0x2e0 [ubi]
[  306.095194]  ? __list_add_valid+0x2b/0x130
[  306.095759]  ? _raw_spin_unlock_irqrestore+0x22/0x50
[  306.096441]  ? ubi_io_write+0x2c2/0xa90 [ubi]
[  306.097081]  ? _raw_read_lock_irq+0x90/0x90
[  306.097662]  ? kmem_cache_alloc_trace+0x3c2/0x7a0
[  306.098307]  ? do_sync_erase+0x350/0x350 [ubi]
[  306.098978]  ? __kasan_check_write+0x20/0x30
[  306.099562]  ? down_write+0xf2/0x190
[  306.100058]  ? down_write_killable+0x1b0/0x1b0
[  306.100663]  ? check_mapping+0x2c/0x590 [ubi]
[  306.101302]  ? prb_read_valid+0x6e/0xa0
[  306.101841]  ? ubi_eba_write_leb+0x58a/0xfd0 [ubi]
[  306.102540]  ? console_unlock+0x4bb/0x960
[  306.103090]  ? test_bit.constprop.0+0x50/0x50
[  306.103684]  ? process_one_work+0x47f/0xa20
[  306.104256]  ? ubi_eba_read_leb_sg+0x1f0/0x1f0 [ubi]
[  306.104980]  ? hrtimer_active+0x9b/0x100
[  306.105528]  ? ubi_leb_write+0x22c/0x2f0 [ubi]
[  306.106182]  ? map_id_up+0x108/0x1b0
[  306.106676]  ? ubifs_leb_write+0xf2/0x1b0 [ubifs]
[  306.107393]  ? ubifs_wbuf_write_nolock+0x421/0x12c0 [ubifs]
[  306.108225]  ? write_head+0xdc/0x1c0 [ubifs]
[  306.108886]  ? ubifs_jnl_write_inode+0x627/0x960 [ubifs]
[  306.109714]  ? update_group_capacity+0x4f0/0x4f0
[  306.110350]  ? ret_from_fork+0x1e/0x30
[  306.110871]  ? ubifs_jnl_write_data+0x660/0x660 [ubifs]
[  306.111654]  ? orc_find+0xe3/0x320
[  306.112124]  ? generic_writepages+0x99/0x140
[  306.112708]  ? write_cache_pages+0x9a0/0x9a0
[  306.113294]  ? __kasan_check_write+0x20/0x30
[  306.113887]  ? mutex_lock+0xa6/0x110
[  306.114380]  ? __mutex_lock_slowpath+0x30/0x30
[  306.114989]  ? ubifs_write_inode+0x1c0/0x290 [ubifs]
[  306.115738]  ? do_writepages+0x15b/0x370
[  306.116282]  ? __writeback_single_inode+0x5d6/0x790
[  306.116950]  ? writeback_sb_inodes+0x3a9/0x990
[  306.117567]  ? write_inode_now+0x1f0/0x1f0
[  306.118140]  ? __writeback_inodes_wb+0xc8/0x170
[  306.118765]  ? wb_writeback+0x645/0x710
[  306.119298]  ? __writeback_inodes_wb+0x170/0x170
[  306.119925]  ? cpumask_next+0x3f/0x60
[  306.120430]  ? get_nr_dirty_inodes+0x93/0xd0
[  306.121018]  ? wb_workfn+0x8af/0xb80
[  306.121520]  ? update_cfs_group+0x1e/0x1b0
[  306.122080]  ? inode_wait_for_writeback+0x60/0x60
[  306.122715]  ? schedule+0xb5/0x240
[  306.123182]  ? finish_task_switch+0x1a4/0x660
[  306.123772]  ? __kasan_check_write+0x20/0x30
[  306.124353]  ? __kasan_check_read+0x1d/0x30
[  306.124920]  ? read_word_at_a_time+0x16/0x30
[  306.125502]  ? strscpy+0xdb/0x220
[  306.125957]  ? process_one_work+0x47f/0xa20
[  306.126526]  ? worker_thread+0x352/0x910
[  306.127058]  ? rescuer_thread+0x800/0x800
[  306.127602]  ? kthread+0x247/0x2a0
[  306.128069]  ? set_kthread_struct+0xa0/0xa0
[  306.128636]  ? ret_from_fork+0x1f/0x30
[  306.129153] 
[  306.129374] Allocated by task 128:
[  306.129869]  kasan_save_stack+0x23/0x60
[  306.130396]  set_alloc_info+0x46/0x70
[  306.130901]  __kasan_kmalloc+0x8d/0xd0
[  306.131412]  __kmalloc+0x3dc/0x7f0
[  306.131879]  ubifs_jnl_write_inode+0x150/0x960 [ubifs]
[  306.132640]  ubifs_write_inode+0x1c0/0x290 [ubifs]
[  306.133373]  __writeback_single_inode+0x5d6/0x790
[  306.134043]  writeback_sb_inodes+0x3a9/0x990
[  306.134607]  __writeback_inodes_wb+0xc8/0x170
[  306.135184]  wb_writeback+0x645/0x710
[  306.135683]  wb_workfn+0x8af/0xb80
[  306.136150]  process_one_work+0x47f/0xa20
[  306.136694]  worker_thread+0x352/0x910
[  306.137207]  kthread+0x247/0x2a0
[  306.137662]  ret_from_fork+0x1f/0x30
[  306.138152] 
[  306.138365] The buggy address belongs to the object at ffff888105594000
[  306.138365]  which belongs to the cache kmalloc-4k of size 4096
[  306.140017] The buggy address is located 4088 bytes inside of
[  306.140017]  4096-byte region [ffff888105594000, ffff888105595000)
[  306.141602] The buggy address belongs to the page:
[  306.142247] page:0000000067f4e566 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x105590
[  306.143500] head:0000000067f4e566 order:3 compound_mapcount:0 compound_pincount:0
[  306.144499] flags: 0x2fffff80010200(slab|head|node=0|zone=2|lastcpupid=0x1fffff)
[  306.145487] raw: 002fffff80010200 dead000000000100 dead000000000122 ffff888100043040
[  306.146518] raw: 0000000000000000 0000000080040004 00000001ffffffff 0000000000000000
[  306.147544] page dumped because: kasan: bad access detected
[  306.148285] 
[  306.148497] Memory state around the buggy address:
[  306.149140]  ffff888105594e80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[  306.150112]  ffff888105594f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[  306.151074] >ffff888105594f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
[  306.152032]                                                                 ^
[  306.152977]  ffff888105595000: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  306.153947]  ffff888105595080: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  306.154922] ==================================================================
Comment 1 Zhihao Cheng 2021-10-21 02:48:17 UTC
Function ubifs_wbuf_write_nolock() may access buf out of bounds in following process:
ubifs_wbuf_write_nolock
  aligned_len = ALIGN(len, 8);   // Assume len = 4089, aligned_len = 4096
  if (aligned_len <= wbuf->avail) ... // Not satisfy
  if (wbuf->used) {
    ubifs_leb_write()  // Fill some data in avail wbuf
    len -= wbuf->avail;   // len is still not 8-bytes aligned
    aligned_len -= wbuf->avail;
  }
  n = aligned_len >> c->max_write_shift;
  if (n) {
    n <<= c->max_write_shift;
    err = ubifs_leb_write(c, wbuf->lnum, buf + written,
                          wbuf->offs, n); // n > len, read out of bounds less than (n-len)8 bytes
  }
Comment 2 Zhihao Cheng 2021-10-21 02:52:18 UTC
Reproducer:
1. apply print.patch, and compile kernel (UBIFS/UBI/NANDSIM = m, CONFIG_UBIFS_ATIME_SUPPORT=y)
2. Run write_symlink.sh (Wait 1min~ to see read oob)
Comment 3 Zhihao Cheng 2021-10-21 02:52:43 UTC
Created attachment 299291 [details]
print.patch
Comment 4 Zhihao Cheng 2021-10-21 02:52:56 UTC
Created attachment 299293 [details]
write_symlink.sh