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.