* [PATCH] ntfs: prevent write access to $MFT inode
@ 2026-07-02 6:35 Hongling Zeng
2026-08-13 21:04 ` kernel test robot
0 siblings, 1 reply; 2+ messages in thread
From: Hongling Zeng @ 2026-07-02 6:35 UTC (permalink / raw)
To: linkinjeon, hyc.lee, charsyam
Cc: linux-fsdevel, linux-kernel, zhongling0719, Hongling Zeng, stable
Malicious NTFS images can expose $MFT to userspace and allow write
operations, leading to potential kernel NULL pointer dereference
since ntfs_mft_aops lacks write_begin support.
The vulnerability affects both write_iter and mmap-based write paths:
1. write_iter path: ntfs_file_write_iter()
2. mmap write path: ntfs_filemap_page_mkwrite()
Without protecting both paths, attackers can bypass single-path
protection by using the alternative write method.
Fix by adding write protection in ntfs_file_write_iter() to prevent
any write operations to FILE_MFT.
Fixes: 1e9ea7e04472d ("Revert \"fs: Remove NTFS classic\"")
Cc: stable@vger.kernel.org
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
---
fs/ntfs/file.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index 6a7b638e523d..0d8f11e5ccb7 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -550,6 +550,12 @@ static ssize_t ntfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
if (NVolShutdown(vol))
return -EIO;
+ if (ni->mft_no == FILE_MFT) {
+ ntfs_error(vi->i_sb, "Attempt to write to $MFT denied (mft_no: 0x%lx)",
+ ni->mft_no);
+ return -EACCES;
+ }
+
if (NInoEncrypted(ni)) {
ntfs_error(vi->i_sb, "Writing for %s files is not supported yet",
NInoCompressed(ni) ? "Compressed" : "Encrypted");
@@ -618,8 +624,15 @@ static ssize_t ntfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
static vm_fault_t ntfs_filemap_page_mkwrite(struct vm_fault *vmf)
{
struct inode *inode = file_inode(vmf->vma->vm_file);
+ struct ntfs_inode *ni = NTFS_I(inode);
vm_fault_t ret;
+ if (ni->mft_no == FILE_MFT) {
+ ntfs_error(inode->i_sb, "Attempt to write to $MFT via mmap denied (mft_no: 0x%lx)",
+ ni->mft_no);
+ return VM_FAULT_SIGBUS;
+ }
+
sb_start_pagefault(inode->i_sb);
file_update_time(vmf->vma->vm_file);
--
2.25.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] ntfs: prevent write access to $MFT inode
2026-07-02 6:35 [PATCH] ntfs: prevent write access to $MFT inode Hongling Zeng
@ 2026-08-13 21:04 ` kernel test robot
0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2026-08-13 21:04 UTC (permalink / raw)
To: Hongling Zeng, linkinjeon, hyc.lee, charsyam
Cc: oe-kbuild-all, linux-fsdevel, linux-kernel, zhongling0719,
Hongling Zeng, stable
Hi Hongling,
kernel test robot noticed the following build warnings:
[auto build test WARNING on brauner-vfs/vfs.all]
[also build test WARNING on linus/master v7.2-rc7 next-20260812]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Hongling-Zeng/ntfs-prevent-write-access-to-MFT-inode/20260814-004837
base: https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git vfs.all
patch link: https://lore.kernel.org/r/20260702063529.45448-1-zenghongling%40kylinos.cn
patch subject: [PATCH] ntfs: prevent write access to $MFT inode
config: powerpc-allmodconfig (https://download.01.org/0day-ci/archive/20260814/202608140556.ICYSq5Cy-lkp@intel.com/config)
compiler: powerpc64-linux-gcc (GCC) 16.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260814/202608140556.ICYSq5Cy-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202608140556.ICYSq5Cy-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from fs/ntfs/inode.h:13,
from fs/ntfs/ntfs.h:26,
from fs/ntfs/attrib.h:13,
from fs/ntfs/lcnalloc.h:13,
from fs/ntfs/file.c:19:
fs/ntfs/file.c: In function 'ntfs_file_write_iter':
>> fs/ntfs/file.c:554:38: warning: format '%lx' expects argument of type 'long unsigned int', but argument 4 has type 'u64' {aka 'long long unsigned int'} [-Wformat=]
554 | ntfs_error(vi->i_sb, "Attempt to write to $MFT denied (mft_no: 0x%lx)",
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
555 | ni->mft_no);
| ~~~~~~~~~~
| |
| u64 {aka long long unsigned int}
fs/ntfs/debug.h:59:68: note: in definition of macro 'ntfs_error'
59 | #define ntfs_error(sb, f, a...) __ntfs_error(__func__, sb, f, ##a)
| ^
fs/ntfs/file.c:554:84: note: format string is defined here
554 | ntfs_error(vi->i_sb, "Attempt to write to $MFT denied (mft_no: 0x%lx)",
| ~~^
| |
| long unsigned int
| %llx
fs/ntfs/file.c: In function 'ntfs_filemap_page_mkwrite':
fs/ntfs/file.c:631:41: warning: format '%lx' expects argument of type 'long unsigned int', but argument 4 has type 'u64' {aka 'long long unsigned int'} [-Wformat=]
631 | ntfs_error(inode->i_sb, "Attempt to write to $MFT via mmap denied (mft_no: 0x%lx)",
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
632 | ni->mft_no);
| ~~~~~~~~~~
| |
| u64 {aka long long unsigned int}
fs/ntfs/debug.h:59:68: note: in definition of macro 'ntfs_error'
59 | #define ntfs_error(sb, f, a...) __ntfs_error(__func__, sb, f, ##a)
| ^
fs/ntfs/file.c:631:96: note: format string is defined here
631 | ntfs_error(inode->i_sb, "Attempt to write to $MFT via mmap denied (mft_no: 0x%lx)",
| ~~^
| |
| long unsigned int
| %llx
vim +554 fs/ntfs/file.c
537
538 static ssize_t ntfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
539 {
540 struct file *file = iocb->ki_filp;
541 struct inode *vi = file->f_mapping->host;
542 struct ntfs_inode *ni = NTFS_I(vi);
543 struct ntfs_volume *vol = ni->vol;
544 ssize_t ret;
545 ssize_t count;
546 loff_t pos;
547 int err;
548 loff_t old_data_size, old_init_size;
549
550 if (NVolShutdown(vol))
551 return -EIO;
552
553 if (ni->mft_no == FILE_MFT) {
> 554 ntfs_error(vi->i_sb, "Attempt to write to $MFT denied (mft_no: 0x%lx)",
555 ni->mft_no);
556 return -EACCES;
557 }
558
559 if (NInoEncrypted(ni)) {
560 ntfs_error(vi->i_sb, "Writing for %s files is not supported yet",
561 NInoCompressed(ni) ? "Compressed" : "Encrypted");
562 return -EOPNOTSUPP;
563 }
564
565 if (NInoCompressed(ni) && iocb->ki_flags & IOCB_DIRECT)
566 return -EOPNOTSUPP;
567
568 if (iocb->ki_flags & IOCB_NOWAIT) {
569 if (!inode_trylock(vi))
570 return -EAGAIN;
571 } else
572 inode_lock(vi);
573
574 ret = generic_write_checks(iocb, from);
575 if (ret <= 0)
576 goto out_lock;
577
578 err = file_modified(iocb->ki_filp);
579 if (err) {
580 ret = err;
581 goto out_lock;
582 }
583
584 if (!(vol->vol_flags & VOLUME_IS_DIRTY))
585 ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY);
586
587 pos = iocb->ki_pos;
588 count = ret;
589
590 old_data_size = ni->data_size;
591 old_init_size = ni->initialized_size;
592
593 if (NInoNonResident(ni) && NInoCompressed(ni)) {
594 ret = ntfs_compress_write(ni, pos, count, from);
595 if (ret > 0)
596 iocb->ki_pos += ret;
597 goto out;
598 }
599
600 if (NInoNonResident(ni) && iocb->ki_flags & IOCB_DIRECT)
601 ret = ntfs_dio_write_iter(iocb, from);
602 else
603 ret = iomap_file_buffered_write(iocb, from, &ntfs_write_iomap_ops,
604 &ntfs_iomap_folio_ops, NULL);
605 out:
606 if (ret < 0 && ret != -EIOCBQUEUED) {
607 if (ni->initialized_size != old_init_size) {
608 mutex_lock(&ni->mrec_lock);
609 ntfs_attr_set_initialized_size(ni, old_init_size);
610 mutex_unlock(&ni->mrec_lock);
611 }
612 if (ni->data_size != old_data_size) {
613 truncate_setsize(vi, old_data_size);
614 ntfs_attr_truncate(ni, old_data_size);
615 }
616 }
617 out_lock:
618 inode_unlock(vi);
619 if (ret > 0)
620 ret = generic_write_sync(iocb, ret);
621 return ret;
622 }
623
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-08-13 21:05 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-02 6:35 [PATCH] ntfs: prevent write access to $MFT inode Hongling Zeng
2026-08-13 21:04 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox