{"uuid": "c87bbfcb-0d83-4cd2-94ce-797e7a0bf94a", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-31431", "type": "seen", "source": "https://gist.github.com/sayem314/6a33676059e6539501c55a978410795d", "content": "Copy Fail is a Linux kernel local privilege escalation in `algif_aead`, part of the AF_ALG userspace crypto API. If a vulnerable host runs untrusted local code, containers, CI jobs, app sandboxes, or shared shell users, treat it as urgent.\n\nThe real fix is a patched kernel from your distribution. The mitigation below blocks the affected module until you can patch and reboot.\n\nSources:\n\n- https://copy.fail/\n- https://ubuntu.com/blog/copy-fail-vulnerability-fixes-available\n- https://security-tracker.debian.org/tracker/CVE-2026-31431\n\n## Quick check\n\n```bash\nuname -r\ndpkg -l 'linux-image*' | grep '^ii'\ndpkg -l kmod | grep '^ii'\ngrep -qE '^algif_aead ' /proc/modules &amp;&amp; echo \"algif_aead is loaded\" || echo \"algif_aead is not loaded\"\n```\n\nOn Ubuntu, Canonical also shipped a `kmod` mitigation for affected releases. Still update the kernel when your release has a fixed kernel package.\n\n```bash\nsudo apt update\nsudo apt install --only-upgrade kmod\nsudo apt full-upgrade\nsudo reboot\n```\n\n## Manual mitigation\n\nUse this when you cannot patch immediately, or when you want a fleet-wide safety block while waiting for kernel updates.\n\n```bash\nsudo tee /etc/modprobe.d/disable-algif_aead.conf &gt;/dev/null &lt;&lt;'EOF'\ninstall algif_aead /bin/false\nEOF\n\nsudo modprobe -r algif_aead 2&gt;/dev/null || true\n\ngrep -qE '^algif_aead ' /proc/modules &amp;&amp; echo \"algif_aead is still loaded, reboot required\" || echo \"algif_aead is not loaded\"\nmodprobe -n -v algif_aead\n```\n\nExpected `modprobe -n -v algif_aead` output should include:\n\n```text\ninstall /bin/false\n```\n\nIf `algif_aead` is still loaded after `modprobe -r`, reboot the host. If you suspect the host was already exposed to untrusted local code, prefer a reboot after applying the mitigation or kernel update.\n\n## Ansible playbook\n\nSave as `copyfail-mitigate.yml`:\n\n```yaml\n---\n- name: Mitigate Copy Fail CVE-2026-31431\n  hosts: all\n  become: true\n  gather_facts: false\n\n  vars:\n    copyfail_module: algif_aead\n\n  tasks:\n    - name: Block algif_aead from loading\n      ansible.builtin.copy:\n        dest: \"/etc/modprobe.d/disable-{{ copyfail_module }}.conf\"\n        owner: root\n        group: root\n        mode: \"0644\"\n        content: |\n          install {{ copyfail_module }} /bin/false\n      register: copyfail_blacklist\n\n    - name: Unload algif_aead if currently loaded\n      community.general.modprobe:\n        name: \"{{ copyfail_module }}\"\n        state: absent\n      register: copyfail_unload\n      failed_when: false\n\n    - name: Check whether algif_aead is still loaded\n      ansible.builtin.shell: \"grep -qE '^{{ copyfail_module }} ' /proc/modules\"\n      register: copyfail_loaded\n      changed_when: false\n      failed_when: false\n\n    - name: Verify modprobe resolves algif_aead to /bin/false\n      ansible.builtin.command: \"modprobe -n -v {{ copyfail_module }}\"\n      register: copyfail_modprobe_check\n      changed_when: false\n\n    - name: Show mitigation status\n      ansible.builtin.debug:\n        msg:\n          - \"config_changed={{ copyfail_blacklist.changed }}\"\n          - \"module_unload_rc={{ copyfail_unload.rc | default('n/a') }}\"\n          - \"module_loaded={{ copyfail_loaded.rc == 0 }}\"\n          - \"modprobe_check={{ copyfail_modprobe_check.stdout }}\"\n\n    - name: Fail if algif_aead is still loaded\n      ansible.builtin.fail:\n        msg: \"algif_aead is still loaded. Reboot this host to complete mitigation.\"\n      when: copyfail_loaded.rc == 0\n```\n\nExample `inventory.yml`:\n\n```yaml\n---\nall:\n  children:\n    webservers:\n      hosts:\n        web-1:\n          ansible_host: 203.0.113.10\n          ansible_user: ubuntu\n        web-2:\n          ansible_host: 203.0.113.11\n          ansible_user: ubuntu\n    workers:\n      hosts:\n        worker-1:\n          ansible_host: 203.0.113.20\n          ansible_user: debian\n  vars:\n    ansible_become: true\n    ansible_python_interpreter: /usr/bin/python3\n```\n\nRun it:\n\n```bash\nansible-playbook -i inventory.yml copyfail-mitigate.yml\n```\n\nRun only a selected group:\n\n```bash\nansible-playbook -i inventory.yml copyfail-mitigate.yml --limit webservers\n```\n\n## Ansible role-style task\n\nIf you already have a common hardening role, put the module name in group vars:\n\n```yaml\ndisabled_kernel_modules:\n  - algif_aead\n```\n\nThen use this task block:\n\n```yaml\n- name: Block disabled kernel modules from loading\n  ansible.builtin.copy:\n    dest: \"/etc/modprobe.d/disable-{{ item }}.conf\"\n    owner: root\n    group: root\n    mode: \"0644\"\n    content: |\n      install {{ item }} /bin/false\n  loop: \"{{ disabled_kernel_modules | default([]) }}\"\n\n- name: Unload disabled kernel modules if currently loaded\n  community.general.modprobe:\n    name: \"{{ item }}\"\n    state: absent\n  loop: \"{{ disabled_kernel_modules | default([]) }}\"\n  failed_when: false\n```\n\n## What may break\n\nFor most Debian and Ubuntu servers, nothing noticeable. Normal TLS, SSH, LUKS, WireGuard, IPsec, OpenSSL, Docker networking, and web apps do not depend on `algif_aead`.\n\nPossible impact: software explicitly configured to use AF_ALG from userspace, such as OpenSSL with the `afalg` engine enabled or custom apps that open AF_ALG sockets directly. If unsure, check:\n\n```bash\nss -xa | grep -i alg || true\nlsof 2&gt;/dev/null | grep AF_ALG || true\n```\n\n## Remove the manual mitigation later\n\nOnly do this after your running kernel is fixed and you have rebooted into it.\n\n```bash\nsudo rm /etc/modprobe.d/disable-algif_aead.conf\nsudo reboot\n```\n", "creation_timestamp": "2026-05-08T16:18:22.000000Z"}