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


2 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