Skip to content

fix: harden QOpen state and process boundaries - #13

Merged
CoderLambert merged 17 commits into
mainfrom
hotfix/marketplace-security-hardening
Aug 28, 2026
Merged

fix: harden QOpen state and process boundaries#13
CoderLambert merged 17 commits into
mainfrom
hotfix/marketplace-security-hardening

Conversation

@CoderLambert

@CoderLambert CoderLambert commented Aug 28, 2026

Copy link
Copy Markdown
Owner

Summary

  • anchor the complete catalog, backup, recovery and replacement lifecycle to a trusted directory descriptor
  • reject symlinks, hard links, special files, unsafe ownership/permissions and oversized state before parsing
  • replace the pathname lock with a deadline-bound directory FD lock
  • remove QML FileView and all StdioCollector usage in favor of bounded one-line backend responses and TERM-to-KILL deadlines
  • run bounded helpers in isolated process groups so descendants cannot outlive helper deadlines
  • add adversarial race, special-file, output-limit, timeout and bilingual-documentation coverage
  • add explicit regression coverage for intermediate ancestor symlinks, concurrent backup-path replacement races, root-parent FD ownership and helper descendants
  • add an explicit PathPicker refresh control plus F5 without introducing filesystem watchers
  • keep ResourceEditor field sizing responsive while rendering complete four-sided form-field borders
  • reject ambiguous bare single-label web targets while preserving domains, IPs, localhost and explicit-scheme intranet hosts
  • document the security model and v2.5.1 upgrade behavior with precise runtime-vs-repair permission semantics

Marketplace review mapping

  1. State paths now use component-by-component O_DIRECTORY/O_NOFOLLOW traversal, descriptor-relative O_NONBLOCK regular-file reads, same-directory temporary files, descriptor-relative os.replace, directory locking and fsync. Regression tests exercise an intermediate parent-directory symlink, a live config.json.bak regular-file/symlink race, and the /config.json root-parent FD ownership edge case.
  2. QML no longer reads the catalog directly. The Python producer caps catalog/API/helper output before QML receives it; QML applies a secondary protocol-size check. Bounded helpers run in their own process groups and enforce real TERM-to-KILL deadlines across descendants.

Validation

  • python -m json.tool manifest.json
  • python -m py_compile bin/qopen
  • python -m unittest discover -s tests -v46 passed
  • qmlcachegen for all 5 QML components
  • omarchy plugin validate .
  • git diff --check
  • read-only real-catalog check; SHA-256 unchanged before/after

@CoderLambert

Copy link
Copy Markdown
Owner Author

Runtime acceptance completed at exact HEAD bf7a352 on Omarchy 4.0.1 / Quickshell 0.3.1: the catalog rendered all 38 existing resources, collections rendered correctly, and the project add route opened the embedded non-GTK path picker. No new QML errors or Quickshell core dumps were observed. The personal catalog SHA-256 remained 40f3cecd5bc448a4b73e59c248a6bbd0fc9f45359d596b992dbd262fc54473f6 before and after all read-only checks. The installed copy was then restored to stable main.

@CoderLambert
CoderLambert force-pushed the hotfix/marketplace-security-hardening branch from cf23fca to 56f58a0 Compare August 28, 2026 17:36
@CoderLambert
CoderLambert merged commit 96acdb0 into main Aug 28, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant