You do not have permission to delete messages in this group
Copy link
Report message
Show original message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to tinymux
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512
Subject: [ANNOUNCE] TinyMUX 2.14.0.8 ALPHA released
TinyMUX 2.14.0.8 ALPHA is now available. This release pairs a broad security and correctness pass with several larger features: a unified date/time parser, a tiered storage cache with speculative prefetch, a substantial hardening and expansion of the GANL networking stack, and continued JIT/interpreter parity work.
The security and correctness pass covers the softcode evaluator, the JIT/DBT pipeline, the @lock and command parsers, the database loaders, and the player-authentication, comsys, and @mail subsystems. Several fixes close player-reachable crashes and denial-of-service conditions; others close out-of-bounds reads/writes that could be triggered by a corrupt, migrated, or maliciously crafted database file. Affected sites are tracked in docs/survey-*.md.
Changes since 2.14.0.7 ALPHA - ------------------------------
New Functions:
- - vwidth() returns the visible display width of a string, accounting for color codes and wide/zero-width characters (the column count wrap() and the alignment functions actually use). - - cachestats() reports attribute-cache statistics (size, hit/miss counts, queue depth) for tuning the tiered storage cache.
Date and Time:
- - ParseDate has been replaced by a unified Ragel scanner feeding a recursive-descent parser, giving consistent handling of the many accepted date/time formats (convtime(), @convtime, and friends). - - Out-of-range years are now rejected rather than silently wrapped, and do_convtime no longer overflows on extreme year values. (#715) - - A size_t truncation that could make ParseDate fail outright was fixed, and a native fuzz/boundary harness was added.
Tiered Storage and Caching:
- - Stage 1 of the tiered storage cache: a configurable in-RAM attribute cache with a tunable size and depth-preload, in front of the SQLite backend. - - Object-affinity speculative prefetch on a cache miss warms related attributes before they are asked for. - - A write-behind cache with pinning and tombstones, plus batched, demand-driven SQLite writes, removes per-operation write latency from the hot path; cachestats() exposes the counters.
Security and Robustness:
- - Integer division/remainder of the most-negative 64-bit value by -1 (idiv/mod/remainder/floordiv), and division by zero, no longer raise SIGFPE and crash the server. Both the interpreter and the JIT-compiled fast paths are guarded. This was a player-reachable denial-of-service. (#805, #811) - - A deeply nested @lock key (for example, several hundred '!' operators) no longer overflows the C stack and crashes the server. The lock parser now bounds its recursion depth, and its scratch buffer is no longer stack-allocated. Any player able to @lock an object they own could trigger this. (#839) - - The flatfile and SQLite database loaders now validate the dbrefs, attribute numbers, message numbers, and lock expressions they read. A corrupt or crafted database can no longer drive an out-of-bounds write, an out-of-bounds read, an unbounded recursion, or a runaway allocation while loading objects, attributes, locks, @mail, or comsys channels. (#806, #807, #808, #810, #841, #843) - - Logging in as a player whose stored password uses a hash method the local C library's crypt() cannot compute (for example, a $6$ SHA-512 password database moved to a platform without it) no longer crashes the server; authentication now fails closed. (#842) - - The JIT translator's instruction-emit, code-cache reconstruction, and Lua-bytecode paths now bound every buffer write and index, closing several out-of-bounds writes/reads reachable under code-buffer pressure or from a malformed compiled-code cache entry. (#830, #831, #832, #833) - - The softcode expression ([...]) parser now caps its recursion depth, matching the evaluator, so pathologically nested input cannot overflow the stack on platforms with a small default stack size. (#840) - - justify() no longer reserves a ~1.25 MB stack frame. (#818)
JIT / DBT Engine:
- - Numerous JIT-vs-interpreter result divergences were corrected so that JIT-compiled softcode produces byte-identical results to the interpreter: folds of t()/not() on fractional-zero and whitespace inputs (#824); folds of bound() and comp() (#824); float results fed into integer operations no longer truncate (#826); trunc() rounds toward zero (#827); mod() of negative operands is floor-mod (#828); and float add()/sub() use the same error-compensated summation as the interpreter (#829). - - Tier-2 "blob" math now matches the interpreter for list reductions, lnum()/space() edge cases, and ladd(); isdbref() is handled by the engine; and ladd() is re-enabled with full parity. (#812, #813, #814, #815) - - The DBT now reclaims its x86-64 translation buffer when it nears full, so a long-running server no longer silently degrades JIT-compiled attributes back to the interpreter. (#834) - - AArch64 DBT code generation fixes for zero-base LOAD/STORE, scratch-register clobbers, an inverted conditional-select, and division by zero. (#804, #809) (AArch64 is a non-default backend.) - - More functions now run in JIT-compiled code with verified interpreter parity: ldelete() and wordpos() are re-enabled in Tier 2 with correct semantics (#768); ulambda() bodies are routed through the evaluator so they compile (#718); and runtime-argument floating-point arithmetic is handled via the Tier-2 blob (#778). - - Further divergences were closed: pos() returns #-1 (not 0) when the substring is not found (#770); ljust()/rjust()/center() truncate when the width is smaller than the content (#772); multi-character delim/osep arguments fall back to the interpreter where they were mishandled (#768, #782); empty list elements now survive split_token (#789); and COLOR-encoded output is byte-exact against the interpreter (#785, #787). - - The JIT now reclaims its per-VM code arena on recompile instead of leaking it, keeps its arena registry and cursor thread-local, and tightens ECALL context isolation. DBT JIT is now enabled on Apple Silicon (arm64 macOS).
Wildcard and String Matching:
- - '?' in a wildcard pattern now matches one whole UTF-8 character rather than one byte, so strmatch(caf<e9>,????) matches as expected. (#835) - - Case-insensitive wildcard matching now folds non-ASCII letters from either side, in both the non-capturing matcher (strmatch, name/attribute/channel matching) and the capturing matcher used by $-commands and ^-listens, while preserving original-case captures. (#836, #837) - - A '?' immediately following a '*' no longer splits a multi-byte character across capture registers. (#838) - - accent() with the E/e plus macron form now returns the correct character. (#816)
Networking:
This release brings a large hardening pass over the GANL networking stack and the telnet/WebSocket/DNS protocol surface.
- - Site-ban bypass fixes: IPv4-mapped IPv6 source addresses are now canonicalized before site-rule matching, and subnet containment with a shared base/end address is computed correctly, so an IPv6-presented client can no longer slip past an IPv4 site ban. (#799, #800) - - The epoll engine now handles the epoll_wait() error path (EINTR retry; real errors surfaced) instead of spinning. (#791) - - Reverse-DNS hostnames from the resolver slave are sanitized, the slave protocol buffers are bounded, and a purely numeric address can no longer pose as a resolved hostname. (#801) - - The connection-handle-to-descriptor narrowing is guarded against truncation (#790), the descriptor re-entrancy guard is now state-based (#802), and DESC teardown paths are hardened against stale handle mappings. - - WebSocket: RFC 6455 conformance hardening (CLOSE/fragment/RSV/ UTF-8/64-bit length/control-frame rules); a zero-payload frame ending exactly at a read boundary is now dispatched; the handshake flag is cleared before processing; and a Windows-IOCP double-free of per-I/O data on an immediate WSASend/WSARecv failure is fixed. (#792, #796) - - Telnet: an IAC-encoding buffer overflow is fixed, the subnegotiation buffer is decoupled from SBUF_SIZE, parser limits are bounded, and descriptor field copies are clamped. A one-byte stack overflow in the slave.cpp query buffer, and overflow/shift/ digit-offset bugs in the DecodeN IPv4 parser, are fixed. - - New negotiation support: configurable STARTTLS offers, NEW-ENVIRON parsing, CHARSET REQUEST list parsing, ANSI/MXP capability handling, and an OpenSSL key-password callback; an SSL session use-after-free and an unhandled read() EOF are fixed. (#793, #797, #803) - - The sqlslave helper now surfaces connection/query failures instead of dropping them, and ref-count races and buffer-ownership bugs are fixed.
Engine and Database:
- - @dolist/now runs multi-command bodies and honors @break, and inline command lists support ;| piping. (#765, #788) - - Comsys channels and @mail created in-game now survive a warm boot, and are cleared correctly on a forced game load. (#783) - - Flatfile export no longer silently drops per-attribute owner and flags, and the SQLite import path is mistake-proofed against importing into a live database. (#766) - - wrap() truecolor width is fixed; grapheme clusters are no longer split on interior color codes; and width/strdistance are cluster-aware for ZWJ emoji. (#716, #787) - - SQLite backend: column reads are null-guarded, code-cache blobs are validated and the statement reset on failure, and the reset/rollback/checkpoint paths are corrected.
Memory Safety and Reliability:
- - A large RAII migration: ~75 atr_get/atr_pget sites and ~150 alloc_lbuf/free_lbuf sites were converted to owning LBuf handles (LBuf::adopt, LBufPtr), removing manual free paths that could leak on an error return. (#717) - - All static scratch buffers are now thread-local, and reference counts across the comsys, @mail, lua, and exp3 modules -- and the platform layer -- are atomic. - - The Lua undumper caps its read_size() varint length to prevent a size_t overflow, and validates compiled-code-cache blobs before use.
Platform and Build:
- - macOS arm64 build and test-rig support; the UTF-8 DFA tables were regenerated and the table-generator toolchain fixed on macOS. - - Restart and file-descriptor handling hardened: close_range/ closefrom in the boot-helper fast path, the real rlim_cur reported, and PanicRestart bounds its argv by argc and uses execv. - - Generated-file safeguards: a pre-commit hook plus read-only Ragel output guard against hand-editing generated sources. - - The long-dead muxsvc/ Windows service stub was removed.
Clients:
- - TitanFugue gained interactive keyboard input for read()/tfread() (#758, #759, #760), a tokenized status-format-var cache (#761), an nlog() counter, and better Hydra reconnect/error diagnostics. - - Credential storage is hardened across the console and Win32 GUI clients; web-client world passwords were moved out of localStorage; and the WorldBuilder gained TLS verification, attribute-escaping fixes, and expanded softcode danger checks.
Other:
- - version() no longer returns an empty string. (#817)
Download:
Full source (tar.gz): mux-2.14.0.8.unix.tar.gz SHA256: bac36a1fbf5c356f26dae337055bdfe0056ed4d46a5266b9d8197b48895d3185
Full source (tar.bz2): mux-2.14.0.8.unix.tar.bz2 SHA256: 5ef2ccd497611901bd88649af5a19cbb99c923819c5ec5c9336f20b1da8b037f
Patch from 2.14.0.7: mux-2.14.0.7-2.14.0.8.unix.patch.gz SHA256: 0cbf8944ec7a1fca9140e65aef67e8f2be3cf28d635afc544801f639a1b8e324
All files are GPG-signed (.asc).
This is ALPHA software. Make backups. Report bugs to brazi...@gmail.com.