Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions crates/lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1493,6 +1493,15 @@ pub fn global_init() -> Result<()> {
std::env::set_var("HOME", "/root");
}
}
// Disable libdevmapper's udev synchronization. Inside a container with an
// isolated IPC namespace (the podman/docker default), udevd on the host
// cannot see the container's semaphores, causing cryptsetup luksOpen and
// luksClose to deadlock on semop(). This is a defense-in-depth measure;
// the primary fix is to run the install container with --ipc=host.
// SAFETY: Called early in main() before any threads are spawned.
unsafe {
std::env::set_var("DM_DISABLE_UDEV", "1");
Copy link
Collaborator

Choose a reason for hiding this comment

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

While a deadlock is not great, I think since we have a primary fix already I'd rather just rely on that. I would guess that setting this means we're entering much less well tested logic in devmapper. IOW if we are in the right namespace, we should definitely keep the udev synchronization.

What we could do instead here is

    let pid1ipcns = std::fs::File::open("/proc/1/ns/ipc").context("open pid1 icons")?;
    rustix::thread::move_into_link_name_space(
        pid1ipcns.as_fd(),
        Some(rustix::thread::LinkNameSpaceType::Ipc),
    )
    .context("setns")?;

We should do that really first thing here.

Though it'd be better to detect when we're already in the namespace, and no-op then.

}
Ok(())
}

Expand Down
6 changes: 3 additions & 3 deletions docs/src/bootc-install.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,15 @@ to an existing system and install your container image. Failure to run
Here's an example of using `bootc install` (root/elevated permission required):

```bash
podman run --rm --privileged --pid=host -v /var/lib/containers:/var/lib/containers -v /dev:/dev --security-opt label=type:unconfined_t <image> bootc install to-disk /path/to/disk
podman run --rm --privileged --pid=host --ipc=host -v /var/lib/containers:/var/lib/containers -v /dev:/dev --security-opt label=type:unconfined_t <image> bootc install to-disk /path/to/disk
```

Note that while `--privileged` is used, this command will not perform any
destructive action on the host system. Among other things, `--privileged`
makes sure that all host devices are mounted into container. `/path/to/disk` is
the host's block device where `<image>` will be installed on.

The `--pid=host --security-opt label=type:unconfined_t` today
The `--pid=host --ipc=host --security-opt label=type:unconfined_t` today
make it more convenient for bootc to perform some privileged
operations; in the future these requirements may be dropped.

Expand Down Expand Up @@ -191,7 +191,7 @@ process, you can create a raw disk image that you can boot via virtualization. R

```bash
truncate -s 10G myimage.raw
podman run --rm --privileged --pid=host --security-opt label=type:unconfined_t -v /dev:/dev -v /var/lib/containers:/var/lib/containers -v .:/output <yourimage> bootc install to-disk --generic-image --via-loopback /output/myimage.raw
podman run --rm --privileged --pid=host --ipc=host --security-opt label=type:unconfined_t -v /dev:/dev -v /var/lib/containers:/var/lib/containers -v .:/output <yourimage> bootc install to-disk --generic-image --via-loopback /output/myimage.raw
```

Notice that we use `--generic-image` for this use case.
Expand Down