Skip to content

Releases: sylvinus/exav

Release list

v0.0.2

Choose a tag to compare

@github-actions github-actions released this 11 Oct 22:48
435e75a

The scanner, rebuilt around one streaming scan; three new projects (a browser
file viewer, image decoders, a perceptual image hash); and a long run of
fuzzing that fixed more than a hundred bounds and decoding bugs.

Highlights

  • One scan for every input, at any size. A file, stdin, a FIFO, INSTREAM,
    ICAP and HTTP all go through the same pipeline. A file over
    --max-object-bytes (256 MiB by default) now gets the full scan (wildcard and
    logical signatures, PCRE, YARA, bytecode, carving, heuristics), read through
    an 8 MiB block cache; it used to get a literal-and-hash pass only. What needs
    the whole object in memory (PE structure, Authenticode, packers, YARA's pe,
    elf and dotnet modules, containers read whole) makes such a file
    LIMITS-EXCEEDED, unless something is found. --all-matches and
    ALLMATCHSCAN list every detection at any size.
  • Faster. One index of signature literals replaces the automatons; a
    signature with a narrow offset window is checked where it can start; whole-file
    digests are computed once and only when a signature can use them; objects read
    through the block cache are read far fewer times. A prebuilt database is
    smaller and loads faster.
  • DWG and DXF drawings are scanned (R13 to 2018, ASCII and binary): the
    files an OLE2FRAME embeds are extracted and scanned.
  • @exav/viewer, a new npm package: a file viewer for the browser (PDF,
    images, DWG and DXF, Word, Excel, PowerPoint, CSV, IFC and STL models, video,
    audio, archives), each engine loaded on first use, with a sandboxed mode that
    opens each file in its own <iframe sandbox>. Demo at exav.org/viewer/demo/.
  • exav-render, memory-safe decoders for what to draw: TIFF, BMP and other
    raster images, JPEG 2000, JBIG2, fax, DWG, DXF, IFC, STL. exav-imagehash,
    a crate and a command: perceptual image hashes, with presets equal to
    sigtool --fuzzy-img and Python imagehash.phash; the scanner's fuzzy_img#
    now goes through it.
  • A Helm chart (deploy/helm/exav-chart) and a Kubernetes guide, by
    Bastien Ogier.
  • exav-unpack has unzip's command line: -l, -t, -p, -d, -x,
    -o, -n, -P and the rest mean what they mean to Info-ZIP unzip 6.00,
    with its exit statuses. It extracts every format the library reads, restores
    times, modes and symlinks, never writes through a link, and reads a split ZIP
    (.z01) or a RAR volume set from any part.
  • Releases carry exav-unpack, exav-grep, exav-pe-emu and exav-imagehash
    beside exav. exav.org is organised by product.

Breaking changes

  • Removed: --max-extracted-bytes (it stops the run with a message naming the
    change: a scan holds 1 GiB, 400M under --clamav-compat, and
    --max-process-bytes lowers it); --build-shard-bytes; exav-core's
    scan_stream (use scan_seekable); exav's checksums feature; the
    exav-unpack list and extract subcommands (-l, -d DIR).
  • Renamed: environment variables without a flag are EXAV_DEBUG_*
    (EXAV_BC_TRACE is EXAV_DEBUG_BC_TRACE, and so on); the systemd unit is
    exav.service (it was exav-clamd.service).
  • The daemon's signals match clamd's: SIGUSR2 reloads the signatures and
    SIGHUP reopens the --log file. SIGUSR2 used to kill the process.
  • A stream that ends before its terminator is answered ERROR on INSTREAM
    and EXINSTREAM. A signature path that loads nothing is an error.
  • YARA detections are named YARA.<rule> outside --clamav-compat. A YARA
    pattern keeps at most a million matches, as yara-x does.
  • --max-process-bytes also lowers --max-object-bytes to a quarter of the
    memory a scan gets: a file past it is LIMITS-EXCEEDED, not out of memory.
  • A scan that fails behind the ICAP listener is a block.
  • The published image uses Docker mediatypes, so podman honours its
    HEALTHCHECK (by Nastaliss). This drops the buildx provenance attestation.
    The 0.0.1 tags are OCI.

