Skip to content

Commit de5e095

Browse files
Elden-Ringgregkh
authored andcommitted
fs/ntfs3: Validate data run offset
[ Upstream commit 6db6208 ] This adds sanity checks for data run offset. We should make sure data run offset is legit before trying to unpack them, otherwise we may encounter use-after-free or some unexpected memory access behaviors. [ 82.940342] BUG: KASAN: use-after-free in run_unpack+0x2e3/0x570 [ 82.941180] Read of size 1 at addr ffff888008a8487f by task mount/240 [ 82.941670] [ 82.942069] CPU: 0 PID: 240 Comm: mount Not tainted 5.19.0+ #15 [ 82.942482] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014 [ 82.943720] Call Trace: [ 82.944204] <TASK> [ 82.944471] dump_stack_lvl+0x49/0x63 [ 82.944908] print_report.cold+0xf5/0x67b [ 82.945141] ? __wait_on_bit+0x106/0x120 [ 82.945750] ? run_unpack+0x2e3/0x570 [ 82.946626] kasan_report+0xa7/0x120 [ 82.947046] ? run_unpack+0x2e3/0x570 [ 82.947280] __asan_load1+0x51/0x60 [ 82.947483] run_unpack+0x2e3/0x570 [ 82.947709] ? memcpy+0x4e/0x70 [ 82.947927] ? run_pack+0x7a0/0x7a0 [ 82.948158] run_unpack_ex+0xad/0x3f0 [ 82.948399] ? mi_enum_attr+0x14a/0x200 [ 82.948717] ? run_unpack+0x570/0x570 [ 82.949072] ? ni_enum_attr_ex+0x1b2/0x1c0 [ 82.949332] ? ni_fname_type.part.0+0xd0/0xd0 [ 82.949611] ? mi_read+0x262/0x2c0 [ 82.949970] ? ntfs_cmp_names_cpu+0x125/0x180 [ 82.950249] ntfs_iget5+0x632/0x1870 [ 82.950621] ? ntfs_get_block_bmap+0x70/0x70 [ 82.951192] ? evict+0x223/0x280 [ 82.951525] ? iput.part.0+0x286/0x320 [ 82.951969] ntfs_fill_super+0x1321/0x1e20 [ 82.952436] ? put_ntfs+0x1d0/0x1d0 [ 82.952822] ? vsprintf+0x20/0x20 [ 82.953188] ? mutex_unlock+0x81/0xd0 [ 82.953379] ? set_blocksize+0x95/0x150 [ 82.954001] get_tree_bdev+0x232/0x370 [ 82.954438] ? put_ntfs+0x1d0/0x1d0 [ 82.954700] ntfs_fs_get_tree+0x15/0x20 [ 82.955049] vfs_get_tree+0x4c/0x130 [ 82.955292] path_mount+0x645/0xfd0 [ 82.955615] ? putname+0x80/0xa0 [ 82.955955] ? finish_automount+0x2e0/0x2e0 [ 82.956310] ? kmem_cache_free+0x110/0x390 [ 82.956723] ? putname+0x80/0xa0 [ 82.957023] do_mount+0xd6/0xf0 [ 82.957411] ? path_mount+0xfd0/0xfd0 [ 82.957638] ? __kasan_check_write+0x14/0x20 [ 82.957948] __x64_sys_mount+0xca/0x110 [ 82.958310] do_syscall_64+0x3b/0x90 [ 82.958719] entry_SYSCALL_64_after_hwframe+0x63/0xcd [ 82.959341] RIP: 0033:0x7fd0d1ce948a [ 82.960193] Code: 48 8b 0d 11 fa 2a 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 a5 00 00 008 [ 82.961532] RSP: 002b:00007ffe59ff69a8 EFLAGS: 00000202 ORIG_RAX: 00000000000000a5 [ 82.962527] RAX: ffffffffffffffda RBX: 0000564dcc107060 RCX: 00007fd0d1ce948a [ 82.963266] RDX: 0000564dcc107260 RSI: 0000564dcc1072e0 RDI: 0000564dcc10fce0 [ 82.963686] RBP: 0000000000000000 R08: 0000564dcc107280 R09: 0000000000000020 [ 82.964272] R10: 00000000c0ed0000 R11: 0000000000000202 R12: 0000564dcc10fce0 [ 82.964785] R13: 0000564dcc107260 R14: 0000000000000000 R15: 00000000ffffffff Signed-off-by: Edward Lo <[email protected]> Signed-off-by: Konstantin Komarov <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent d4489ba commit de5e095

File tree

5 files changed

+46
-0
lines changed

5 files changed

+46
-0
lines changed

fs/ntfs3/attrib.c

