Why cp Command Doesn’t Inherit ACLs and How to Fix It in Linux Filesystems


10 views

When working with shared directories in Linux, we often configure them with specific ACLs to ensure proper group access. A typical setup looks like:

$ mkdir shared_dir
$ chgrp developers shared_dir
$ chmod g+ws shared_dir
$ setfacl -m group:developers:rwx shared_dir
$ setfacl -dm group:developers:rwx shared_dir

While newly created files respect the default ACLs, copied files don't inherit these permissions:

$ cp external_file shared_dir/
$ ls -l shared_dir/
total 8
-rw-rw-r--+ 1 user developers 1024 Jun 1 10:00 new_file
-rw-r--r--+ 1 user developers 2048 Jun 1 10:01 external_file

The cp command creates new files with the process's umask rather than inheriting directory ACLs. This occurs because:

  • cp opens source file for reading
  • Creates destination file with default permissions
  • Copies content without ACL preservation

Option 1: Use rsync with ACL preservation

$ rsync -av --chmod=Du=rwx,Dg=rwx,Do=rx,Fu=rw,Fg=rw,Fo=r source_file shared_dir/

Option 2: Modify cp behavior with install

$ install -m 664 -t shared_dir/ source_file

Option 3: Create a cp wrapper script

#!/bin/bash
cp "$1" "$2" && setfacl --modify=file:"$2" --set-file=<(getfacl "$(dirname "$2")")

For consistent behavior across operations:

  • Consider setting system-wide defaults in /etc/profile
  • Use chmod g+s on directories for consistent group inheritance
  • Combine with filesystem mounting options like acl,user_xattr

Different filesystems handle ACLs differently. Test these solutions on:

  • ext4 with acl mount option
  • XFS (better ACL support)
  • ZFS with ACL inheritance enabled

When working with Linux file permissions, administrators often encounter an unexpected behavior: the cp command doesn't automatically inherit Access Control Lists (ACLs) from parent directories. This creates security and usability challenges in shared environments.


# Expected ACL inheritance (but doesn't happen)
$ setfacl -dm g:developers:rwx /shared
$ cp important_doc.txt /shared/
$ getfacl /shared/important_doc.txt
# Result shows missing group permissions

The cp command follows these permission-handling rules:

  • Creates new inodes for copied files (unlike mv)
  • Applies the user's umask to new files
  • Only preserves explicit source file permissions
  • Ignores parent directory's default ACLs during file creation

Here are three reliable approaches to ensure proper ACL inheritance:

1. Using rsync with ACL preservation


rsync -a --chmod=ugo=rwX --no-perms source_file /shared/

2. cp Alternative with ACL Support


cp --preserve=all --attributes-only source dest
cat source > dest

3. Post-copy ACL Application


cp source.txt /shared/
setfacl -b /shared/source.txt
setfacl --restore=shared_dir_acls.facl

The default behavior exists because:

  • Copy operations might cross security boundaries
  • Original file permissions often need preservation
  • Automatic ACL inheritance could create privilege escalation risks

For consistent permission handling:


# Set directory with proper defaults
mkdir /shared
setfacl -d -m g:devteam:rwx /shared
chmod g+s /shared

# Use wrapper script for copying
#!/bin/bash
cp "$1" /shared/ && 
setfacl -m g:devteam:rwx /shared/"${1##*/}"

Behavior may vary across filesystems:

  • XFS: Better ACL inheritance support
  • EXT4: Requires explicit ACL settings
  • ZFS: Advanced permission features