All notable changes to this project are documented in this file. The format is based on Keep a Changelog.
NIKOS is a fork of IKOS, ported from LLVM 14 to LLVM 20 and extended with additional checkers.
- LLVM frontend: the importer recovers pointer element types from the debug
information (previously every pointer was translated to
opaque*, losing signedness and layouts), types allocas fromllvm.dbg.declareonly (allvm.dbg.valueon an array made the array a scalar), and handles anonymoustypedef structtypes, class templates, C++ empty bases and[[no_unique_address]]members, pointers to members, empty parameters dropped by clang,llvm.global_ctors, and glibc symbol aliases. Theikos-importregression tests are regenerated from upstream's expectations;var-args.ll,vla.llandvirtual-inheritance.llare no longer skipped. ikos-pplowers sized and alignedoperator new/operator delete(default in clang 19+, including their 32-bit manglings) so thatdfa,boaanduafsee them; thestd::threadmodeling pass no longer crashes oninvokeinstructions, including forpthread_once.- LLVM frontend: an
allocais no longer typed from the debug information of another variable (a reference bound to a temporary made the allocation too small, or opaque); classes passed by reference are matched against every structure type of the module with the same name, whatever its.<n>suffix. - Composite scalar domain: the taint component was widened and narrowed twice and the taint of assigned integers was forgotten.
- Buffer overflow checker: no more assertion failure on zero-sized element types.
- Value analysis: the models of
read,getsandfgetswrote a literal zero byte into the buffer, hiding bugs from every checker. - Analysis engine: a pointer to a local variable returned by a function is now
matched with the result of the call, so use-after-return through
return &xis detected. - Taint analysis: tainted memory is tracked per memory location (definitely and
possibly tainted), taint propagates through operations, unknown functions,
strdup,strndup,memcpy,memmoveand the string functions, sinks receiving possibly tainted data are warnings, sources in the configuration are honored (includingscanf,recv,getline), and-a=taintrequires a taint configuration. Unknown functions no longer clear the taint of the buffers they receive, overwriting a buffer with untainted data (strcpy,sprintf,memset) makes it possibly tainted only, string literals and other constants are never tainted, and integers loaded from memory carry the taint of their cell. - Concurrency checker: rewritten as a lockset analysis with a thread count; no
crash on unknown pointers or without pointer analysis;
std::mutexand lock guards recognized by name (including guards over mutex types with nested names); single-threaded code is not reported. - Use-after-free checker: unknown, null and uninitialized pointers are left to the other checkers, use-after-return is only reported for local variables.
- Use-after-move checker: rewritten on top of the value analysis (dereference of a null pointer loaded from a moved-from object) instead of a global set of moved locations; no hardcoded class names; reassigned objects are not reported.
ikos-reportandikos-viewno longer crash on the new check kinds;ikos-report -tno longer crashes on a database without timing results; the SARIF rules are the check kinds, so that every result refers to a declared rule;ikos-viewcheck kind filters work and malformed filters are ignored;ikos-serveuses the right columns and reports a missing database at startup;ikos-scan --taintkeeps the default analyses; the taint configuration is only passed to the analyzer when the taint analysis is enabled, andikoswarns when--taint-configor--taint-profileis given without it.script/regen_checks.py: leading output lines are kept,CHECK-LABELlines are regenerated correctly when the label changes, tests without CHECK lines are supported, failures to run the tools are reported, and the tools can be given with--ikos-importand--file-check.- Packaging: the python virtual environment is created in the staging
directory when
make installruns withDESTDIR, so the Debian package contains it; the package installs under/opt/nikos, links the tools into/usr/binand depends onclang-20andllvm-20; the continuous integration builds, checks and publishes it for tagged releases;script/install.shinstalls the latest release on Ubuntu 24.04; the Docker image builds again (LLVM apt repository in both stages,python3-venv); versions taken from the project version; RPM file list matches the install tree; LLVM apt repository key handled withoutapt-key.
uafis no longer part of the default analyses of theikosdriver (boaalready reports use after free and use after return).fastapianduvicornare optional (pip install ikos[serve]);nikos-bridgesummarizes a SARIF report and no longer modifies sources.- Removed the IKOS 3.0 installation guides, the old distribution Dockerfiles,
script/bootstrap, the duplicatedtest/taintdirectory and the tracked build artifacts. - Documentation rewritten to match the tools.
- AR type verifier: bitcasts between structurally identical struct types, which the importer produces with LLVM 20 opaque pointers, are accepted.
Fixes failing CI jobs on Linux and macOS caused by an outdated pip module update behavior and an incorrect path to taint_config.json.
- pip install command in CMake — Unified the installation command
pip install -U pip setuptools wheel pygmentsto resolveModuleNotFoundError: No module named 'pip._internal.operations.build'. taint_config.jsoninstallation path — Fixed CMake install command to point correctly to"${CMAKE_CURRENT_SOURCE_DIR}/taint_config.json".
2.3.1 — 2026-06-16
Fixes all remaining LLVM 20 AR output mismatches across the full import regression test suite. Adds developer tooling and documentation for future LLVM upgrades.
-
Complete LLVM 20 regression test suite — all 162 non-skipped tests now pass across
no_optimization,basic_optimization, andaggressive_optimizationsuites (previously 40+ tests failing). Root cause was that CHECK lines were written against LLVM 14 AR output; the localikos-importbinary was LLVM 14 while CI used LLVM 20. -
no_optimization/— 37 files updated: concrete scalar alloca types (allocate opaque→allocate si32/float/etc.), bitcast elimination cascades, struct layout resolution, SSA variable renumbering. -
basic_optimization/— 3 files updated: bitfield signedness (ui16→si16), struct alloca type resolution, PHI node renumbering. -
aggressive_optimization/— 1 file updated: vtable bitcast chain.
-
script/regen_checks.py— tool to auto-regenerate; CHECK:lines in.lltest files from actualikos-importoutput. Eliminates error-prone hand-editing after LLVM upgrades. Supports--batch,--failing-only,--diff, and--dry-runmodes. -
doc/LLVM20_AR_CHANGES.md— reference guide documenting every way the AR output changed between LLVM 14 and LLVM 20: concrete alloca types, struct field layout resolution, selective bitcast elimination rules, return value bitcast chain expansion, constructor delegation behavior, SSA renumbering cascades, and integer signedness changes. Includes local testing instructions and a troubleshooting checklist. -
README "Working with the Test Suite" section — links to
LLVM20_AR_CHANGES.md, showsregen_checks.pyusage, and explains how to run the suite locally with the correct LLVM version.
2.3.0 — 2026-06-15
Third milestone in the 2.x security analysis series. Broadens taint source coverage to network and standard I/O, ships built-in vulnerability profiles, enhances diagnostic output with source-attribution labels, and grows the taint regression suite from 10 to 14 tests.
-
Expanded taint sources —
recv,recvfrom,recvmsg(network I/O);fgets,fgetc,getchar,getline,scanf,fscanf,sscanf,read(standard I/O) registered as taint sources intaint_config.json. -
New taint sinks — exec family:
execl,execlp,execle,execv,execve,execvp(CommandInjection); filesystem:openat,unlink,rename,remove(PathTraversal);syslog(FormatString). -
Path sanitizers —
realpathandbasenameadded tosanitizerslist intaint_config.json, clearing path traversal taint when data passes through canonical path resolution. -
profiles/posix.json— new built-in profile targeting POSIX command/path injection and format string vulnerabilities; no SQL sinks. -
Updated
profiles/web.json— added network I/O sources (recv,recvfrom,fgets,read) andrealpathsanitizer. -
Updated
profiles/sql.json— added PostgreSQL sanitizers (PQescapeStringConn,PQescapeLiteral) alongside existing MySQL/SQLite ones; broadened sources to include network and file I/O. -
Verbosity-2 taint source labels in
ikos-report— at-v 2, taint findings now include(source: <name>)attribution drawn from thetaint_sourcesprovenance key stored in the check info dict. New helper_taint_source_suffix()inreport.py. -
4 new regression tests (total: 14):
recv_source.c— network socket data →system()(CommandInjection)fgets_source.c— stdin input →fopen()(PathTraversal)realpath_sanitizer.c—fgets→realpath()→fopen()(safe)snprintf_sink.c—getenv()→snprintf()→system()(CommandInjection)
KeyError: 53inikos-report— the system-installedenums.pyat/usr/local/libexec/lib/python3.12/site-packages/ikos/was the old upstream IKOS version, missing all 2.xCheckKindadditions (USE_AFTER_FREE,USE_AFTER_RETURN,DATA_RACE,DEADLOCK,COMMAND_INJECTION,PATH_TRAVERSAL,FORMAT_STRING,SQL_INJECTION). Deployed updatedenums.pyand all other modified Python files to both install targets.
2.2.0 — 2026-06-15
See RELEASE_2.2.0.md for full details. Highlights:
- Lockset analysis checker (
-a concurrency) withpthread_mutex_lock/unlock CheckKind::DATA_RACEandCheckKind::DEADLOCK- 3 regression tests (mutex_safe, data_race, deadlock)
2.1.0 — 2026-06-15
See RELEASE_2.1.0.md for full details. Highlights:
CheckKind::USE_AFTER_FREE,USE_AFTER_RETURN,USE_AFTER_MOVECheckerName::UAF,UAM- Lifetime tracking improvements
Post-release patch addressing build failures discovered when CI ran against current toolchain versions (CMake 4.3.3, AppleClang 17, Homebrew Boost 1.90). No functional changes to the analyzer itself.
-
CMake 4.x compatibility — bumped
cmake_minimum_requiredfrom3.4.3to3.14in all four sub-projectCMakeLists.txtfiles (core/,ar/,frontend/llvm/,analyzer/) and inanalyzer/python/settings.cmake.in. CMake 4.3.3 removed support forVERSION < 3.5entirely. -
Boost 1.90
boost_systemremoved —boost_systembecame header-only in Boost 1.69 and is no longer a findable library component in Boost's ownBoostConfig.cmake(shipped by Homebrew since 1.86). RemovedsystemfromCOMPONENTSinfrontend/llvm/CMakeLists.txtandanalyzer/CMakeLists.txt. -
Deprecated
FindPythonInterp— replaced withfind_package(Python3 COMPONENTS Interpreter)inanalyzer/CMakeLists.txt.FindPythonInterpwas deprecated in CMake 3.12 and removed in CMake 3.27+. -
wpo.hppmember name typo —WpoNode::is_successor_lifted()referencedthis->_successor_lifted(non-existent); corrected to_successors_lifted. Latent bug from upstream IKOS; GCC silently accepts it via lazy template instantiation but AppleClang 17 hard-rejects it. Reported upstream as NASA-SW-VnV/ikos#336. -
gauge.hppoperator=(Number)member name typo —GaugeBound::operator=assigned tothis->_n(non-existent); corrected tothis->_cst. Equivalent to upstream fix in NASA-SW-VnV/ikos#332 which merged after our fork point. -
CI workflows —
ikos --versionverification step replaced withikos-analyzer --help(the Python wrapper's shebang is baked to the install-time prefix and is not portable across CI runners). Added explicitmake build-*-testsstep beforectestsince test targets areEXCLUDE_FROM_ALL.
NIKOS is now officially v1.0.0 — Production Ready. This release delivers a complete documentation overhaul and multiple distribution methods so NIKOS can be installed with a single command on any supported platform.
-
script/install.sh— self-contained Bash install script:- Detects Ubuntu 22.04 / 24.04; installs LLVM 20 via
apt.llvm.org - Builds from source with CMake; installs to
~/.local/nikos(configurable) --with-apronflag: clones, builds, and links APRON automatically--prefix,--jobs,--apron-prefixoptions; idempotent (safe to re-run)
- Detects Ubuntu 22.04 / 24.04; installs LLVM 20 via
-
Debian package (
packaging/deb/) —nikos_1.0.0_amd64.deb:- 17 MB self-contained package with all runtime binaries
- Built via
packaging/deb/build.sh; installs withdpkg -i
-
RPM spec (
packaging/rpm/nikos.spec) — Fedora/RHEL RPM:- Standard
%prep/%build/%install/%filesspec for Fedora 40+ packaging/rpm/README.mdwith build instructions and Docker workaround for Ubuntu
- Standard
-
Docker image (
Dockerfile) — multi-stage build:- Stage 1 (
builder): Ubuntu 24.04 + LLVM 20 + full build - Stage 2 (
runtime): minimal Ubuntu 24.04 with install tree only docker/docker-compose.ymlfor conveniencedoc/DOCKER.mdwith CI integration guide
- Stage 1 (
-
Flatpak manifest (
packaging/flatpak/com.alternativeintelligence.nikos.yml):- Uses
org.freedesktop.Sdk.Extension.llvm20(no LLVM source build) org.freedesktop.Platform24.08 runtime
- Uses
-
doc/USAGE.md— comprehensive walkthrough guide:- Full pipeline tutorial (clone → build → analyze → interpret results)
- All 16 checker IDs with use-case guidance
- Abstract domain selection guide with decision table
- SQLite output schema and example SQL queries
- GitHub Actions CI integration snippet
- Appendices: pipeline diagram, domain compatibility matrix, troubleshooting
-
doc/install/1.0/— fresh installation guides replacing the stale upstream IKOS 3.0 guides:UBUNTU_22.04.md— primary supported platformUBUNTU_24.04.md— notes on LLVM 17 default; LLVM apt repo requiredAPRON.md— deep-dive APRON source build guide (Makefile.config, OCaml skip, manual install, known issues)
CMakeLists.txt: projectVERSIONbumped from0.6.0to1.0.0TROUBLESHOOTING.md: converted from plain text to Markdown; added LLVM 20 error table, APRON-specific issues section, fortification note, and false-positive guidanceCONTRIBUTING.md:make check→ctest; addedLLVM_CONFIG_EXECUTABLEto cmake invocationdoc/OVERVIEW.md: fully rewritten for v1.0.0 — updated directory tree, expanded architecture diagram, abstract domains table, key components sectiondoc/CODING_STANDARDS.md: reviewed, accurate as-is
Closes the v0.13 series. Verifies the APRON domains work correctly from the installed binary tree, and confirms all 64 regression tests pass end-to-end.
- Install verification (NAP-022):
ikos-analyzerbuilt against the install prefix correctly detects bugs withapron-octagon(noLD_LIBRARY_PATHrequired — APRON is statically linked). - 64/64 tests passing — full suite passes in 28 seconds with APRON enabled.
- Precision benchmark documented —
APRON_PRECISION_BENCHMARK.mdrecords interval vs apron-octagon comparison across 6 analysis suites (255 tests).
This release adds optional support for the APRON numerical abstract domain library, enabling 13 additional analysis domains with stronger relational reasoning capabilities.
-
APRON integration —
cmake/FindAPRON.cmakeupdated with:APRON_ITV_LIB(libitvMPQ) added to required libraries (needed bylibap_pplandlibap_pkgridat link time — missing from original find module).-Wl,--start-group/-Wl,--end-grouplinker groups to resolve circular dependencies between APRON domain libs andlibaproncore (static linking).- Domain libraries reordered: consumers (
box,oct,polka,ppl,pkgrid) beforelibaproncore.
-
13 APRON abstract domains — all verified functional:
- Base:
apron-interval,apron-octagon,apron-polka-polyhedra,apron-polka-linear-equalities,apron-ppl-polyhedra,apron-ppl-linear-congruences,apron-pkgrid-polyhedra-lin-cong - Variable-packing variants:
var-pack-apron-{octagon,polka-polyhedra, polka-linear-equalities,ppl-polyhedra,ppl-linear-congruences, pkgrid-polyhedra-lin-cong}
- Base:
-
APRON regression test suite (
analyzer/test/regression/apron/) — 4 tests:- Safe loop with
apron-octagon(BOA smoke test) - Buffer overflow detection with
apron-octagon(BOA error test) - Interprocedural safe loop with
var-pack-apron-octagon - Null dereference detection with
apron-octagon(nullity checker)
- Safe loop with
-
--domainCLI override inlibruntest.py— run the full regression suite with any abstract domain viapython3 runtest --domain apron-octagon. -
Precision benchmark —
apron-octagonpasses 251/255 regression tests with 138PASS_IMPROVEresults (stronger precision than defaultinterval). 4 false positives on tests designed forinterval-congruence/gaugedomains.
- APRON is an optional dependency. NIKOS builds without it; APRON support
activates automatically when
-DAPRON_ROOT=/path/to/apron/installis passed. - APRON must be built from source (
antoinemine/apron) — not available via apt. - Build with C API only (
HAS_OCAML=;HAS_OCAMLOPT=). OCaml bindings requiremlgmpidland are not needed by NIKOS. - APRON libs are statically linked — no
LD_LIBRARY_PATHrequired.
- 64/64 tests passing (59 existing + 4 APRON core unit tests + 1 APRON regression suite)
0.12.0 — 2026-06-14
This release marks NIKOS as production-ready with full LLVM 20 support.
--opt=custommode restored forikos-pp— supports--lower-select,--lower-cst-expr,--remove-printf-calls,--remove-unreachable-blocks,--name-values, and--mark-internal-inlineflags.- Opaque pointer tolerance mode in test framework —
OPAQUE_PTR_TOLERANCEinlibruntest.pytreats precision losses from opaque pointers asPASS_IMPROVEinstead ofFAIL.
- VLA (variable-length array) crash —
translate_array_di_typeintype.cppnow handlesDISubrangewithDIVariablecount (LLVM 20 VLA representation) instead of crashing intranslate_basic_di_type. - Array allocation type mismatch —
infer_type_from_dbginfunction.cppnow always catchesTypeDebugInfoMismatchfor dynamic allocas, regardless of_allow_debug_info_mismatchsetting. - Opaque pointer type checker —
ar::TypeVerifierrelaxed to allow:- Bitcasts involving opaque types
- Load/store through opaque pointers
{opaque*, si32}as exception structure (LLVM 20__cxa_throw)- Implicit bitcasts with opaque types in function call parameters
- Import test patterns — regenerated 171
.llFileCheck patterns acrossno_optimization,basic_optimization, andaggressive_optimizationfor LLVM 20's opaque pointer AR output. Reduced import skip lists from 9/6/3 to 3/3/2 files.
- Test harness —
libruntest.pycatchesCalledProcessErrorfrom analyzer crashes, reporting them asFAILinstead of aborting the suite.
- Stale
.orig/.rejpatch artifacts, debug GDB scripts, and build logs.
0.6.1 — 2026-06-14
-
llvm::Optional→std::optionalmigration across all 27 checker files (includes and implementations).llvm::Optionalwas removed in LLVM 17; the replacement isstd::optional/std::nulloptfrom C++17. Affected files:checker.hpp,buffer_overflow,checker,null_dereference,concurrent_inliner,double_free, and all remaining checker headers/sources. -
Missing transitively-included headers in
analyzer/src/database/table/operands.cpp. LLVM 20 tightened header hygiene — four headers previously pulled in transitively are now required explicitly:llvm/ADT/SmallString.h— forAPInt::toString(SmallVectorImpl<char>&)llvm/BinaryFormat/Dwarf.h— fordwarf::DW_TAG_*constantsllvm/IR/GetElementPtrTypeIterator.h— forgep_type_begin/gep_type_endllvm/IR/GlobalAlias.h— for completeGlobalAliastype (enables.getAliasee())
Without these,
ikos-analyzerfailed to compile with errors likeno member named 'DW_TAG_typedef' in namespace 'llvm::dwarf'andmember access into incomplete type 'llvm::GlobalAlias'.
0.6.0 — 2026-06-14
ikos-ppfully ported to LLVM 20 with hybrid legacy/new PassManager.preprocess_module()inNikosBridge::import()— runs 5 mandatory lowering passes before AR import (LowerSwitch, LowerAtomic, LowerCstExpr, LowerSelect, UnifyFunctionExitNodes).libikos-pp.anow linked into Nitpick for IKOS-specific pass access.
- 7 LLVM passes migrated from removed legacy API to new PassInfoMixin:
GlobalDCEPass,GlobalOptPass,InternalizePass,JumpThreadingPass,SCCPPass,LoopDeletionPass,UnifyFunctionExitNodesPass. - Removed 11 dead
initializeXxxPass()calls for passes removed in LLVM 20. frontend/llvm/CMakeLists.txt: addedpassesLLVM component for PassBuilder.
NikosBridge::import()now handlesselect,switch, atomic, and constant expression instructions (previously threwImportError).ikos-ppbinary now compiles on LLVM 20 (was broken with 25+ errors).
0.5.1 — 2026-06-14
NikosWarningPromoterclass for automated Z3 SMT query generation from IKOS warnings.- SMT-LIB2 query templates for 7 check kinds:
- Null dereference (
QF_BV) - Division by zero (
QF_LIA) - Buffer overflow (
QF_LIA) - Signed integer overflow (
QF_BV) - Unsigned integer overflow (
QF_BV) - Shift count (
QF_LIA) - Pointer overflow (
QF_BV)
- Null dereference (
WarningPromotionoutcomes:PromotedToError(SAT),DismissedAsSafe(UNSAT),Unchanged,NotApplicable.WarningPromotionReportwith text formatting.- Direct use of Z3 C API (
Z3_eval_smtlib2_string).
0.5.0 — 2026-06-14
NikosAnalysisRunner: subprocess driver forikos-analyzer.NikosCrossValidator: matches IKOS checks against Z3 findings by location and category.CrossValidationReportwith verdicts:Confirmed,Dismissed,IkosOnly,Z3Only,Inconclusive.NikosBridge::analyze()andcan_analyze()methods.- Binary discovery:
NIKOS_ANALYZER_PATHenv var, sibling directory,PATH.
0.4.2 — 2026-06-14
NikosReportwith per-function metrics (name, params, locals, basic blocks, statements).to_text()formatter with Unicode box-drawing table.to_json()formatter for SARIF/tooling integration.NikosBridge::report()method.
0.4.1 — 2026-06-14
- Verified
NikosBridge::import(llvm::Module&)fulfills in-memory ingestion requirement.
0.4.0 — 2026-06-13
NikosBridgeclass with PIMPL pattern for clean API boundary.NikosBridge::import(llvm::Module&)for LLVM module to AR bundle translation.- Linked
libikos-ar.aandlibikos-llvm-to-ar.ainto Nitpick'snpkcbinary. - 82 NIKOS symbols initially linked.
0.3.1 — 2026-06-13
- Type translation for LLVM 20's opaque pointer migration.
- Aggregate type (struct/array) translation.
- Ensured AR types faithfully represent LLVM IR semantics.
0.3.0 — 2026-06-13
- Audited all AR (Abstract Representation) factory methods for LLVM 20 compatibility.
- Bundle creation, function signatures, and basic block construction.
- Statement translation (assignments, assertions, calls).
0.2.3 — 2026-06-12
- Completed LLVM frontend compilation with LLVM 20.
ikos-pp(preprocessor) andikos-importfor opaque pointers.- LLVM PassManager API changes.
0.2.2 — 2026-06-12
- All compilation errors in the AR (Abstract Representation) library.
- Type system updated for LLVM 20 changes.
0.2.1 — 2026-06-12
- All compilation errors in the core abstract interpretation library.
- Abstract domains and fixpoint iterators updated for C++17.
0.2.0 — 2026-06-12
- Forked from NASA-SW-VnV/ikos (LLVM 14).
- Initial compilation fixes across all components.
- Updated CMake to find LLVM 20.
- C++ standard from C++14 to C++17.