Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fs: ntfs3: fix infinite loop in attr_load_runs_range on inconsistent metadata

We found an infinite loop bug in the ntfs3 file system that can lead to a
Denial-of-Service (DoS) condition.

A malformed NTFS image can cause an infinite loop when an attribute header
indicates an empty run list, while directory entries reference it as
containing actual data. In NTFS, setting evcn=-1 with svcn=0 is a valid way
to represent an empty run list, and run_unpack() correctly handles this by
checking if evcn + 1 equals svcn and returning early without parsing any run
data. However, this creates a problem when there is metadata inconsistency,
where the attribute header claims to be empty (evcn=-1) but the caller
expects to read actual data. When run_unpack() immediately returns success
upon seeing this condition, it leaves the runs_tree uninitialized with
run->runs as a NULL. The calling function attr_load_runs_range() assumes
that a successful return means that the runs were loaded and sets clen to 0,
expecting the next run_lookup_entry() call to succeed. Because runs_tree
remains uninitialized, run_lookup_entry() continues to fail, and the loop
increments vcn by zero (vcn += 0), leading to an infinite loop.

This patch adds a retry counter to detect when run_lookup_entry() fails
consecutively after attr_load_runs_vcn(). If the run is still not found on
the second attempt, it indicates corrupted metadata and returns -EINVAL,
preventing the Denial-of-Service (DoS) vulnerability.

Co-developed-by: Seunghun Han <kkamagui@gmail.com>
Signed-off-by: Seunghun Han <kkamagui@gmail.com>
Co-developed-by: Jihoon Kwon <kjh010315@gmail.com>
Signed-off-by: Jihoon Kwon <kjh010315@gmail.com>
Signed-off-by: Jaehun Gou <p22gone@gmail.com>
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>

authored by

Jaehun Gou and committed by
Konstantin Komarov
4b90f16e fac760f5

+12 -3
+12 -3
fs/ntfs3/attrib.c
··· 1354 1354 CLST vcn; 1355 1355 CLST vcn_last = (to - 1) >> cluster_bits; 1356 1356 CLST lcn, clen; 1357 - int err; 1357 + int err = 0; 1358 + int retry = 0; 1358 1359 1359 1360 for (vcn = from >> cluster_bits; vcn <= vcn_last; vcn += clen) { 1360 1361 if (!run_lookup_entry(run, vcn, &lcn, &clen, NULL)) { 1362 + if (retry != 0) { /* Next run_lookup_entry(vcn) also failed. */ 1363 + err = -EINVAL; 1364 + break; 1365 + } 1361 1366 err = attr_load_runs_vcn(ni, type, name, name_len, run, 1362 1367 vcn); 1363 1368 if (err) 1364 - return err; 1369 + break; 1370 + 1365 1371 clen = 0; /* Next run_lookup_entry(vcn) must be success. */ 1372 + retry++; 1366 1373 } 1374 + else 1375 + retry = 0; 1367 1376 } 1368 1377 1369 - return 0; 1378 + return err; 1370 1379 } 1371 1380 1372 1381 #ifdef CONFIG_NTFS3_LZX_XPRESS