[BUG] fs/ntfs3: closing query_streams can dirty the volume

From: shaos

Date: Mon Oct 19 2026 - 20:36:48 EST


Hello,

The :query_streams pseudo ADS has no backing $DATA attribute, but ntfs_file_release() treats it like a writable stream and calls attr_set_size_ex() on last close. That lookup fails, marks the inode bad, and sets the volume dirty. A later read-write mount then refuses the volume until it is repaired or mounted with force.

HEAD commit: fe2ec83746e501645709761605c2464a44fd2929
git tree: upstream Linux checkout, local branch master
source version: Linux 7.3.0-rc4-70-gfe2ec83746e50
compiler: gcc 11.4.0, GNU ld 2.38 (from the kernel build banner)

console output:
https://gist.githubusercontent.com/shaos26/696df55ba34ba3d0ea908a473c5628c0/raw/a388466cae0def97290365e4daaf573405381b73/console-output.txt
kernel config:
https://gist.githubusercontent.com/shaos26/696df55ba34ba3d0ea908a473c5628c0/raw/f1f2cc408fb1591991bf120e6c749ec011f3db35/kernel-config.txt
reproducer:
https://gist.githubusercontent.com/shaos26/696df55ba34ba3d0ea908a473c5628c0/raw/4ef0ad6f0d9b4a630b3b072332e53e7586c36c89/poc.c

Run in a disposable VM with a fresh read-write NTFS3 image. The pseudo-stream open and close are done as uid 1000; unmount and try a second read-write mount to observe the dirty-volume refusal:

dd if=/dev/zero of=/tmp/query-streams.img bs=1M count=64 status=none
mkntfs -F -q -L TEST -c 4096 -s 512 /tmp/query-streams.img
mkdir -p /mnt
mount -t ntfs3 -o loop,ads,rw,uid=1000,gid=1000 /tmp/query-streams.img /mnt
gcc -static -O2 -Wall -o stream_dirty_poc poc.c
setpriv --reuid=1000 --regid=1000 --clear-groups ./stream_dirty_poc /mnt pseudo
sync
umount /mnt
mount -t ntfs3 -o loop,ads,rw /tmp/query-streams.img /mnt

The UID 1000 run marked the NTFS volume dirty on close, made later access to the pseudo stream fail with EINVAL, and caused the next read-write mount to fail with the dirty-volume check. Fresh-image positives reproduced; read-only open, a real ADS, and ads=0 controls stayed clean.

Impact and prerequisites:
Any local user who can write a file on a read-write NTFS3 volume can persistently mark the whole volume dirty with one open/close sequence. This can deny subsequent read-write mounts and require repair. No memory corruption or privilege escalation is claimed.

Validation: Two fresh-image positives, including a uid 1000 run, marked the volume dirty on close. Read-only pseudo-stream, real-ADS, and ads=0 controls stayed clean.

Thanks,

shaos