* [PATCH 0/2] fs/ntfs3: fixes for directory permission and symlink consistency
@ 2026-09-27 18:03 Zhenyan Wang
2026-09-27 18:03 ` [PATCH 1/2] fs/ntfs3: clear FILE_ATTRIBUTE_READONLY bit when argument 'mode' contains write permission Zhenyan Wang
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Zhenyan Wang @ 2026-09-27 18:03 UTC (permalink / raw)
To: Konstantin Komarov
Cc: Christian Brauner, ntfs3, linux-fsdevel, linux-kernel, Zhenyan Wang
This patch series fixes two instances of non-compliance with POSIX
specifications.
Patch 1 clears FILE_ATTRIBUTE_READONLY when the argument 'mode' of mkdir
contains write permission.
Patch 2 leaves the symlink target unchanged in PrintName, avoiding
conversion from '\' to '/' in readlink.
The patched code is compiled and tested in qemu. Everything works well.
Zhenyan Wang (2):
fs/ntfs3: clear FILE_ATTRIBUTE_READONLY bit when argument 'mode'
contains write permission
fs/ntfs3: keep PrintName not changed when creating symlink
fs/ntfs3/inode.c | 24 +++++++++++-------------
1 file changed, 11 insertions(+), 13 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH 1/2] fs/ntfs3: clear FILE_ATTRIBUTE_READONLY bit when argument 'mode' contains write permission 2026-09-27 18:03 [PATCH 0/2] fs/ntfs3: fixes for directory permission and symlink consistency Zhenyan Wang @ 2026-09-27 18:03 ` Zhenyan Wang 2026-09-27 18:03 ` [PATCH 2/2] fs/ntfs3: keep PrintName not changed when creating symlink Zhenyan Wang 2026-09-27 20:30 ` [PATCH 0/2] fs/ntfs3: fixes for directory permission and symlink consistency Zhenyan Wang 2 siblings, 0 replies; 6+ messages in thread From: Zhenyan Wang @ 2026-09-27 18:03 UTC (permalink / raw) To: Konstantin Komarov Cc: Christian Brauner, ntfs3, linux-fsdevel, linux-kernel, Zhenyan Wang When creating a subdirectory, ntfs3 inherits the parent's FILE_ATTRIBUTE_READONLY bit unconditionally, which means if the parent is readonly, the child is readonly by default. When argument 'mode' does not contain write permission, ntfs3 sets this bit to 1. However, when mode contains write permission, it does not clear this bit. Fix this by clearing FILE_ATTRIBUTE_READONLY when mode contains write permission. Signed-off-by: Zhenyan Wang <maximwang110@gmail.com> --- fs/ntfs3/inode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c index 0c9bd66..6717563 100644 --- a/fs/ntfs3/inode.c +++ b/fs/ntfs3/inode.c @@ -1273,6 +1273,8 @@ int ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir, if (!(mode & 0222)) fa |= FILE_ATTRIBUTE_READONLY; + else + fa &= ~FILE_ATTRIBUTE_READONLY; new_de = kzalloc(PATH_MAX, GFP_KERNEL); if (!new_de) { -- 2.53.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/2] fs/ntfs3: keep PrintName not changed when creating symlink 2026-09-27 18:03 [PATCH 0/2] fs/ntfs3: fixes for directory permission and symlink consistency Zhenyan Wang 2026-09-27 18:03 ` [PATCH 1/2] fs/ntfs3: clear FILE_ATTRIBUTE_READONLY bit when argument 'mode' contains write permission Zhenyan Wang @ 2026-09-27 18:03 ` Zhenyan Wang 2026-09-28 7:28 ` Zhan Xusheng 2026-09-27 20:30 ` [PATCH 0/2] fs/ntfs3: fixes for directory permission and symlink consistency Zhenyan Wang 2 siblings, 1 reply; 6+ messages in thread From: Zhenyan Wang @ 2026-09-27 18:03 UTC (permalink / raw) To: Konstantin Komarov Cc: Christian Brauner, ntfs3, linux-fsdevel, linux-kernel, Zhenyan Wang When creating a symlink, ntfs3 converts all the '/' to '\' in both PrintName and SubstituteName. When reading this symlink, ntfs3 converts all the '\' to '/'. So if you create a symlink to 'a\b', the result of readlink would be 'a/b'. Fix this by converting SubstituteName only because SubstituteName is used by NT kernel to read symlink while PrintName isn't; PrintName is left unchanged to ensure consistency. Signed-off-by: Zhenyan Wang <maximwang110@gmail.com> --- fs/ntfs3/inode.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c index 6717563..000ac34 100644 --- a/fs/ntfs3/inode.c +++ b/fs/ntfs3/inode.c @@ -1091,6 +1091,7 @@ ntfs_create_reparse_buffer(struct ntfs_sb_info *sbi, const char *symname, int i, err; struct REPARSE_DATA_BUFFER *rp; __le16 *rp_name; + __le16 *sub_name; typeof(rp->SymbolicLinkReparseBuffer) *rs; bool is_absolute; @@ -1118,12 +1119,6 @@ ntfs_create_reparse_buffer(struct ntfs_sb_info *sbi, const char *symname, goto out; } - /* Translate Linux '/' into Windows '\'. */ - for (i = 0; i < err; i++) { - if (rp_name[i] == cpu_to_le16('/')) - rp_name[i] = cpu_to_le16('\\'); - } - rp->ReparseTag = IO_REPARSE_TAG_SYMLINK; rp->ReparseDataLength = cpu_to_le16(*nsize - offsetof(struct REPARSE_DATA_BUFFER, @@ -1142,9 +1137,16 @@ ntfs_create_reparse_buffer(struct ntfs_sb_info *sbi, const char *symname, */ rs->Flags = cpu_to_le32(is_absolute ? 0 : SYMLINK_FLAG_RELATIVE); - memmove(rp_name + err + (is_absolute ? 4 : 0), rp_name, + sub_name = rp_name + err + (is_absolute ? 4 : 0); + memmove(sub_name, rp_name, sizeof(short) * err); + /* Translate Linux '/' into Windows '\'. */ + for (i = 0; i < err; i++) { + if (sub_name[i] == cpu_to_le16('/')) + sub_name[i] = cpu_to_le16('\\'); + } + if (is_absolute) { /* Decorate SubstituteName. */ rp_name += err; @@ -2031,12 +2033,6 @@ static noinline int ntfs_readlink_hlp(const struct dentry *link_de, if (err < 0) goto out; - /* Translate Windows '\' into Linux '/'. */ - for (i = 0; i < err; i++) { - if (buffer[i] == '\\') - buffer[i] = '/'; - } - /* Always set last zero. */ buffer[err] = 0; -- 2.53.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] fs/ntfs3: keep PrintName not changed when creating symlink 2026-09-27 18:03 ` [PATCH 2/2] fs/ntfs3: keep PrintName not changed when creating symlink Zhenyan Wang @ 2026-09-28 7:28 ` Zhan Xusheng 2026-09-28 8:03 ` Zhenyan Wang 0 siblings, 1 reply; 6+ messages in thread From: Zhan Xusheng @ 2026-09-28 7:28 UTC (permalink / raw) To: Zhenyan Wang Cc: Zhan Xusheng, Konstantin Komarov, Christian Brauner, ntfs3, linux-fsdevel, linux-kernel On Sun, Sep 27, 2026 at 06:03:59PM +0000, Zhenyan Wang wrote: > - /* Translate Windows '\' into Linux '/'. */ > - for (i = 0; i < err; i++) { > - if (buffer[i] == '\\') > - buffer[i] = '/'; > - } ntfs_readlink_hlp() reads PrintName, for both tags: case IO_REPARSE_TAG_MOUNT_POINT: ... MountPointReparseBuffer.PrintNameOffset ... case IO_REPARSE_TAG_SYMLINK: ... SymbolicLinkReparseBuffer.PrintNameOffset ... On a volume written by Windows that PrintName is the display form, so its separator is '\' - "C:\Users\foo". Without this loop readlink() hands that back verbatim and the whole string becomes one component. The loop is after the switch, so junctions and mount points lose it too. Keeping it, the first hunk alone already fixes the '/' case: symlink target PrintName readlink a/b a/b a/b a\b a\b a/b The second row cannot be fixed this way. A '\' in PrintName is either a Windows separator or a literal character from Linux, and nothing in the buffer tells them apart, so a round trip for the literal one needs a different encoding, not a missing conversion. Also, after the first hunk the is_absolute block still decorates through rp_name while the copy is at sub_name; both point into the same buffer, which is easy to get wrong later. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] fs/ntfs3: keep PrintName not changed when creating symlink 2026-09-28 7:28 ` Zhan Xusheng @ 2026-09-28 8:03 ` Zhenyan Wang 0 siblings, 0 replies; 6+ messages in thread From: Zhenyan Wang @ 2026-09-28 8:03 UTC (permalink / raw) To: Zhan Xusheng Cc: Zhan Xusheng, Konstantin Komarov, Christian Brauner, ntfs3, linux-fsdevel, linux-kernel, Zhenyan Wang I noticed this regression shortly after submitting and I've already dropped Patch 2/2 in the cover letter thread. Link: https://lore.kernel.org/all/6ab97ce4.a24da115.4bfe6.0f74@mx.google.com/ Thanks. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 0/2] fs/ntfs3: fixes for directory permission and symlink consistency 2026-09-27 18:03 [PATCH 0/2] fs/ntfs3: fixes for directory permission and symlink consistency Zhenyan Wang 2026-09-27 18:03 ` [PATCH 1/2] fs/ntfs3: clear FILE_ATTRIBUTE_READONLY bit when argument 'mode' contains write permission Zhenyan Wang 2026-09-27 18:03 ` [PATCH 2/2] fs/ntfs3: keep PrintName not changed when creating symlink Zhenyan Wang @ 2026-09-27 20:30 ` Zhenyan Wang 2 siblings, 0 replies; 6+ messages in thread From: Zhenyan Wang @ 2026-09-27 20:30 UTC (permalink / raw) To: Konstantin Komarov Cc: Christian Brauner, ntfs3, linux-fsdevel, linux-kernel, Zhenyan Wang After analysis, I found that Patch 2 introduces a regression. The readlink function treats backslashes in symlinks as literal characters but they're path separators on Windows so symlinks created under Windows cannot be traversed. There is a partial way to fix. Since symlinks created under Windows wouldn't contain '/', in the readlink function, we may only convert symlinks without '/' to cover all Windows-created symlinks while keeping some of Linux-created symlinks shaped like 'a\b/c' unchanged. But the 'a\b' problem is back again - it isn't fixed because we cannot distinguish it from Windows-created ones. So I'm dropping Patch 2/2. Patch 1/2 is unaffected. ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-09-28 8:03 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-09-27 18:03 [PATCH 0/2] fs/ntfs3: fixes for directory permission and symlink consistency Zhenyan Wang 2026-09-27 18:03 ` [PATCH 1/2] fs/ntfs3: clear FILE_ATTRIBUTE_READONLY bit when argument 'mode' contains write permission Zhenyan Wang 2026-09-27 18:03 ` [PATCH 2/2] fs/ntfs3: keep PrintName not changed when creating symlink Zhenyan Wang 2026-09-28 7:28 ` Zhan Xusheng 2026-09-28 8:03 ` Zhenyan Wang 2026-09-27 20:30 ` [PATCH 0/2] fs/ntfs3: fixes for directory permission and symlink consistency Zhenyan Wang
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®