[PATCH] ntfs3: Update only the member values without replacing the opts pointer

Edward Adam Davis posted 1 patch 1 month, 3 weeks ago
fs/ntfs3/super.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[PATCH] ntfs3: Update only the member values without replacing the opts pointer
Posted by Edward Adam Davis 1 month, 3 weeks ago
There is a potential race condition when accessing options during remount
and read operations. This would trigger a uaf [1].

CPU0: remount				CPU1: read options
==================================	==================
do_remount()
reconfigure_super()
 ntfs_fs_reconfigure()
  sbi->options = fc->fs_private
put_fs_context()
 ntfs_fs_free()
  put_mount_options()			ntfs_show_options()
   kfree(sbi->options)			 opts = sbi->options
				         opts->dmask //trigger uaf

The fix involves not updating the sbi->options pointer during
reconfiguration, but instead using fc->fs_private to update the
corresponding member values.

[1]
BUG: KASAN: slab-use-after-free in ntfs_show_options+0x656/0x800 fs/ntfs3/super.c:762
Call Trace:
 ntfs_show_options+0x656/0x800 fs/ntfs3/super.c:762
 show_vfsmnt+0x637/0x780 fs/proc_namespace.c:129
 seq_read_iter+0x8d6/0xcb0 fs/seq_file.c:273
 new_sync_read fs/read_write.c:493 [inline]
 vfs_read+0x59e/0xa90 fs/read_write.c:574

Allocated by task 6027:
 ntfs_init_fs_context+0x55/0x570 fs/ntfs3/super.c:1862
 alloc_fs_context+0x9a3/0xd00 fs/fs_context.c:295
 do_remount fs/namespace.c:3392 [inline]
 path_mount+0xc5e/0x1040 fs/namespace.c:4153
 do_mount fs/namespace.c:4174 [inline]

Freed by task 6026:
 kfree+0x1c5/0x6c0 mm/slub.c:6692
 put_fs_context+0x123/0xb00 fs/fs_context.c:498
 do_remount fs/namespace.c:3419 [inline]
 path_mount+0xef9/0x1040 fs/namespace.c:4153
 do_mount fs/namespace.c:4174 [inline]

Fixes: cd39981fb92a ("fs/ntfs3: Fix double free on remount")
Reported-by: syzbot+4c22f022eb39c86b9d19@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=4c22f022eb39c86b9d19
Tested-by: syzbot+4c22f022eb39c86b9d19@syzkaller.appspotmail.com
Signed-off-by: Edward Adam Davis <eadavis@qq.com>
---
 fs/ntfs3/super.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
index 3305fe406cb2..58540491e68b 100644
--- a/fs/ntfs3/super.c
+++ b/fs/ntfs3/super.c
@@ -461,7 +461,7 @@ static int ntfs_fs_reconfigure(struct fs_context *fc)
 	}
 
 	sync_filesystem(sb);
-	swap(sbi->options, fc->fs_private);
+	memcpy(sbi->options, fc->fs_private, sizeof(*sbi->options));
 
 	return 0;
 }
-- 
2.43.0