Skip to content

Shared mounts can be written back to the wrong slots after Monty.run(...) #380

@fswair

Description

@fswair

When shared mounts are passed to Monty.run(...), mount identity is not preserved if caller-provided order differs from Monty’s internal longest-prefix-first ordering. After a successful run, mounts can be written back into the wrong shared slots, causing the caller-visible mount objects to come back with the wrong virtual_path, host_path, and mode. This appears to be a real mount identity corruption bug, not just a display issue.

Monty version: 0.0.16
Python version: 3.11.7

Note: Bug found by ChatGPT while I'm playing with hackmonty. Issue title and body generated by AI, I don't want to throw AI slop somewhere but I tried this by myself and it seemed a bug to me.

Repro

from pathlib import Path
from tempfile import TemporaryDirectory
from pydantic_monty import Monty, MountDir

with TemporaryDirectory() as dir_a, TemporaryDirectory() as dir_ab:
    Path(dir_a, "one.txt").write_text("ONE")
    Path(dir_ab, "two.txt").write_text("TWO")

    mount_a = MountDir("/a", dir_a, mode="read-only")
    mount_ab = MountDir("/a/b", dir_ab, mode="read-write")

    print("BEFORE mount_a :", mount_a.virtual_path, mount_a.host_path, mount_a.mode)
    print("BEFORE mount_ab:", mount_ab.virtual_path, mount_ab.host_path, mount_ab.mode)

    Monty("1 + 1").run(mount=[mount_a, mount_ab])

    print("AFTER  mount_a :", mount_a.virtual_path, mount_a.host_path, mount_a.mode)
    print("AFTER  mount_ab:", mount_ab.virtual_path, mount_ab.host_path, mount_ab.mode)

Observed raw output

BEFORE mount_a : /a /private/var/folders/9t/dwwzwmw57xg7yyml_2jtb9lc0000gn/T/tmpf9iya794 read-only
BEFORE mount_ab: /a/b /private/var/folders/9t/dwwzwmw57xg7yyml_2jtb9lc0000gn/T/tmpgaa15ift read-write
AFTER  mount_a : /a/b /private/var/folders/9t/dwwzwmw57xg7yyml_2jtb9lc0000gn/T/tmpgaa15ift read-write
AFTER  mount_ab: /a /private/var/folders/9t/dwwzwmw57xg7yyml_2jtb9lc0000gn/T/tmpf9iya794 read-only

Expected behavior

mount_a should remain bound to /a with its original host directory and read-only mode, and mount_ab should remain bound to /a/b with its original host directory and read-write mode.

Actual behavior

After Monty.run(...), the two mount objects are swapped. mount_a comes back as the /a/b mount, and mount_ab comes back as the /a mount.

Likely cause

The behavior appears to come from a mismatch between:

  1. the order shared mounts are taken from caller-provided slots,
  2. the internal reordering done for mount dispatch, and
  3. the positional write-back when mounts are returned to shared slots.

Impact

At minimum, this causes persistent mount identity corruption across a run. If shared mount objects are reused, later operations may target the wrong mount point, host directory, or mode. Depending on how shared mounts are used, this could also create integrity or privilege-confusion risks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions