Skip to content

Commit 6db6208

Browse files
Elden-Ringaalexandrovich
authored andcommitted
fs/ntfs3: Validate data run offset
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]>
1 parent e19c627 commit 6db6208

File tree

5 files changed

+46
-0
lines changed

5 files changed

+46
-0
lines changed

fs/ntfs3/attrib.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ static 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);
@@ -1232,6 +1236,10 @@ int attr_load_runs_vcn(struct ntfs_inode *ni, enum ATTR_TYPE type,
12321236
}
12331237

12341238
ro = le16_to_cpu(attr->nres.run_off);
1239+
1240+
if (ro > le32_to_cpu(attr->size))
1241+
return -EINVAL;
1242+
12351243
err = run_unpack_ex(run, ni->mi.sbi, ni->mi.rno, svcn, evcn, svcn,
12361244
Add2Ptr(attr, ro), le32_to_cpu(attr->size) - ro);
12371245
if (err < 0)
@@ -1901,6 +1909,11 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
19011909
u16 le_sz;
19021910
u16 roff = le16_to_cpu(attr->nres.run_off);
19031911

1912+
if (roff > le32_to_cpu(attr->size)) {
1913+
err = -EINVAL;
1914+
goto out;
1915+
}
1916+
19041917
run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn,
19051918
evcn1 - 1, svcn, Add2Ptr(attr, roff),
19061919
le32_to_cpu(attr->size) - roff);

fs/ntfs3/attrlist.c

Lines changed: 5 additions & 0 deletions
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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,12 @@ static int ni_repack(struct ntfs_inode *ni)
568568
}
569569

570570
roff = le16_to_cpu(attr->nres.run_off);
571+
572+
if (roff > le32_to_cpu(attr->size)) {
573+
err = -EINVAL;
574+
break;
575+
}
576+
571577
err = run_unpack(&run, sbi, ni->mi.rno, svcn, evcn, svcn,
572578
Add2Ptr(attr, roff),
573579
le32_to_cpu(attr->size) - roff);
@@ -1589,6 +1595,9 @@ int ni_delete_all(struct ntfs_inode *ni)
15891595
asize = le32_to_cpu(attr->size);
15901596
roff = le16_to_cpu(attr->nres.run_off);
15911597

1598+
if (roff > asize)
1599+
return -EINVAL;
1600+
15921601
/* run==1 means unpack and deallocate. */
15931602
run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn, evcn, svcn,
15941603
Add2Ptr(attr, roff), asize - roff);
@@ -2291,6 +2300,11 @@ int ni_decompress_file(struct ntfs_inode *ni)
22912300
asize = le32_to_cpu(attr->size);
22922301
roff = le16_to_cpu(attr->nres.run_off);
22932302

2303+
if (roff > asize) {
2304+
err = -EINVAL;
2305+
goto out;
2306+
}
2307+
22942308
/*run==1 Means unpack and deallocate. */
22952309
run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn, evcn, svcn,
22962310
Add2Ptr(attr, roff), asize - roff);

fs/ntfs3/fslog.c

Lines changed: 9 additions & 0 deletions
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

Lines changed: 5 additions & 0 deletions
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)