{"uuid": "562b85ec-3899-4619-9450-c26b5a0248b6", "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/MKMithun2806/99dea4bb94917cf457ff8a81203e4bb2", "content": "#!/usr/bin/env python3\n\"\"\"\nCopy Fail (CVE-2026-31431) - read-only checker.\n\nDoes NOT:\n  - modify files\n  - modify page cache\n  - target setuid binaries\n  - execute an exploit\n\"\"\"\n\nimport os\nimport platform\nimport socket\nimport subprocess\nimport sys\n\n\nFIXES = {\n    \"5.10\": (5, 10, 254),\n    \"5.15\": (5, 15, 204),\n    \"6.1\":  (6, 1, 170),\n    \"6.6\":  (6, 6, 137),\n    \"6.12\": (6, 12, 85),\n    \"6.18\": (6, 18, 22),\n    \"6.19\": (6, 19, 12),\n}\n\n\ndef command(*args):\n    try:\n        return subprocess.check_output(\n            args,\n            text=True,\n            stderr=subprocess.DEVNULL\n        ).strip()\n    except (OSError, subprocess.CalledProcessError):\n        return None\n\n\ndef parse_kernel_release(release):\n    # Handles strings such as:\n    # 6.12.71-generic\n    # 6.6.90-rt\n    base = release.split(\"-\", 1)[0]\n    parts = base.split(\".\")\n\n    try:\n        return tuple(int(x) for x in parts[:3])\n    except (ValueError, IndexError):\n        return None\n\n\ndef kernel_version_status(version):\n    parsed = parse_kernel_release(version)\n\n    if not parsed:\n        return \"UNKNOWN\"\n\n    major, minor, patch = parsed\n    key = f\"{major}.{minor}\"\n\n    if key in FIXES:\n        fixed = FIXES[key]\n\n        if parsed &gt;= fixed:\n            return f\"PATCHED (&gt;= {fixed[0]}.{fixed[1]}.{fixed[2]})\"\n\n        return f\"POTENTIALLY AFFECTED (&lt; {fixed[0]}.{fixed[1]}.{fixed[2]})\"\n\n    # Versions older than the affected range are not relevant.\n    if parsed &lt; (4, 14, 0):\n        return \"NOT IN LISTED AFFECTED RANGE\"\n\n    # Newer branches may contain the upstream fix even when\n    # this table does not know their vendor backport status.\n    return \"UNKNOWN (check vendor kernel advisories)\"\n\n\ndef check_af_alg():\n    try:\n        s = socket.socket(socket.AF_ALG, socket.SOCK_SEQPACKET, 0)\n    except OSError as e:\n        return False, f\"AF_ALG unavailable: {e}\"\n\n    try:\n        s.bind((\"aead\", \"authencesn(hmac(sha256),cbc(aes))\"))\n        return True, \"authencesn available\"\n    except OSError as e:\n        return False, f\"authencesn unavailable: {e}\"\n    finally:\n        s.close()\n\n\ndef check_modules():\n    loaded = command(\"lsmod\")\n    if loaded is None:\n        return \"unknown\"\n\n    return \"loaded\" if \"algif_aead\" in loaded else \"not loaded\"\n\n\ndef main():\n    print(\"=\" * 60)\n    print(\" Copy Fail / CVE-2026-31431 \u2014 READ-ONLY CHECK\")\n    print(\"=\" * 60)\n\n    release = platform.release()\n    print(f\"\\nKernel       : {release}\")\n\n    version_status = kernel_version_status(release)\n    print(f\"Version      : {version_status}\")\n\n    splice = hasattr(os, \"splice\")\n    print(f\"os.splice()  : {'available' if splice else 'unavailable'}\")\n\n    afalg, afalg_msg = check_af_alg()\n    print(f\"AF_ALG       : {'available' if afalg else 'unavailable'}\")\n    print(f\"authencesn   : {afalg_msg}\")\n\n    module = check_modules()\n    print(f\"algif_aead   : {module}\")\n\n    distro = command(\"cat\", \"/etc/os-release\")\n    if distro:\n        pretty = None\n        for line in distro.splitlines():\n            if line.startswith(\"PRETTY_NAME=\"):\n                pretty = line.split(\"=\", 1)[1].strip('\"')\n                break\n        print(f\"Distro       : {pretty or 'unknown'}\")\n    else:\n        print(\"Distro       : unknown\")\n\n    print(\"\\nAssessment\")\n    print(\"-\" * 60)\n\n    if version_status.startswith(\"PATCHED\"):\n        print(\"[OK] Kernel version is at/above the listed fixed version.\")\n        print(\"     Verify your distro's advisory for backported fixes.\")\n\n    elif version_status.startswith(\"POTENTIALLY AFFECTED\"):\n        if afalg and splice:\n            print(\"[!] POTENTIALLY VULNERABLE\")\n            print(\"    Kernel is below the listed fixed release and\")\n            print(\"    the relevant attack surface is exposed.\")\n            print(\"    Check your distro's security advisory/package.\")\n        else:\n            print(\"[?] Kernel version is in an affected range,\")\n            print(\"    but the required attack surface is unavailable.\")\n\n    else:\n        print(\"[?] Cannot determine vulnerability status reliably\")\n        print(\"    from version information alone.\")\n\n    print(\"\\nThis checker performs no page-cache write and does not\")\n    print(\"execute /usr/bin/su or any other privileged executable.\")\n\n\nif __name__ == \"__main__\":\n    try:\n        main()\n    except KeyboardInterrupt:\n        print(\"\\nInterrupted.\", file=sys.stderr)\n        sys.exit(130)", "creation_timestamp": "2026-08-17T17:09:06.230037Z"}