Skip to content

Module-file transactions: out-of-threat-model review findings (PR #561) #565

Description

@wisdommen

Follow-up of #561 under the maintainer's local-review rule (2026-10-01): review findings whose trigger lies outside the pull request's threat model are collected here instead of being fixed in the review loop.

Threat model of #561: crashes, restarts, the operator's normal commands and panel actions (/upm install, /upm update, /upm update all, /upm uninstall, restarts from the panel), and concurrency among those. Outside it: a Java security manager denying file access, hand-edited framework-internal files (transaction records), a third party changing the modules folder or the transaction folder while a transaction is pending, and the like.

Findings from the GitHub review rounds 1–19

All 21 findings were fixed on #561; none is left open. The ones whose trigger was outside the threat model, fixed anyway before the rule changed, are listed so the record is complete:

Round Finding Trigger Fixed in
5, 7, 18 a malformed, incomplete, or null-entry transaction record hand-edited internal file 5d019894, be31008e, 00d80764
3, 4, 13 a SecurityException from a file operation Java security manager 60847e7b, b293e223, ab93f344
4, 19 a staged, kept, or applied JAR changed or replaced mid-transaction third party changing files cf10b491, d76b3d79 (foreign-file guard, NEEDS_OPERATOR)
17 a duplicate copy failing isValidModuleJar counted as loading first a hand-placed oversized copy 88472f91

Findings from the local Codex runs

  • Run 1 on ca5f6407 (gpt-6.1-sol, effort high): no finding.

Known limitations outside the threat model (recorded during the review, not fixed)

  1. A module can stay unloaded until the operator acts. If a crash leaves the old JAR kept aside and the staged JAR is then changed by someone else, the foreign-file rule touches nothing: the record is NEEDS_OPERATOR, the old JAR stays in .ultikits/upm-transactions/<record>/backup/ (named in the SEVERE line), and the module does not load until the operator moves it back and deletes the record. Two faults are needed: a crash and a third-party change.
  2. A duplicate copy the update check cannot see. /upm update refuses when another copy of the module would load first, judged by its plugin.yml main:. A copy whose plugin.yml cannot be read, or that bundles the module's class under another main:, is not detected (reading classes out of archives is deliberately not done); the start-up observation still rolls such an update back.
  3. A release that renames its main class. The duplicate-copy check uses the current main class; a copy declaring the old main class that sorts first refuses the update even if the new version's main class differs. The refusal names the copy, so the operator can remove it.
  4. Operator-made placements in the recovery table's "made by hand" column (a copy of the new version already in the modules folder, and similar): outside what a crash or failure can produce; see the table on fix(upm): commit a module update only after the next start shows it loaded (#505, #513, #518, #517) #561.

中文摘要:#561 的威胁模型为崩溃、重启、管理员正常命令与面板操作及其并发。GitHub 第 1–19 轮的全部发现均已修复,其中超出威胁模型的几项在规则变更前已修;本地复审第 1 次无发现。本 issue 记录超出威胁模型、未修复的已知限制。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions