Fix 5364 - #5366
Conversation
|
Thanks @guerricv, the diagnosis is spot on and the fix attacks the right side of the problem: the writers, not the scanner. No exclusion rule, the audit keeps watching those files, and testPermissionScanStillReportsUnsafeRuntimeFiles proves it. The extra concurrency fix that comes with it (opening without truncation and moving ftruncate() after the flock(), so a competing handler can no longer erase the running owner's PID) is a genuine bonus. The test coverage is a real strength, five umasks, repair of a permissive mode without changing the inode or truncating, 0600 preserved, lock contention, symlinks, invalid targets, and a real end-to-end scan. Two things I'd like changed before merge, then a few low-cost hardenings.
app/sources/runtime_files.functions.php is the only file in app/sources/ without the project header block. I checked every file in the directory, all the others carry it, including the recently added file_scope.functions.php and item_restriction_logic.php. Please add the standard Teampass - a collaborative passwords manager. --- … @license GPL-3.0 block.
tpOpenRuntimeFile() returns false when chmod() fails. In acquireProcessLock() that propagates to processBackgroundTasks() (background_tasks___handler.php:87), which returns immediately, no task is processed at all, with only an error_log() line as evidence. chmod() requires ownership (or root), so this triggers whenever the lock file already exists with a different mode and belongs to another account. Suggestion: when fopen() succeeded but only chmod() failed, log and keep the handle instead of returning false. The permission warning reappears (the pre-existing, harmless state) rather than turning a cosmetic finding into an outage. I note tpFileIntegrityWriteJsonFile() (file_integrity.functions.php:759) already throws on the same failure, so the PR is consistent with existing code; it's the consequence that differs (one report not written vs. the whole task pipeline stopped). Low-cost hardenings
Adjacent, out of scope but worth a follow-up
One process noteThe branch is 3 commits behind develop (62c8a0d, b18e667, e85a252 — the API item-level restrictions). The three-way merge applies cleanly and everything is green, but a rebase on develop before merge would make the PR's own CI reflect the real state. As it stands, taking main.functions.php wholesale from the branch reverts those commits and breaks SecurityPostureAuthorizationTest. Thanks for the thorough test suite. |
|
Thanks Nils — points 1–6 are addressed in de5a9e5e2.
Added regression tests for chmod denial after successful opening, replacement during permission repair, path identity, non-blocking contention (with a bounded subprocess timeout), and probing a read-only lock. The chmod-denial fixture is isolated in a subprocess and requires no sudo/account changes. Updated the documentation and PR description to reflect the best-effort permission policy. The fresh Linux CI passes on PHP 8.2.33 and 8.3.33: 1,732 tests and 59,651 assertions on each, without skipped tests. PHPStan level 4, CodeQL, the quality guards and Scrutinizer are also green. Local Windows validation and its platform limitations are recorded in the PR description. The task-log writer/path handling and the persistent-lock lifecycle remain separate follow-ups. No manifest, exclusion-rule, Composer metadata or dependency changes were made. |
|
Separate follow-up on branch alignment: I fetched upstream develop again and checked both Git and GitHub's comparison. At this check, upstream I could not resolve The new |
Description
Fix the recurring permissions warning for
storage/logs/teampass_background_tasks.lockreported in #5364 by correcting runtime-file writers, without weakening the integrity or permissions audit.($currentMode & 0640) | 0600: preserve0600, ensure owner read/write, and do not grant group/other access or change the process-wide umask.chmodfails, log an actionable warning and continue with the existing access. Invalid/replaced targets and actual open/write failures still fail. The permissions audit continues reporting unresolved unsafe modes.dev/inobefore and after permission repair. These checks detect observed replacements; they do not make path-basedchmodatomic. Runtime directories must remain protected against untrusted writers.LOCK_EX | LOCK_NB, distinguishing contention from I/O failure so a web request does not wait or emit a misleading directory-permission error.Runtime data remains excluded from release checksum comparisons but included in the permissions audit. No exclusion rule or
app/files_reference.txtchange is included.The task-log writer and the existing unlink-after-unlock lifecycle race are intentionally left for separate follow-ups, as requested in review.
Related issue
Fixes #5364
Type of change
How has this been tested?
Review follow-up commit:
de5a9e5e28cfd74f4231b1935bbcb3b5b9423e3c. Validation checked on 2026-09-10.Linux CI:
The regression coverage includes creation/recreation under five umasks, preservation of 0600 and active contents/inodes, continued writing plus an audit warning after a simulated chmod denial, observed target replacement, a bounded subprocess test for contending signal writers, read-only status probing, invalid targets/symlinks, and continued detection of unsafe runtime permissions. Chmod denial is simulated in an isolated PHP subprocess; the tests require neither sudo nor account changes.
Local Windows validation:
settings.sample.php, removed afterwards.git diff --check: passed.No live-instance UI/database/user-role tests were run locally. Roles and personal-folder behaviour are unchanged. Suggested lab validation: trigger background processing and an integrity scan under the normal web/cron account; verify lock/signal modes, task progress, and continued reporting of an unrelated unsafe runtime file.
Checklist
php app/vendor/bin/phpstan analyse --memory-limit=2G)php _tools/phpunit.phar) — Linux CI on PHP 8.2 and 8.3; Windows limitations documented abovevar_dump()orconsole.log()left in the codeapp/sources/*.queries.phpfiles have a matchingpublic/sources/proxy shim — not applicableteampassclasseswere applied to both copies — not applicableapp/vendor/composer/is in its production form — left untouchedImpact on install / upgrade
install/upgrade_run_X.X.X.phpscript is included and the fresh install path was testedNo install/upgrade or configuration migration is required. Existing accessible locks/signals are repaired when possible. Incorrect ownership or inaccessible directories still require administrator remediation; the helper does not change ownership.
Screenshots
Not applicable: no UI change.