Ansible copy module fails with “Invalid cross-device link” followed by “Operation not permitted” when copying into hardened /etc directory with become

Ansible copy module fails with “Invalid cross-device link” followed by “Operation not permitted” when copying into hardened /etc directory with become

Hello,

I’m encountering a failure with the Ansible copy module when copying a file into a hardened system directory. I would like to confirm whether this is expected behavior or a configuration issue.

Environment

  • Ansible core version: 2.16.14
  • AWX execution environment
  • Target OS: RHEL-based hardened image
  • Connection user: efv-ansible
  • Privilege escalation: become: true (sudo, passwordless)
  • SELinux: Disabled
  • Filesystem: standard ext4/xfs
  • Destination path: /etc/common/swid
- name: Copy SWID file
  copy:
    src: secure-standard-build.swidtag
    dest: /etc/common/swid
    owner: root
    group: root
    mode: '0600'
  become: true

error on my AWX:

diff: []
exception: >
  Traceback (most recent call last):
    File "/tmp/ansible_ansible.legacy.copy_payload_x_qms_48/ansible_ansible.legacy.copy_payload.zip/ansible/module_utils/basic.py", line 1690, in atomic_move
      os.rename(b_src, b_dest)
  OSError: [Errno 18] Invalid cross-device link:
  b'/home/efv-ansible/.ansible/tmp/ansible-tmp-1770408721.4119422-4350-152331924043449/source'
  -> b'/etc/common/swid/secure-standard-build.swidtag'


  During handling of the above exception, another exception occurred:


  Traceback (most recent call last):
    File "/tmp/ansible_ansible.legacy.copy_payload_x_qms_48/ansible_ansible.legacy.copy_payload.zip/ansible/module_utils/basic.py", line 1741, in atomic_move
      os.rename(b_tmp_dest_name, b_dest)
  PermissionError: [Errno 1] Operation not permitted:
  b'/etc/common/swid/.ansible_tmp1f2s3zacsecure-standard-build.swidtag'
  -> b'/etc/common/swid/secure-standard-build.swidtag'
msg: >-
  Unable to make
  b'/home/efv-ansible/.ansible/tmp/ansible-tmp-1770408721.4119422-4350-152331924043449/source'
  into to /etc/common/swid/secure-standard-build.swidtag, failed final
  rename from
  b'/etc/common/swid/.ansible_tmp1f2s3zacsecure-standard-build.swidtag':
  [Errno 1] Operation not permitted:
  b'/etc/common/swid/.ansible_tmp1f2s3zacsecure-standard-build.swidtag'
  -> b'/etc/common/swid/secure-standard-build.swidtag'
invocation:
  module_args:
    src: >-
      /home/efv-ansible/.ansible/tmp/ansible-tmp-1770408721.4119422-4350-152331924043449/source
    dest: /etc/common/swid
    owner: root
    group: root
    mode: '0600'
    _original_basename:secure-standard-build.swidtag
    follow: false
    checksum: 1c23f81499fa5752a57539170b898f084500728d
    backup: false
    force: true
    unsafe_writes: false
checksum: 1c23f81499fa5752a57539170b898f084500728d
_ansible_no_log: false
changed: false

Observations / Validation already done

  • Destination directory exists and is writable by root
  • No ACL restrictions
  • Sudo escalation confirmed
    sudo -l -U efv-ansible
    (ALL) NOPASSWD: ALL

Current Understanding

From debugging, it appears:

  • Ansible creates temporary files under:
    /home/efv-ansible/.ansible/tmp
  • The copy module then performs an atomic rename into /etc/...
  • The system rejects the rename operation with Operation not permitted

This seems related to the temp file being created as the connection user rather than root prior to privilege escalation.

Ansible attempts several things to do an atomic update of the file, the last one is:

  [Errno 1] Operation not permitted:
  b'/etc/common/swid/.ansible_tmp1f2s3zacsecure-standard-build.swidtag'
  -> b'/etc/common/swid/secure-standard-b

The temporary file is in the same directory and cannot overwrite the target file, this might be due to flags or other restrictions on the file. You need to find out what is creating this restriction, it can be things like having the immutable flag on the file or it is mounted from a host system in such a way that the container cannot overwrite the inode.

Depending on the issue, one thing you can try is setting unsafe_writes=True which will try to write to the existing inode, but this is not something we normally recommend as it will allow other processes to access a file in inconsistent/intermediate states.

1 Like

Can you guide me to troubleshoot this i have confirmed that this is not a immutable file

Is /home/efv-ansible/.ansible/ located on nfs mount or with different filesystem?