Added

  • --max-pcre-bytes, --min-scan-bytes (default 6) and
    --max-pe-emulation-steps; --partial-as password-protected=found reports
    any encrypted member as Heuristics.Encrypted.*, as ClamAV's
    --alert-encrypted does; the image-hash and phishing features, on by
    default; .msu databases under --detect pua.
  • Decoding: encrypted RAR with the caller's passwords (headers encrypted
    included), RAR 7 headers, ZIP Shrink, Reduce, Implode and PPMd members, NSIS
    with bzip2, ZIP members found by their local header, ZIP64 included.
  • A guide to sizing a server, with the flags for a 4 GB host; a health check in
    the Compose and Kubernetes examples; make miri.
  • exav-unpack: Prescan and detect_prescanned, and a modification time on
    MemberMeta and Entry.

Changed

  • Matching no longer copies an object whole, and PCRE no longer scans a copy of
    it. Bytecode follows ClamAV 1.4.3 in four more places, and its triggers are
    evaluated with the object's container.
  • A signature reload lets scans in progress finish. A DMG is walked without
    decompressing its whole disk.
  • A compressed stream damaged part way keeps what was decoded before the damage
    and is reported as damaged, not lost or complete. exav-unpack-wasm's
    list() decodes nothing it can avoid.
  • Dependencies: bincode (RUSTSEC-2025-0141) and serde are gone from
    exav-unpack; the RustCrypto crates move to their current generation
    (digest 0.11, cipher 0.5); ureq 3 for the http features, which now
    follows the HTTP_PROXY, HTTPS_PROXY and NO_PROXY environment;
    tlsh2 1.x, ext4-view 1.0 and lzma-rust2 0.21 with their upstream
    fixes; the bzip2 decoder is vendored from bzip2-rs with a fix.

Fixed

Found by fuzzing, an arithmetic audit and the ClamAV comparison. The bugs that
could change a verdict:

  • A decompression or parsing bomb now stops at a budget. About a hundred
    header numbers added or multiplied unchecked are refused: the disk-image
    readers (VMDK, QCOW2, VHDX, NTFS, WIM, ext, FAT, partitions), CHM, DWG
    polylines and hatches, 7z folders, carving, signature files and databases
    past u32. ARC, ZOO and .Z decoders no longer allocate without limit.
  • A damaged or cut-short member is never OK. Truncated bzip2, Zstandard,
    xz, UPX, NSIS, 7z PPMd, DMG and EGG data, a RAR member failing its CRC, and a
    member cut off by the end of the file are reported as damaged or
    UNSCANNABLE.
  • PCRE subsignatures match as ClamAV's PCRE2 does: bytes above 0x7F,
    offsets, the g flag, \b and \B beside a high byte, and a repeat that can
    match nothing.
  • RAR: encrypted headers and stored members, the window of each member in
    an archive, the x86, Itanium and ARM filters, empty members in a solid group,
    a volume set missing a volume, a volume numbered 65,535 or 2^64 - 1.
  • ZIP: members found only by their local header, with other bytes before
    the archive, in ZIP64 form, compressed with an unknown method, with LZMA or
    Zstandard and cut short. --all-matches with --alert-exceeds-max dropped
    the alert on a decompression bomb and reported a clean scan.
  • Performance and portability: a YARA xor(1-255) pattern cost 255
    comparisons per position; a scan time limit above 100,000,000 seconds was
    refused by macOS and left no limit.
  • Daemon: the watch of its signature source missed changes, so new
    signatures were not loaded; a worker stopped mid-job answers with ERROR
    instead of closing the connection; scanning a URL took a server that answered
    a range request with the whole object (200, not 206) as the range, and is
    an error now.
  • Emulator and decoders: a panic on a packed file with a bad import
    directory; the x86 decoder sized UMONITOR's register by the operand size;
    a PE whose parse failed over one malformed directory lost the rest.
  • Documents: PDF encryption (revision 4, 40-bit RC4), encrypted DMG and
    workbooks, VBA projects, lenient compound files, Ole10Native objects, GIF
    extension blocks, HTML and text signatures, JPEG checks under
    --detect broken-media, and fuzzy_img# hashes now computed as ClamAV 1.4.6
    does.
  • An object whose first read failed made the safetensors sniff panic.

0.0.1

Choose a tag to compare

@sylvinus sylvinus released this 16 Sep 17:56
3197917

First public release