Skip to content

Commit 57a8a15

Browse files
committed
[Change] CHANGELOG: v2.0.1 dedup — consolidate #480/#482/#483, trim section drift
[Change] Collapse issue #482 into one consolidated [Fix] (field parity + scaling) [Change] Collapse issue #483 into one consolidated [Fix] (sort + started_epoch + .html glob) [Change] Collapse issue #480 into one [New] + one [Fix] (two-file union model) [Change] Correct #483 scope — only reports[] is globally sorted; active[]/stopped[] gain started_epoch for consumer-side sortability [Change] Tag #482's three Lifecycle-JSON / _json_escape_string [Change] entries with issue ref [Change] Move 14 mis-tagged entries to correct sections (Fix→Fixes, New→Features, Change→Changes) [Change] Drop internal-only entries — comment-normalization T1/T2/T3, batsman CI-infra bumps, test-only announcements [Change] Drop fluff — docs-housekeeping entries for features already announced as [New] [Change] Trim verbose multi-line entries — vendored-lib sync, DEB override_dh_fixperms, --test-alert digest, _json_escape_string sed→bash [Change] Collapse Monitor 12-defects [Fix] into the parent [New] supervisor entry (was duplicated) [Change] Remove stale intermediate vendored-lib sync ([Change] tlog_lib 2.0.5 etc) superseded by current 2.0.6 sync [Change] v2.0.1 entry count 131 -> 112 (35 New / 24 Change / 53 Fix); CHANGELOG.RELEASE byte-parity preserved
1 parent 6a32df1 commit 57a8a15

File tree

2 files changed

+82
-262
lines changed

2 files changed

+82
-262
lines changed

CHANGELOG

Lines changed: 41 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ v2.0.1 | Mar 25 2026:
22

33
-- New Features --
44

5-
[New] Monitor mode: supervisor model replaces double-fork; 12 pre-existing defects resolved
5+
[New] Monitor mode: supervisor model replaces double-fork; 12 pre-existing defects resolved (graceful shutdown, crash recovery, session rotation, event filter, PID guard, ClamAV cache); issue #454, #447, #459
66
[New] Config: digest_interval, digest_escalate_hits, monitor_paths_extra for monitor mode
77
[New] TSV canonical session format: 11-field hit records replace plaintext session files;
88
session_legacy_compat config (auto/0/1) for backward compatibility
@@ -72,45 +72,15 @@ v2.0.1 | Mar 25 2026:
7272
supports args/file/json output tiers, sync/async execution, timeout
7373
with SIGTERM/SIGKILL, elog audit trail, min_hits threshold, scan type filter;
7474
scan_start epoch in JSON payload (LMD_SCAN_START env); issue #477
75-
[New] ignore_inotify: versioned defaults file ($inspath/internals/ignore_inotify.defaults) consulted in addition to user ignore_inotify; refreshed for systemd-private tmpdirs, modern MariaDB, PostgreSQL, Redis; issue #480
76-
[Fix] ignore_inotify: replace dead legacy regex defaults (broken since 2026-03-19 _monitor_escape_ere change) with user-template header; live defaults now ship in ignore_inotify.defaults; issue #480
77-
[Fix] monitor: union-load ignore_inotify + ignore_inotify.defaults; new _monitor_load_ignore_inotify_union helper skips blanks+comments, dedupes across both files; issue #480
78-
[New] packaging: ship ignore_inotify.defaults in RPM spec, DEB rules, links, symlink-manifest; non-conffile under /usr/lib/maldet/internals/ so upgrades refresh the file; override_dh_fixperms preserves 640 mode on DEB; issue #480
79-
[Change] docs: document ignore_inotify.defaults two-file union model in README §5/§7 and maldet.1 MONITOR MODE; issue #480
80-
[Fix] ignore_inotify.defaults: scope 'sql_' to /tmp/#sql_ + /var/tmp/#sql_ and drop bare 'scantemp' to prevent matching user files like sql_backup.php and scantemplate.php; add /var/lib/maldet/ for FHS scan-temp coverage; sentinel remediation for issue #480
75+
[New] ignore_inotify: two-file union model — LMD-managed defaults
76+
($inspath/internals/ignore_inotify.defaults) refreshed for systemd-private
77+
tmpdirs, modern MariaDB, PostgreSQL, Redis, ClamAV runtime; user-owned
78+
ignore_inotify retained for site overrides; dead legacy regex defaults
79+
replaced (broken since _monitor_escape_ere change); issue #480
8180

