Files
VeraCrypt/Tests/test_windows_header_cleanup.py
Mounir IDRASSI 7eab121669 Release header allocations after early setup failures
Free the key-info buffer and owned crypto context on pre-KDF errors,
preserving borrowed contexts and avoiding uninitialized drain resources.

Inject every setup allocation and event failure to verify cleanup.
2026-10-16 21:27:25 +09:00

55 lines
2.3 KiB
Python

#!/usr/bin/env python3
"""Inject failures into the production Windows header setup/cleanup paths.
Extracts those paths verbatim; replaces only the intervening cryptographic search
with a chosen success/failure result. Tracks allocation, event and lock ownership.
Run in an x64 MSVC environment: python Tests/test_windows_header_cleanup.py
"""
import argparse
import os
from pathlib import Path
import shutil
import subprocess
import tempfile
from test_windows_kdf_completion import ROOT, block
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--build-dir", type=Path)
args = parser.parse_args()
if os.name != "nt" or not shutil.which("cl.exe"):
parser.error("An x64 MSVC developer environment on Windows is required")
build = (args.build_dir or Path(tempfile.mkdtemp(prefix="vc-header-cleanup-"))).resolve()
build.mkdir(parents=True, exist_ok=True)
source = (ROOT / "src/Common/Volumes.c").read_text()
start = source.index("int ReadVolumeHeaderWithAbort (")
header = block(source, start)
setup = header[:header.index("\tcrypto_loadkey (keyInfo,")]
cleanup = header[header.index("\nerr:"):]
signature = source[start:source.index("{", start)]
(build / "header_cleanup.inc").write_text(signature + setup + """
if (TestHeaderError) { status = ERR_PASSWORD_WRONG; goto err; }
status = ERR_SUCCESS;
goto ret;
""" + cleanup)
item_end = source.index("} KeyDerivationWorkItem;") + len("} KeyDerivationWorkItem;")
item_start = source.rindex("typedef struct", 0, item_end)
(build / "kdf_item.inc").write_text(source[item_start:item_end])
exe = build / "windows_header_cleanup_test.exe"
command = ["cl.exe", "/nologo", "/O2", "/W3", "/WX", "/MD", "/wd4101",
"/DUNICODE", "/D_UNICODE", f"/I{build}"]
command += [f"/I{ROOT / 'src' / directory}"
for directory in ("", "Common", "Crypto", "Crypto/Argon2/include")]
command += [str(ROOT / "Tests/windows_header_cleanup_test.c"), f"/Fe:{exe}"]
result = subprocess.run(command, cwd=build, capture_output=True, text=True)
(build / "build.log").write_text(result.stdout + result.stderr)
if result.returncode:
raise RuntimeError(result.stdout + result.stderr)
subprocess.run([str(exe)], cwd=build, check=True, timeout=30)
if __name__ == "__main__":
main()