On 1/2/25 9:37 AM, Jan Kara wrote:
Hello!
On Fri 27-12-24 13:15:08, Pali Rohár wrote:
Few months ago I discussed with Steve that Linux SMB client has some
problems during removal of directory which has read-only attribute set.
I was looking what exactly the read-only windows attribute means, how it
is interpreted by Linux and in my opinion it is wrongly used in Linux at
all.
Windows filesystems NTFS and ReFS, and also exported over SMB supports
two ways how to present some file or directory as read-only. First
option is by setting ACL permissions (for particular or all users) to
GENERIC_READ-only. Second option is by setting the read-only attribute.
Second option is available also for (ex)FAT filesystems (first option via
ACL is not possible on (ex)FAT as it does not have ACLs).
First option (ACL) is basically same as clearing all "w" bits in mode
and ACL (if present) on Linux. It enforces security permission behavior.
Note that if the parent directory grants for user delete child
permission then the file can be deleted. This behavior is same for Linux
and Windows (on Windows there is separate ACL for delete child, on Linux
it is part of directory's write permission).
Second option (Windows read-only attribute) means that the file/dir
cannot be opened in write mode, its metadata attribute cannot be changed
and the file/dir cannot be deleted at all. But anybody who has
WRITE_ATTRIBUTES ACL permission can clear this attribute and do whatever
wants.
I guess someone with more experience how to fuse together Windows & Linux
permission semantics should chime in here but here are my thoughts.
Linux filesystems has similar thing to Windows read-only attribute
(FILE_ATTRIBUTE_READONLY). It is "immutable" bit (FS_IMMUTABLE_FL),
which can be set by the "chattr" tool. Seems that the only difference
between Windows read-only and Linux immutable is that on Linux only
process with CAP_LINUX_IMMUTABLE can set or clear this bit. On Windows
it can be anybody who has write ACL.
Now I'm thinking, how should be Windows read-only bit interpreted by
Linux filesystems drivers (FAT, exFAT, NTFS, SMB)? I see few options:
0) Simply ignored. Disadvantage is that over network fs, user would not
be able to do modify or delete such file, even as root.
1) Smartly ignored. Meaning that for local fs, it is ignored and for
network fs it has to be cleared before any write/modify/delete
operation.
2) Translated to Linux mode/ACL. So the user has some ability to see it
or change it via chmod. Disadvantage is that it mix ACL/mode.
So this option looks sensible to me. We clear all write permissions in
file's mode / ACL. For reading that is fully compatible, for mode
modifications it gets a bit messy (probably I'd suggest to just clear
FILE_ATTRIBUTE_READONLY on modification) but kind of close.
IMO Linux should store the Windows-specific attribute information but
otherwise ignore it. Modifying ACLs based seems like a road to despair.
Plus there's no ACL representation for OFFLINE and some of the other
items that we'd like to be able to support.
If I were king-for-a-day (tm) I would create a system xattr namespace
just for these items, and provide a VFS/statx API for consumers like
Samba, ksmbd, and knfsd to set and get these items. Each local
filesystem can then implement storage with either the xattr or (eg,
ntfs) can store them directly.
Semantics like READONLY or IMMUTABLE might be provided in the VFS if
we care to expose these semantics to POSIX consumers.
3) Translated to Linux FS_IMMUTABLE_FL. So the user can use lsattr /
chattr to see or change it. Disadvantage is that this bit can be
changed only by root or by CAP_LINUX_IMMUTABLE process.
4) Exported via some new xattr. User can see or change it. But for
example recursive removal via rm -rf would be failing as rm would not
know about this special new xattr.
In any case, in my opinion, all Linux fs drivers for these filesystems
(FAT, exFAT, NTFS, SMB, are there some others?) should handle this
windows read-only bit in the same way.
What do you think, what should be the best option?
I have another idea. What about introducing a new FS_IMMUTABLE_USER_FL
bit which have same behavior as FS_IMMUTABLE_FL, just it would be
possible to set it for any user who has granted "write" permission?
Uh, in unix, write permission is for accessing file data. Modifying access
permissions etc. is always limited to inode owner (or user with special
capabilities). So this would be very confusing in Unix permission model.
Instead of requiring CAP_LINUX_IMMUTABLE. I see a nice usecase that even
ordinary user could be able to mark file as protected against removal or
modification (for example some backup data).
So I don't see us introducing another immutable bit in VFS. Special
"protected file" bit modifiable by whoever can modify file permissions is
not really different from clearing write permission bits in mode. So that
doesn't seem as a terribly useful feature to me. That being said nothing
really stops individual filesystems from introducing their own inode flags,
get / set them via ioctl and implement whatever permission checking needed
with them. After all this is how the flags like IMMUTABLE or APPEND started
and only later on when they propagated into many filesystems we've lifted
them into VFS.
Honza
--
Chuck Lever