+13
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ int attr_load_runs(struct ATTRIB *attr, struct ntfs_inode *ni,
101101

102102
asize = le32_to_cpu(attr->size);
103103
run_off = le16_to_cpu(attr->nres.run_off);
104+
105+
if (run_off > asize)
106+
return -EINVAL;
107+
104108
err = run_unpack_ex(run, ni->mi.sbi, ni->mi.rno, svcn, evcn,
105109
vcn ? *vcn : svcn, Add2Ptr(attr, run_off),
106110
asize - run_off);
@@ -1157,6 +1161,10 @@ int attr_load_runs_vcn(struct ntfs_inode *ni, enum ATTR_TYPE type,
11571161
}
11581162

11591163
ro = le16_to_cpu(attr->nres.run_off);
1164+
1165+
if (ro > le32_to_cpu(attr->size))
1166+
return -EINVAL;
1167+
11601168
err = run_unpack_ex(run, ni->mi.sbi, ni->mi.rno, svcn, evcn, svcn,
11611169
Add2Ptr(attr, ro), le32_to_cpu(attr->size) - ro);
11621170
if (err < 0)
@@ -1832,6 +1840,11 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
18321840
u16 le_sz;
18331841
u16 roff = le16_to_cpu(attr->nres.run_off);
18341842

1843+
if (roff > le32_to_cpu(attr->size)) {
1844+
err = -EINVAL;
1845+
goto out;
1846+
}
1847+
18351848
run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn,
18361849
evcn1 - 1, svcn, Add2Ptr(attr, roff),
18371850
le32_to_cpu(attr->size) - roff);

fs/ntfs3/attrlist.c

+5
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ int ntfs_load_attr_list(struct ntfs_inode *ni, struct ATTRIB *attr)
6868

6969
run_init(&ni->attr_list.run);
7070

71+
if (run_off > le32_to_cpu(attr->size)) {
72+
err = -EINVAL;
73+
goto out;
74+
}
75+
7176
err = run_unpack_ex(&ni->attr_list.run, ni->mi.sbi, ni->mi.rno,
7277
0, le64_to_cpu(attr->nres.evcn), 0,
7378
Add2Ptr(attr, run_off),

fs/ntfs3/frecord.c

+14
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,12 @@ static int ni_repack(struct ntfs_inode *ni)
567567
}
568568

569569
roff = le16_to_cpu(attr->nres.run_off);
570+
571+
if (roff > le32_to_cpu(attr->size)) {
572+
err = -EINVAL;
573+
break;
574+
}
575+
570576
err = run_unpack(&run, sbi, ni->mi.rno, svcn, evcn, svcn,
571577
Add2Ptr(attr, roff),
572578
le32_to_cpu(attr->size) - roff);
@@ -1541,6 +1547,9 @@ int ni_delete_all(struct ntfs_inode *ni)
15411547
asize = le32_to_cpu(attr->size);
15421548
roff = le16_to_cpu(attr->nres.run_off);
15431549

1550+
if (roff > asize)
1551+
return -EINVAL;
1552+
15441553
/* run==1 means unpack and deallocate. */
15451554
run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn, evcn, svcn,
15461555
Add2Ptr(attr, roff), asize - roff);
@@ -2242,6 +2251,11 @@ int ni_decompress_file(struct ntfs_inode *ni)
22422251
asize = le32_to_cpu(attr->size);
22432252
roff = le16_to_cpu(attr->nres.run_off);
22442253

2254+
if (roff > asize) {
2255+
err = -EINVAL;
2256+
goto out;
2257+
}
2258+
22452259
/*run==1 Means unpack and deallocate. */
22462260
run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn, evcn, svcn,
22472261
Add2Ptr(attr, roff), asize - roff);

fs/ntfs3/fslog.c

+9
Original file line numberDiff line numberDiff line change
@@ -2727,6 +2727,9 @@ static inline bool check_attr(const struct MFT_REC *rec,
27272727
return false;
27282728
}
27292729

2730+
if (run_off > asize)
2731+
return false;
2732+
27302733
if (run_unpack(NULL, sbi, 0, svcn, evcn, svcn,
27312734
Add2Ptr(attr, run_off), asize - run_off) < 0) {
27322735
return false;
@@ -4769,6 +4772,12 @@ int log_replay(struct ntfs_inode *ni, bool *initialized)
47694772
u16 roff = le16_to_cpu(attr->nres.run_off);
47704773
CLST svcn = le64_to_cpu(attr->nres.svcn);
47714774

4775+
if (roff > t32) {
4776+
kfree(oa->attr);
4777+
oa->attr = NULL;
4778+
goto fake_attr;
4779+
}
4780+
47724781
err = run_unpack(&oa->run0, sbi, inode->i_ino, svcn,
47734782
le64_to_cpu(attr->nres.evcn), svcn,
47744783
Add2Ptr(attr, roff), t32 - roff);

fs/ntfs3/inode.c

+5
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,11 @@ static struct inode *ntfs_read_mft(struct inode *inode,
364364
attr_unpack_run:
365365
roff = le16_to_cpu(attr->nres.run_off);
366366

367+
if (roff > asize) {
368+
err = -EINVAL;
369+
goto out;
370+
}
371+
367372
t64 = le64_to_cpu(attr->nres.svcn);
368373
err = run_unpack_ex(run, sbi, ino, t64, le64_to_cpu(attr->nres.evcn),
369374
t64, Add2Ptr(attr, roff), asize - roff);

0 commit comments

Comments
 (0)