TinyMUX 2.14.0.8 ALPHA

1 view
Skip to first unread message

Brazil

unread,
Jun 16, 2026, 12:26:04 AM (8 days ago) Jun 16
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.

- -- Brazil

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEE8GWFNwJrhRGk25uvF80K5PxQP7EFAmowh+8ACgkQF80K5PxQ
P7GAFg/5AenfPIccMVIsyrqyyoiOlkQiN6lxLhpHu7Os9LVJ+IouQJBM1l4ZCndq
2DQwzmnPNgkk0pZaTmKJ8t7meJ0romPVr2uszSQ/EmgbkvqQRxPgCYbFRMfh0H2Z
TfM+gNd3E/L+7KyPNFPqLa1HWSriVgTouj4mSZld2pL77wDyYFmh/PDpkUEJkRbc
ChHqeWzvrdOsHzf4bO+rOYlsKhfqDU2E0z87qeMMGz+LUMoL7ejGwUCFgJEyenqF
SFMmNqb3iQkog58rV23rgILCrYg81+lRUiz5bqqaP0PH1/+K8bC6DXjr8R3MSlk2
/i/6MIWKoYg0zhU3OxL4bZllo/lZWb+mf/nqGmns0XFzzalSOOSTBnp94ExaOwBK
8pBjFBKk0MtvSt7Un5/tWO+W9dLdgilg+t/g3p7Egk7HNdN/4HJJX/zuiWQ9baHd
M+Wm8HXh/m8qp5LMtoj3Vwkzf1iBw0Uv2mCD1i+E8ZjTmLOGmsJusIZF1J9bjFWC
su3fqhOh6sOaj1kYbfUNbdC7QQ5N0MrnxT3PIreCwWZhNxBE9jdxBckfLr0a9Aw3
kDfmwxfCx0WFx7pthzhx/U/KirJXgBAk22tmb6DNuuYD9HvTfVwTqs2Ymqgbu6kX
IOpLSn0YSPjip62Pvy07C+V46q8XbLY90OwhjOtlN7+bxlIJRQk=
=mnBQ
-----END PGP SIGNATURE-----

Reply all
Reply to author
Forward
0 new messages