Skip to content

linux: one wrap, one working directory, and no object taken for the same install - #655

Merged
ronleizrowice-ant merged 2 commits into
mainfrom
fix/one-wrap-one-working-directory
Oct 5, 2026
Merged

ronleizrowice-ant merged 2 commits into
mainfrom
fix/one-wrap-one-working-directory

Conversation

@ronleizrowice-ant

@ronleizrowice-ant ronleizrowice-ant commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator

Two ways past the check "one wrap, one configuration". Both came with the walk in turns (#628), which is on main and in no release.

What was wrong

A wrap starts over when it finds another configuration object than it started with.

  • The working directory is not covered. A relative entry (. as a write root) is resolved against it wherever it is read. A host that calls chdir() in a turn of the walk gets a command put together from both directories: denies walked from the old one, . bound back from the new one. Where the new one lies inside a folder a ** rule denies, what the rule matches there comes back readable.
  • An object can come again. initialize() keeps the caller's own object, so reset() and initialize() with it again, during a wrap, looks like no change. A file written before that is not denied, against linux: a wrap that starts over reads the disk again #644's invariant.

What changes

One predicate in place of the identity test, in the walk's steps and after the last await. A wrap also starts over when:

  • a configuration has been installed since it began: a count, raised by initialize() and updateConfig();
  • process.cwd() has changed (5 to 15 ns a call on Node 22 and Bun 1.4). A directory that was removed counts as a change.

The Linux wrapper awaits once more after that, for its scan for dangerous names, and resolves relative entries on both sides of it. It notes the working directory at its start and throws WorkingDirectoryChanged right after the scan if that has changed, before anything is left on the host; the manager starts over. (Second commit.)

Each new term only makes a wrap start over more often. The bound after two restarts is as it was for the walk; the scan still gives the thread back.

Known limit

Mutating the object handed to initialize() is still not seen. Cloning it there would lose its function-valued fields.

Measured

Real bubblewrap, a walk over 400,150 files, 3 runs a case:

during the walk main here
chdir() into a folder a ** rule denies, allowWrite: ['.'] the file is read refused
a file is written, then reset() and initialize(sameObject) the file is read refused
chdir() during the scan (a stand-in that takes 0.4 s), allowWrite: ['.'] the old directory is the write root the new one is; the scan ran twice

Six rules over the same tree, undisturbed: 1.0 s on both.

Testing

Four new cases: chdir() in the middle of the walk, in its last listing and during the scan, and the second install. All fail on main's source. Six mutations: five fail a test. The sixth, dropping the object test, survives: every install counts now, and the test stays for the paths that set the configuration to undefined.

…ame install

Since the walk gives the thread back, a wrap starts over when it finds
another configuration object than it started with. Two things got past
that. A host that changed its working directory in a turn of the walk got
a command put together from both: a `.` bound back from where it had gone
to, over denies walked from where it was. And initialize() keeps the
caller's own object, so reset() and initialize() with it again looked like
no change at all.

A wrap now also starts over when a configuration has been installed since
it began, by a count, and when the working directory has changed.
… well

The Linux wrapper awaits once more, for its scan for dangerous names, after
the manager's last check, and resolves relative entries on both sides of
that. It now notes the working directory at its start and throws right
after the scan if that has changed, before anything is left on the host.
The manager starts the wrap over.

@antdres antdres left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/stamp

@ronleizrowice-ant
ronleizrowice-ant merged commit cb75d65 into main Oct 5, 2026
16 checks passed
@ronleizrowice-ant
ronleizrowice-ant deleted the fix/one-wrap-one-working-directory branch October 5, 2026 18:17
@ronleizrowice-ant ronleizrowice-ant mentioned this pull request Oct 6, 2026
ronleizrowice-ant added a commit that referenced this pull request Oct 7, 2026
New to the bundle: #655, #660 and the version. #643, #639 and #630 come as
squashes of what it held; in the one block git marks, the workflow's, it
keeps its own side, which has the checksummed bun as well.

Two cases of #655 compare two wrapped commands. Here a wrap that names
mount points names a manifest of its own (#584), so the cases take that
name out before they compare.
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.

2 participants