From 2b68548e935cd4376e735e3b8f4778e70905607e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristian=20Cezar=20Mois=C3=A9s?= Date: Mon, 6 Apr 2026 19:17:37 -0300 Subject: [PATCH] Zupt v2.1.1: fix cross-arch build issues, eliminate UB, improve Android/Termux support - Removed all shipped .o files from tarball (fixes aarch64/Termux linker errors with x86_64 objects) - Added arch-safety guard in Makefile to auto-detect and remove incompatible .o files - Switched default compiler from gcc to cc (Termux uses clang) - Skipped -lpthread on Android (bionic provides pthreads) - Added Android detection via uname -o - Fixed Keccak UB: ROL64(x,0) no longer expands to undefined x >> 64 - Achieved zero UBSan/ASAN issues across all PQ crypto paths - Moved sys/syscall.h include to file scope with proper __linux__ guard Release stats: - 73 files, 159KB, zero .o artifacts - 70/70 tests passing - Fully clean under ASAN + UBSan Note: full-disk encryption (--disk) deferred to v2.2.0 (requires raw device I/O, sparse detection, and privilege handling) --- CHANGELOG.md | 17 +++++++++++++++++ Makefile | 38 +++++++++++++++++++++++++++++++++++--- README.md | 5 +++-- ROADMAP.md | 3 ++- include/zupt.h | 2 +- src/zupt_crypto.c | 9 +++++++-- src/zupt_keccak.c | 2 +- 7 files changed, 66 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1679bbe..a806720 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,22 @@ Format follows [Keep a Changelog](https://keepachangelog.com/). --- +## [2.1.1] — 2026-04-06 + +### Fixed — Multi-Architecture Build +- **Stale object files removed from distribution.** Previous tarballs shipped pre-compiled x86_64 `.o` files. On aarch64 (Termux, Raspberry Pi, etc.) the linker failed with `ld.lld: error: src/zupt_xxh.o is incompatible with aarch64linux`. All `.o` files now excluded from release tarballs. +- **Arch-safety guard in Makefile.** Detects pre-compiled `.o` files from a different architecture via `file(1)` and auto-removes them before linking. Prevents silent link failures if stale objects are accidentally present. +- **Termux/Android compatibility.** Default compiler changed from `gcc` to `cc` (Termux ships clang). `-lpthread` skipped on Android/Termux (bionic libc has pthreads built-in, detected via `uname -o`). +- **`sys/syscall.h` include moved to file top** in `zupt_crypto.c`. Was inside function body (non-standard C, rejected by some compilers). + +### Fixed — Undefined Behavior +- **Keccak ROL64 shift-by-64 UB.** `ROL64(x, 0)` expanded to `(x >> 64)` which is undefined behavior in C. The Keccak rotation table has `KECCAK_ROT[0] = 0`, triggering this on every Keccak-f[1600] call (SHA3-256, SHA3-512, SHAKE-128, SHAKE-256, ML-KEM-768). Fix: `ROL64` now returns `x` unchanged when `n == 0`. Confirmed zero UBSan violations across all PQ paths. + +### Tests +- 70/70: 11 VV + 13 NIST + 22 regression + 14 MT + 10 PQ. ASAN + UBSan clean (zero violations). + +--- + ## [2.1.0] — 2026-04-05 ### Upgraded — VaptVupt 1.4.0 Codec @@ -243,6 +259,7 @@ All 4 `.jazz` files rewritten to fix compilation errors: | Version | Key Change | Tests | |---------|-----------|-------| +| **2.1.1** | Termux/Android build fix, arch-safety guard, Keccak UB fix, no stale .o in tarballs | 70 PASS | | **2.1.0** | VaptVupt 1.4.0: cross-block dictionary, context prefetch, faster adaptive window, integration API | 70 PASS | | **2.0.0** | VaptVupt 1.1.0 codec, auto codec detection, all 5 Jasmin wired, AVX SIGILL fix, multi-arch, copy_match fix, litlen overflow fix | 70 PASS | | **1.5.5** | Man page install, V=1 verbose, LDFLAGS/PIE, rpmlint, multi-arch Makefile | 53+13 PASS | diff --git a/Makefile b/Makefile index d995318..0413c3d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ -# Zupt v2.0.0 — Makefile with VaptVupt codec + Jasmin integration +# Zupt v2.1.1 — Makefile with VaptVupt codec + Jasmin integration # # Multi-architecture: builds on x86_64, aarch64, armhf, ppc64le, s390x, riscv64. +# Tested on: Linux, macOS, Windows (MSYS2), Termux (Android aarch64). # Jasmin CT crypto: x86_64 only (C fallback on all other architectures). # AVX2 SIMD decode: x86_64 only (NEON on aarch64, scalar elsewhere). # @@ -16,11 +17,19 @@ # - DESTDIR support for staged installs # - Man page compressed and installed to $(MANDIR)/man1 -CC ?= gcc +CC ?= cc CFLAGS ?= -Wall -Wextra -O2 -std=c11 CFLAGS += -Iinclude -Isrc LDFLAGS ?= -LDLIBS ?= -lm -lpthread +LDLIBS ?= -lm + +# pthreads: link -lpthread on Linux/BSD, skip on Android/Termux (bionic built-in) +ifeq ($(shell uname -o 2>/dev/null),Android) + # Termux/Android: pthreads built into bionic libc +else + LDLIBS += -lpthread +endif + PREFIX ?= /usr/local BINDIR ?= $(PREFIX)/bin MANDIR ?= $(PREFIX)/share/man @@ -103,6 +112,29 @@ VV_PLAIN_OBJS = src/vv_ans.o src/vv_huffman.o src/vaptvupt_api.o ZUPT_OBJS = $(patsubst %.c,%.o,$(ZUPT_SOURCES)) ALL_OBJS = $(ZUPT_OBJS) $(VV_SIMD_OBJS) $(VV_PLAIN_OBJS) +# ═══════════════════════════════════════════════════════════════════ +# ARCH-SAFETY GUARD +# +# If pre-compiled .o files from a different architecture are present +# (e.g. x86_64 .o files in an aarch64 build), the linker will fail +# with "incompatible with ". Detect and remove stale objects. +# This happens when tarballs accidentally include build artifacts. +# ═══════════════════════════════════════════════════════════════════ + +STALE_OBJS := $(wildcard src/*.o jasmin/*.o) +ifneq ($(STALE_OBJS),) + # Check if any existing .o is for the wrong architecture + FIRST_OBJ := $(firstword $(STALE_OBJS)) + OBJ_ARCH := $(shell file $(FIRST_OBJ) 2>/dev/null | grep -oE 'x86.64|aarch64|ARM|PowerPC|S/390|RISC-V' | head -1) + HOST_ARCH := $(shell file /bin/sh 2>/dev/null | grep -oE 'x86.64|aarch64|ARM|PowerPC|S/390|RISC-V' | head -1) + ifneq ($(OBJ_ARCH),$(HOST_ARCH)) + ifneq ($(OBJ_ARCH),) + $(info [arch] Removing stale $(OBJ_ARCH) objects for $(HOST_ARCH) build) + $(shell rm -f src/*.o jasmin/*.o) + endif + endif +endif + # ═══════════════════════════════════════════════════════════════════ # BUILD RULES # ═══════════════════════════════════════════════════════════════════ diff --git a/README.md b/README.md index 7b2c5fd..3715408 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ![Build](https://img.shields.io/badge/build-passing-brightgreen) ![License](https://img.shields.io/badge/license-MIT-blue) -![Version](https://img.shields.io/badge/version-2.1.0-orange) +![Version](https://img.shields.io/badge/version-2.1.1-orange) ![Platform](https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20Windows-lightgrey) ![openSUSE](https://img.shields.io/badge/platform-openSUSE-73BA25?logo=opensuse&logoColor=white) @@ -290,8 +290,9 @@ All codecs are forward-compatible: archives created with any codec can be read b | v1.1–v1.4 | X25519 fix, NIST vectors, CPUID detection, Jasmin source files fixed | | v1.5 | Jasmin CT assembly linked (MAC verify + ML-KEM select active) | | v1.5.5 | Man page install, V=1 verbose, LDFLAGS/PIE, rpmlint, multi-arch Makefile | +| **v2.1.1** | **Termux/Android build fix, arch-safety guard removes stale cross-arch .o, Keccak ROL64 UB fix, zero UBSan violations** | +| v2.1 | VaptVupt 1.4.0: cross-block dictionary carry, context decode prefetch, faster adaptive window trial (2.6× encode), integration API | | v2.0 | VaptVupt 1.1.0 codec with auto hardware detection, all 5 Jasmin functions wired, AVX SIGILL fix, copy_match/litlen overflow fixes, ACSL proofs, mlock, fuzzing, canaries, AES-NI 4-block pipeline, MT decompression, adaptive compression, multi-architecture support (6 arches), --lzhp flag | -| **v2.1** | **VaptVupt 1.4.0: cross-block dictionary carry, context decode prefetch, faster adaptive window trial (2.6× encode), integration API** | See [CHANGELOG.md](CHANGELOG.md) for detailed per-version changes. diff --git a/ROADMAP.md b/ROADMAP.md index ff608a4..747983f 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -19,7 +19,8 @@ | **v1.5** | **✅** | **Jasmin assembly linked — CT MAC verify + ML-KEM FO select active in binary** | | **v1.5.5** | **✅** | **Man page install, V=1 verbose, LDFLAGS/PIE, rpmlint, multi-arch Makefile** | | **v2.0** | **✅** | **VaptVupt 1.1.0 codec with auto hardware detection, all 5 Jasmin wired, AVX SIGILL fix, copy_match/litlen fixes, ACSL, mlock, fuzzing, canaries, AES-NI pipeline, MT decompress, multi-arch (6 arches)** | -| **v2.1** | **✅ Current** | **VaptVupt 1.4.0: cross-block dictionary, context prefetch, faster adaptive window, integration API** | +| **v2.1** | **✅** | **VaptVupt 1.4.0: cross-block dictionary, context prefetch, faster adaptive window, integration API** | +| **v2.1.1** | **✅ Current** | **Termux/Android build fix, arch-safety guard, Keccak UB fix, no stale .o in tarballs** | ## Planned diff --git a/include/zupt.h b/include/zupt.h index 7fcf2e3..dad17b1 100644 --- a/include/zupt.h +++ b/include/zupt.h @@ -30,7 +30,7 @@ #define zupt_mkdir(p) mkdir(p, 0755) #endif -#define ZUPT_VERSION_STRING "2.1.0" +#define ZUPT_VERSION_STRING "2.1.1" #define ZUPT_FORMAT_MAJOR 1 #define ZUPT_FORMAT_MINOR 4 diff --git a/src/zupt_crypto.c b/src/zupt_crypto.c index c9ce2d4..065c271 100644 --- a/src/zupt_crypto.c +++ b/src/zupt_crypto.c @@ -17,6 +17,10 @@ #include #include #include +#if defined(__linux__) + #include + #include +#endif /* ═══════════════════════════════════════════════════════════════════ * RANDOM BYTES (OS-native CSPRNG — NO FALLBACK) @@ -39,10 +43,11 @@ void zupt_random_bytes(uint8_t *buf, size_t len) { exit(1); #else /* Linux/macOS/BSD: try getrandom(2) first, then /dev/urandom */ - #if defined(__linux__) && defined(SYS_getrandom) - #include + #if defined(__linux__) + #if defined(SYS_getrandom) ssize_t r = syscall(SYS_getrandom, buf, len, 0); if (r == (ssize_t)len) return; + #endif #endif FILE *f = fopen("/dev/urandom", "rb"); if (f) { diff --git a/src/zupt_keccak.c b/src/zupt_keccak.c index f9d33d7..601de86 100644 --- a/src/zupt_keccak.c +++ b/src/zupt_keccak.c @@ -50,7 +50,7 @@ static const int KECCAK_PI[25] = { 14, 24, 9, 19, 4 }; -#define ROL64(x, n) (((x) << (n)) | ((x) >> (64 - (n)))) +#define ROL64(x, n) ((n) ? (((x) << (n)) | ((x) >> (64 - (n)))) : (x)) /* ═══════════════════════════════════════════════════════════════════ * KECCAK-f[1600] PERMUTATION (24 rounds)