8281
-- Changes --
8382

84-
[Change] comments: T3 inline prose rehousing + restatement sweep across 18 files
85-
[Change] comments: T2 function-header normalization — collapse signature-restatement blocks
86-
[Change] comments: T1 mechanical cleanup — strip banner separators and file-header catalogues
87-
[Change] - Delete 20 pure-dash banners (lmd_hook.sh: 14, lmd_alert.sh: 6)
88-
[Change] - Transform 95 labeled banners (# --- label --- -> # label)
89-
[Change] - Trim file-header catalogues (hookscan.sh, importconf, tlog, cron.watchdog, pkg-postinst.sh, uninstall.sh, files/uninstall.sh)
90-
[Change] - Applies parent CLAUDE.md §Code Comments primitive (one-line headers, no banners, no tombstones)
91-
[Change] - Preserves load-bearing keeps: BEGIN INIT INFO (service/maldet.sh), flock rationale (cron.daily), cron.watchdog decoupling invariant
92-
[Change] Vendored lib sync: tlog_lib 2.0.5 → 2.0.6, alert_lib 1.0.6 → 1.0.7,
93-
elog_lib 1.0.5 → 1.0.6, pkg_lib 1.0.9 → 1.0.10. All four are
94-
comment-discipline cascade bumps from canonical (banner separators
95-
removed, signature-restatement prose deleted from function headers,
96-
prose config catalogues replaced with README cross-references).
97-
Zero functional change in any of the four libraries; load-bearing
98-
rationale (TLS posture, symlink-safety, eval-guard validation,
99-
pkg_config_merge invariants, SIEM/CEF/GELF contract docs, journal
100-
filter contracts, alert dispatch invariants) preserved intact.
101-
Byte-identical to canonical: tlog_lib d65158c (v2.0.6),
102-
alert_lib 3b66050 (v1.0.7), elog_lib 7a60165 (v1.0.6),
103-
pkg_lib cdd0814 (v1.0.10).
104-
[Change] files/internals/tlog (standalone CLI wrapper): 2.0.4 → 2.0.6 —
105-
byte-synced to canonical. Wrapper had been drifting (skipped
106-
during prior 2.0.5 sync); colocated with tlog_lib.sh so no
107-
BFD-style fallback required. install.sh BASERUN sed pattern
108-
still matches the canonical line format.
109-
[Change] tests/infra: batsman 1.4.1 → 1.4.2 — runs-on input for
110-
self-hosted runner support (CI workflow only, no test behaviour
111-
changes).
112-
[Change] Vendored lib sync: tlog_lib 2.0.5, alert_lib 1.0.6, elog_lib 1.0.5,
113-
pkg_lib 1.0.8
83+
[Change] Vendored libs synced to canonical: tlog_lib 2.0.6, alert_lib 1.0.7, elog_lib 1.0.6, pkg_lib 1.0.10 (zero functional change)
11484
[Change] Alert templates: consolidate summary into headers; drop "TOTAL" prefix from
11585
labels (HITS/CLEANED/QUARANTINED); add quarantine metrics; aligned column spacing
11686
[Change] Hook scans write to rolling hook.hits.log instead of creating session files;
@@ -120,8 +90,6 @@ v2.0.1 | Mar 25 2026:
12090
[Change] CLI: modifier flags (-x, -i, -hscan, -qd, -co, --format, --mailto) are now
12191
position-independent; -co uses in-memory parser; -qd with non-existent
12292
directory exits 1
123-
[Change] Documentation: man page, README, and usage rewritten with complete option/config
124-
coverage
12593
[Change] Rename sig_import_*_url config variables (from import_custsigs_*_url) for
12694
sig_* namespace consistency; compat.conf migration maps old names
12795
[Change] scan_workers default changed from "0" to "auto"; "0" silently accepted as
@@ -155,80 +123,46 @@ v2.0.1 | Mar 25 2026:
155123
maint_archive_age (both disableable with 0)
156124
[Change] cron.daily: run --maintenance after sigup/versionup for automated history
157125
rotation and session cleanup; hardcoded log paths replaced with $maldet_log
158-
[Change] Tests: batsman v1.4.2; per-test 180s timeout prevents hung scans;
159-
GHA 24-way parallel matrix; JUnit XML reports
126+
[Change] Lifecycle JSON (-L --format json): "scan_id" is now the canonical field name;
127+
"scanid" remains as a deprecated alias for one release cycle and will be
128+
removed in v2.1.0. Consumers should switch to "scan_id"; issue #482
129+
[Change] Lifecycle JSON (-L --format json): "workers" field type normalized to
130+
unquoted number to match the field's underlying integer value; issue #482
131+
[Change] _json_escape_string: promoted to lmd.lib.sh shared utilities so all JSON
132+
emitters (scan list, active lifecycle, post-scan hook, ELK dispatch) share
133+
one helper; sibling _json_escape_var out-parameter helper for hot loops
134+
that must avoid a subshell fork per iteration; issue #482
135+
[Change] conf.maldet / maldet.1: correct post_scan_hook_timeout documentation — prior
136+
text claimed a 5-second grace period before SIGKILL, but timeout(1) is invoked
137+
without --kill-after, so a hook that traps SIGTERM will run indefinitely; pr#478
160138

161139
-- Bug Fixes --
162140

163-
[Fix] --json-report list: reports[] entries now include a "path" field, matching
164-
the text-mode list output; active[] entries gain the lifecycle schema
165-
(eta, workers, sig_version, progress{}) so --json-report list and
166-
-L/--list-active emit the same shape; stopped[] entries gain an elapsed
167-
field; all string fields in active[] and stopped[] are now JSON-escaped
168-
via the shared _json_escape_string helper (previously only "path" was
169-
escaped — stage, engine, stopped_hr, stages, sig_version could emit
170-
invalid JSON if scan.meta contained quotes, backslashes, or control
171-
characters); issue #482
172-
[Change] Lifecycle JSON (-L --format json): "scan_id" is now the canonical
173-
field name; "scanid" remains as a deprecated alias for one release cycle
174-
and will be removed in v2.1.0. Consumers should switch to "scan_id"
175-
[Change] Lifecycle JSON (-L --format json): "workers" field type normalized to
176-
unquoted number to match the field's underlying integer value
177-
[Change] _json_escape_string: promoted from lmd_hook.sh (optional sub-lib) to
178-
lmd.lib.sh shared utilities so all JSON emitters — scan list, active
179-
lifecycle, post-scan hook, and ELK dispatch — share one helper. Three
180-
call sites in lmd_alert.sh previously using _alert_json_escape (from the
181-
vendored alert_lib) now use the project-owned helper; vendored library
182-
coupling reduced to the lib's internal self-use. A sibling out-parameter
183-
helper _json_escape_var (sets _JSON_ESC_OUT) is also defined for hot
184-
loops that must avoid a subshell fork per iteration
185-
[Fix] --json-report list: scaling regression at large session counts. Pre-fix
186-
the function exhibited effective hang at ~20K indexed sessions from two
187-
compounding costs: (1) _seen_ids built as a whitespace-joined string
188-
that grew O(N^2) with glob-pattern dedup, and (2) one subshell fork per
189-
report for path escaping. Dedup now uses a function-scoped local -A
190-
associative array (O(N) total), and the reports[]/legacy hot loops use
191-
the new _json_escape_var out-parameter helper instead of $() command
192-
substitution. Measured: 20K reports 82s -> 1.7s; 50K reports now ~1.7s
193-
(linear). Regression guard: tests/31-json-report.bats test 27 runs a
194-
10K-entry synthetic index under a 30s timeout
141+
[Fix] monitor: union-load ignore_inotify + ignore_inotify.defaults; new _monitor_load_ignore_inotify_union helper skips blanks+comments, dedupes across both files; issue #480
142+
[Fix] --json-report list: path field parity with text mode; unified JSON escaping
143+
across reports[]/active[]/stopped[]; dedup+escape rewrite eliminates O(N^2)
144+
hang at ~20K sessions (82s → 1.7s); active[] gains lifecycle schema
145+
(eta/workers/sig_version/progress); stopped[] gains elapsed; issue #482
146+
[Fix] --json-report list: reports[] now globally sorted by started_epoch
147+
(newest first) across TSV index + legacy-session passes (pre-fix emitted
148+
index entries in append-order then legacy, producing visible date
149+
inversions); reports[]/active[]/stopped[] all gain started_epoch integer;
150+
stopped[] gains stopped_epoch; pass-2 glob skips legacy session.*.html
151+
artifacts (fixes 12s+ hangs on installs with pre-on-demand-HTML files);
152+
issue #483
195153
[Fix] clamav_linksigs: guard mktemp staging failure to prevent writing signature
196154
files into the filesystem root. When mktemp -d fails, the empty _staging
197155
variable caused "cp -f ... /" as root; pr#478
198-
[Fix] _json_escape_string: replace sed pipeline with bash parameter expansion.
199-
Two defects fixed in one rewrite: (1) the quoted "$sed" invocation tried
200-
to execve a binary literally named "sed -E" on FreeBSD (where
201-
internals.conf sets sed="$sed -E"), silently breaking post_scan_hook
202-
JSON payload construction; (2) the N;s/\n/\\n/;P;D sed cycle only
203-
escaped the first newline in multi-line input, emitting raw LF bytes
204-
in JSON output for paths with two or more embedded newlines. The bash
205-
parameter expansion form is portable, correct for any number of
206-
newlines, and removes an external process from the hook hot path.
207-
BATS coverage added (J-01 through J-15) including a structural guard
208-
against sed reintroduction; pr#478
209-
[Change] conf.maldet / maldet.1: correct post_scan_hook_timeout documentation.
210-
The prior text claimed a 5-second grace period before SIGKILL, but the
211-
code invokes timeout(1) without --kill-after, so a hook that traps
212-
SIGTERM will run indefinitely. Updated to match actual behavior;
213-
pr#478
214-
[Fix] DEB: override_dh_fixperms target restores 640/750 modes after debhelper's
215-
dh_fixperms normalizes executables to 755 and non-executables to 644.
216-
Without this, 72 files shipped in the data.tar at the wrong mode including
217-
all internals/*.sh sub-libraries, alert templates, cron fragments, and
218-
runtime config files. conf.maldet was masked at runtime by an explicit
219-
chmod in postinst, but conf.maldet.hookscan.default, /etc/default/maldet,
220-
and the 15 sub-library shell files were genuinely wrong on installed
221-
systems. RPM uses %attr() declarations and was unaffected; pr#478
222-
[Fix] --test-alert digest email: seed $tmpdir/digest.hook.alert cursor to
223-
_orig_size before dispatching through genalert. Three related defects in
224-
the prior implementation: (1) first-run tlog_read path silently swallowed
225-
the synthetic test hits on fresh installs, so the function printed
226-
"test email digest alert sent" without actually dispatching anything;
227-
(2) a trailing cursor caused unalerted real hook hits to leak into the
228-
test email; (3) the cursor restore left those same hits to be re-sent
229-
on the next real digest. Also guards post-dispatch truncate against
230-
trim_log having shortened the log mid-digest. Positive-path BATS
231-
coverage added to prevent regression; pr#478
156+
[Fix] _json_escape_string: replaced sed pipeline with bash parameter expansion;
157+
fixes FreeBSD breakage (sed="$sed -E" execve) and multi-newline escaping
158+
for post_scan_hook JSON payloads; pr#478
159+
[Fix] DEB: override_dh_fixperms restores 640/750 modes (72 files incl.
160+
conf.maldet.hookscan.default, /etc/default/maldet, and 15 sub-library shell
161+
files) after debhelper normalizes executables to 755 and non-executables
162+
to 644; RPM uses %attr() and is unaffected; pr#478
163+
[Fix] --test-alert digest: seed $tmpdir/digest.hook.alert cursor to _orig_size
164+
so first-run tlog_read dispatches synthetic hits on fresh installs; prevents
165+
real-hit leakage into test email and re-send on next real digest; pr#478
232166
[Fix] Hook validation: world-writable detection used broken glob extraction that always
233167
returned empty string; replaced with bash substring to correctly extract last octal
234168
digit; pr#478
@@ -260,8 +194,6 @@ v2.0.1 | Mar 25 2026:
260194
man page compression on fresh install; backup robustness; no longer kills inotify
261195
monitoring; Slackware init per rc.NAME convention; preserve hookscan config and
262196
pub/ state; issue #414
263-
[Fix] Docs: missing config vars (scan_hashtype, scan_find_timeout, scan_yara auto),
264-
pkg_lib.sh in FILES section, CLI aliases, --cron-sigup
265197
[Fix] purge() dotfile glob: replace * glob with find -delete to catch dotfiles in
266198
tmp/quarantine/sess
267199
[Fix] Quarantine: correct scan ID in report warning; TOCTOU mv exit code check; inode
@@ -285,8 +217,6 @@ v2.0.1 | Mar 25 2026:
285217
concurrent scan conflicts
286218
[Fix] scan(): exit 1 when all provided scan paths do not exist
287219
[Fix] Hash scanning: handle md5sum/sha256sum backslash-escaped filenames
288-
[Fix] Monitor mode: 12 defects fixed (graceful shutdown, crash recovery, session
289-
rotation, event filter, PID guard, ClamAV cache); issue #454, #447, #459
290220
[Fix] Alerting: Slack migrated from deprecated files.upload API; Telegram /bot prefix;
291221
token security via curl -K; genalert() state isolation; issue #387, #458, #461, #426
292222
[Fix] Security: _safe_source_conf() allowlist (79 vars); conf.maldet 0640; dirs 750;
@@ -326,26 +256,6 @@ v2.0.1 | Mar 25 2026:
326256
[Fix] RPM/DEB %pre: defensive detection for dir-vs-symlink cpio conflict; install
327257
no longer fails with "rename failed - Is a directory" when prior install.sh
328258
or partial install left real directories at symlink-target paths
329-
[Fix] --json-report list: reports[] now globally sorted by started_epoch
330-
(newest first) across TSV index + legacy-session passes; pre-fix
331-
code emitted index entries in append-order then legacy entries,
332-
producing visible date-order inversions (e.g. Mar 29 legacy after
333-
Apr 18 TSV); issue #483
334-
[New] --json-report list: reports[] entries include started_epoch integer
335-
field for machine-readable absolute timestamps; additive schema
336-
change (existing "started" string preserved); issue #483
337-
[New] tests: 3 BATS regressions for --json-report list sort order,
338-
started_epoch field, and legacy-session epoch derivation; issue #483
339-
[New] --json-report list: active[] and stopped[] entries now include
340-
started and started_epoch for consistency with reports[]; stopped[]
341-
also gains stopped_epoch alongside existing stopped_hr; issue #483
342-
[Fix] --report list / --json-report list / -e newest: pass-2 glob now
343-
skips legacy session.*.html artifacts (caught pre-fix by
344-
session.[0-9]* glob). _parse_session_metadata was slurping
345-
multi-MB HTML files line-by-line searching for break markers that
346-
never appear in HTML, producing 12s+ hangs on installs carrying
347-
pre-on-demand-HTML legacy artifacts. Fix at 3 sites in lmd_alert.sh
348-
+ lmd_session.sh
349259

350260
v1.6.6.1 | Feb 25 2025:
351261
[Fix] find_recentopts incorrectly escaping find options to the right of ( -mtime .. -ctime ); previously normalized by eval; issue #440, pr#442

0 commit comments

Comments
 (0)