After archiving a directory tree with GNU tar and unpacking it on another Linux host, the named-user ACL entries are gone although the ordinary mode bits survived. Where does Linux store POSIX ACLs, and what decides whether they survive a copy or a restore?
answer
- not in the inode mode word
- stored beside the file, not in it
- the tool has to ask for them
- the destination must be able to hold them
- the group triad lies afterwards
basics
~20 sPOSIX ACLs live in extended attributes on the file, not in the inode mode field, so any tool that copies only mode bits silently drops them. GNU tar needs --acls, rsync needs -A, and the destination filesystem must be able to store extended attributes at all.
solid answer
~40 sThe nine mode bits are part of the inode itself, so they travel with almost any tool. Extended ACL entries are stored separately, in the extended attributes `system.posix_acl_access` and `system.posix_acl_default`, and a tool has to ask for them. GNU tar carries them only with `--acls`; `rsync` needs `-A`/`--acls`, which its `-a` archive mode does *not* imply; `cp` needs `-a` or `--preserve=all`. The destination matters too: ext4, XFS and btrfs support ACLs and enable them by default on current kernels, while filesystems such as vfat and exfat cannot store them at all, and NFSv4 uses a different ACL model rather than POSIX ACLs. For a tool-independent record, dump with `getfacl -R` and reapply with `setfacl --restore`. Verify a restore by looking for the `+` in `ls -l`, not by trusting the mode.
code
bash · 5 linesgetfacl -R /srv/shared > /var/backups/shared.acl
tar --acls -cf shared.tar -C /srv shared
tar --acls -xf shared.tar -C /srv2
ls -l /srv2/shared | head # look for the trailing '+'
setfacl --restore=/var/backups/shared.aclgo deeper
Remember that ACLs are stored separately from the mode bits, so a plain copy or archive can leave them behind; check for the + in ls -l after moving files.
Name the two extended attributes that hold the access and default ACLs, and know which options each tool needs — tar --acls, rsync -A, cp -a — plus that rsync -a alone is not enough.
Plan the migration: verify destination filesystem support and mount options, take a getfacl -R dump as a fallback and an audit artefact, and validate by diffing ACL dumps rather than reading modes, knowing the group triad can read wider than reality once entries are gone.
Treat ACLs as state your backup and DR story must explicitly cover: decide whether the platform guarantees extended-attribute fidelity end to end, or whether access control must be expressed in a way that survives any transport.
## Two places permissions live A file's classic permissions are three fields in the on-disk inode: owner UID, group GID, and the mode word holding the nine `rwx` bits plus the special bits. Every tool that has ever copied a file understands them, and `stat` returns them without any filesystem-specific machinery. Extended ACL entries are not in the inode. They are stored as **extended attributes** — arbitrary name/value pairs attached to the file — under two reserved names in the `system` namespace: - `system.posix_acl_access` — the access ACL - `system.posix_acl_default` — the default (inheritance) ACL, on directories That single fact explains nearly every ACL-loss incident. Copying a file's permissions and copying a file's extended attributes are two different operations, and the second one is opt-in almost everywhere. ## Which tools carry them | Tool | Carries ACLs when | |---|---| | GNU `tar` | `--acls` is passed (`--xattrs` for other extended attributes) | | `rsync` | `-A` / `--acls` is passed — **not** implied by `-a` | | GNU `cp` | `-a` or `--preserve=all` | | `getfacl` / `setfacl` | always — that is their entire job | The `rsync` case is the classic production trap: `-a` is universally described as "archive mode, preserve everything", and it does preserve permissions, ownership, timestamps, symlinks and devices — but ACLs and extended attributes need `-A` and `-X` respectively, on both ends, with both builds supporting them. ## Which filesystems can hold them A filesystem must support extended attributes before it can hold an ACL: - `ext4`, `XFS` and `btrfs` support POSIX ACLs and enable them by default on current kernels. Older ext-family setups required an explicit `acl` mount option; that is now the default, and the `noacl` option exists to turn support off. - `tmpfs` supports them, which matters for containerised and `/run`-based layouts. - `vfat` and `exfat` have no extended attributes at all — an ACL simply cannot be represented, so a USB stick or an EFI partition is a one-way trip. - Network filesystems are their own topic: NFSv4 defines a richer ACL model that is not POSIX ACLs, so entries may be mapped, approximated or lost depending on server and client configuration. Never assume a POSIX ACL round-trips across a network filesystem without testing it. A restore that silently drops ACLs on a filesystem that cannot store them is not a bug in the tool; it is the destination refusing to represent the data. ## The tool-independent dump When you cannot guarantee the pipeline preserves extended attributes, take the ACLs out of band: ``` $ cd /srv/shared $ getfacl -R . > /var/backups/shared.acl ... move the data by whatever means ... $ cd /srv/shared $ setfacl --restore=/var/backups/shared.acl ``` `getfacl -R` walks the tree and prints a text record with `# file:` headers, and `setfacl --restore` replays it, including the `default:` entries. Because it is plain text it also makes a reviewable artefact — you can diff yesterday's ACL dump against today's and see what changed, which no `ls -l` will ever tell you. ## Why the mode still looks correct after the loss This is the part that makes the failure dangerous rather than merely annoying. On a file with an extended ACL, the group triad of the mode is the **mask**, not the owning group's own rights. When the extended entries are dropped in transit, the mask value stays behind in the mode word and is now interpreted literally as the owning group's permissions. So a file that was `-rw-rw----+` with a mask of `rw-` and an actual `group::r--` arrives as `-rw-rw----`, quietly granting the whole owning group write access it never had. The permissions did not just get *lost* — in the group triad they can get *widened*. That is why the verification step after any migration is `find` for the `+` marker or a re-run of `getfacl -R` compared against the source, rather than eyeballing `ls -l`. ## Practical checklist for a migration 1. Confirm the source tree actually uses ACLs (`getfacl -R` and look for named entries). 2. Confirm the destination filesystem supports them and is not mounted `noacl`. 3. Choose a transfer that carries them (`tar --acls`, `rsync -AX`, `cp -a`) *and* verify the tool on both hosts supports the option. 4. Take a `getfacl -R` dump before the move as your fallback and your audit record. 5. After the move, compare a fresh `getfacl -R` against the dump — not the modes.
- How would you capture and reapply ACLs when the transfer tool cannot carry them?Dump them out of band with `getfacl -R /srv/shared > acls.txt`, move the data however you like, then replay with `setfacl --restore=acls.txt` at the destination. The dump is plain text including `default:` entries, so it doubles as a reviewable record you can diff between runs to see what changed.
- Why can permissions end up more permissive after ACL entries are lost in transit?On a file with an extended ACL the group-class mode bits hold the mask, which is a ceiling, not the owning group's real grant. Strip the extended entries and that value is reinterpreted literally as the owning group's rights, so a file whose group actually had `r--` under an `rw-` mask arrives granting the group write.
- How do you check quickly whether a restored tree still carries its ACLs?Look for the `+` marker rather than the mode: `ls -l` shows it per file, and a recursive `getfacl -R` on both source and destination gives a diffable record. Also confirm the destination is not mounted with `noacl` and that the filesystem supports extended attributes at all, since the failure may be at the destination rather than in the tool.
saying these in an interview costs you the question
- Assuming rsync -a preserves ACLs
- Believing ACLs live in the inode with the mode bits
- Thinking any filesystem can store an ACL
- Verifying a restore by reading ls -l mode bits
- Expecting POSIX ACLs to round-trip unchanged over NFSv4