I am looking to understand how a directory with the immutable bit set behaves on Linux. It is straightforward with files, but the nature of directories having two sides to themselves—the directories themselves and their contents—makes it more confusing. Let's say I had a directory that looked like this:


Can the immutable bits be used in such a way so as to make ${ROOT}, ${ROOT}/build, ${ROOT}/config, ${ROOT}/src, ${ROOT}/Makefile, and ${ROOT}/README read-only (i.e., permissions, owners, extended attributes, and names cannot be changed nor may files/directories be deleted or added) EXCEPT that files and directories may be freely added, removed, and modified under ${ROOT}/build and ${ROOT}/config? I imagine that this could be achieved by running either chattr -R +i ${ROOT}; chattr -R -i ${ROOT}/build ${ROOT}/config or chattr -R +i ${ROOT}; chattr -R -i ${ROOT}/build/* ${ROOT}/config/*, but the behavior of directories on this front is ambiguous to me. A potential use case for this would be if an administrator wants to leave the source code, the makefile, the README, and the top-level directory structure of this project unmodifiable by other users while still allowing them to build in it.

  • "Make ${ROOT}/build read-only" and "freely add and remove files under ${ROOT}/build" are mutually exclusive... – Satō Katsura Sep 13 '16 at 4:25
  • @SatoKatsura They aren't. I am talking about the folder itself being read-only. – Melab Sep 18 '16 at 21:09
  • Adding and removing files involves writing to said files' parent directory. That's basic UNIX semantics. – Satō Katsura Sep 19 '16 at 3:41

For the purposes of access control, the contents of a directory are the file names contained in it. To add, delete, or rename files, write access to the directory is required. (And to list the file names, read access is required.) In addition, there's the sticky bit (+t) for directories, that further limits file removal to the owner of the file and the owner of the directory. IOW, it prevents removing files owned by others, even if you have write access to the directory and could otherwise modify its contents.

As for permissions, only the owner can change those, and the owner of a file can only be changed by root. I think editing extended attributes is tied to write access, so you can't really forbid that separately.

As for your requirements, if I understood correctly, you want to allow creating files inside ${ROOT}/build and ${ROOT}/config, but not in other directories under ${ROOT}. This would be done simply by:

chmod a+rX -R ${ROOT}
chmod o-w -R ${ROOT}
chmod o+w -R ${ROOT}/build ${ROOT}/config
# chmod +t -R ${ROOT}/build ${ROOT}/config

There's really no need to use the immutable bit here, it's filesystem specific, and limits all users equally, including the owner and root.

However, if the builds will happen inside ${ROOT}/build, there's still the problem that multiple users will not be able to work without trampling each other's files. To work against that, you could modify the build system to support making builds in arbitrary output directories, or just let each user make their own copy of the source tree and compile it in their home directories.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.