Skip to content

bug: _build_rootfs leaks loop mounts and masks real exceptions with TypeError #8

@0xR35tu

Description

@0xR35tu

Bug 1 — run() call in exception handler raises TypeError, masking the real error

In firecracker/microvm.py, _build_rootfs exception handler:

except Exception as e:
    if tmp_dir:
        run(f"umount {tmp_dir}", "unmounting")  # ← bug
        os.rmdir(tmp_dir)
    raise VMMError(f"Failed to create image file: {e}")

run() is defined as def run(cmd, **kwargs) — one positional argument only. Passing "unmounting" as a second positional argument raises:

TypeError: run() takes 1 positional argument but 2 were given

This TypeError replaces the original exception e, so the real failure reason is permanently lost. The user sees:

Failed to build rootfs from Docker image: run() takes 1 positional argument but 2 were given

Bug 2 — Loop device and temp dir leaked on successful build

The success path never unmounts:

tmp_dir = tempfile.mkdtemp()
run(f"mount -o loop {file} {tmp_dir}")

with tarfile.open(tar_file, 'r') as tar:
    tar.extractall(path=tmp_dir)

os.remove(tar_file)
# function returns here — tmp_dir is still mounted

Every call to build() that succeeds leaves a dangling loop device and an orphaned /tmp/tmp* directory on the host.


Fix

except Exception as e:
    raise VMMError(f"Failed to create image file: {e}")
finally:
    if tmp_dir:
        run(f"umount {tmp_dir}")  # correct signature, no extra positional arg
        os.rmdir(tmp_dir)
  • finally guarantees cleanup on both success and failure paths
  • except only re-raises the real exception — e is preserved

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