Skip to content
Snippets Groups Projects

Correctly mount /proc when running in a Docker container (Closes: #921815)

Open Kristian Klausen requested to merge klausenbusk-guest/debootstrap:proc-fix into master
1 unresolved thread

Due to a missing check, we ended up symlinking $TARGET/proc -> /proc and calling umount on the symlink, and thus umounted the "hosts" /proc.

Merge request reports

Loading
Loading

Activity

Filter activity
  • Approvals
  • Assignees & reviewers
  • Comments (from bots)
  • Comments (from users)
  • Commits & branches
  • Edits
  • Labels
  • Lock status
  • Mentions
  • Merge request status
  • Tracking
  • Nitpick, but ! [ "$CONTAINER" = "docker" ] could be [ "$CONTAINER" != "docker" ] so there's only a single operator instead of 2.

  • added 1 commit

    • a9a603b1 - Correctly mount /proc when running in a Docker container (Closes: #921815)

    Compare with previous version

  • Nitpick, but ! [ "$CONTAINER" = "docker" ] could be [ "$CONTAINER" != "docker" ] so there's only a single operator instead of 2.

    Fixed

  • Kristian Klausen mentioned in merge request !27 (closed)

    mentioned in merge request !27 (closed)

  • Any idea when this will be merged? I'm trying to build a live ISO in Docker on Travis and running into a similar issue?

    W: Failure trying to run: chroot "/home/xx/chroot" mount -t proc proc /proc
    .
    .
    .
    .
    .
    .
    [2019-08-04 01:15:03] lb chroot_devpts install
    Begin mounting /dev/pts...
    mount: /home/xx/chroot/dev/pts: permission denied.
    [2019-08-04 01:15:03] lb chroot_proc install
    P: Begin mounting /proc...
    mount: /home/xx/chroot/proc: permission denied.
  • @kunalnagar-guest I typically use --cap-add SYS_ADMIN on containers that need to run debootstrap so they can do a proper mount and not rely on container-specific workarounds

  • @tianon It's not like Travis CI gave you the ability to add these options, like pretty much all SaaS CI.

    There are 3 merge requests at the moment for this issue: !26 !27 (closed) and !30 I'm pinging the last committer, @philh could you take a look at those please?

  • I guess my point is that many do (I do so in Travis CI quite frequently by doing docker run directly instead of relying on them to create me a container), so instead of detecting a "container", shouldn't we try to do some feature detection and fall back if (and only if) the mounts fail?

  • I'm not really grasping the issue. I'm running debootstrap 1.0.118ubuntu1.1 in an Ubuntu 20.04 image and can only reproduce the "unmounts host /proc" part in a privileged container. Confusingly, not even CAP_SYS_ADMIN seems required, it works just fine (and reproducible) in a regular container. $TARGET/proc is empty, though.

    In a container $TARGET/proc is symlinked to /proc here, the next umount $TARGET/proc will actually unmount /proc.

    The interesting part is, that the next umount $TARGET/proc actually occurs in setup_proc, which is called in a container as well, as the check wasn't expanded.

    setup_proc already ignores the error mounting proc – which seems to be fine as stated in the first paragraph. I'd say we should remove the umount $TARGET/proc in setup_proc. It looks like an ancient "just in case" command which probably always silently failed with either "not mounted" or "target is busy" until privileged docker containers.

    That said: I'd like to hear more details in case you have this issue in unprivileged containers as I cannot reproduce that.

  • That said: I'd like to hear more details in case you have this issue in unprivileged containers as I cannot reproduce that.

    I should have mentioned that. I'm using a privileged container so I can use loop devices (debootstrap is used as part of a script, which create a bootable Debian image).

    • I'll rest my case with that... !30 will be a symptom of !27 (closed), which is tricky, but apparently unrelated to this.

      This particular issue is caused by L1179 umount "$TARGET/proc" 2>/dev/null || true, which will attempt to umount the symlinked /proc, which only works in a privileged container.

      While this MR somehow fixes the issue and is reasonable, as mentioned before, I don't see the reason for that umount in the first place. And I am with @tianon, implicit environment checking should be preferred over specific container workarounds.


      I just went down further the rabbit hole: The symlinked /proc actually gets replaced right at the beginning of the second stage L130 when installing base-files. Apparently, most of the bootstrap works without /proc (and /sys) even present. Only Ubuntu failed because of rsyslogd in my tests.

      So, this is what happens:

      In any docker container, $TARGET/proc will be symlinked to /proc in the first stage. In an unprivileged container, unmounting /proc fails, ls -A "$TARGET/proc" is not empty and in_target mount -t proc proc /proc will be skipped, even with --cap-add SYS_ADMIN. Shortly after, the symlink is replaced by an empty directory.

      In a privileged container however, unmounting /proc succeeds, ls -A "$TARGET/proc" is empty and in_target mount -t proc proc /proc will be executed, correctly reporting a recursive symbolic link. The bootstrap will succeed, but host /proc is gone.


      As far as I can tell, neither the symlink nor the mount are actually required for the most part. This seems to work just as well – or even better, as it mounts /proc with --cap-add SYS_ADMIN. I'd even drop the whole setup_proc_symlink stuff – it doesn't work, it shouldn't work in fakechroot either.

      @@ -73,7 +73,7 @@ first_stage_install () {
       
              setup_devices
       
      -       if doing_variant fakechroot || [ "$CONTAINER" = "docker" ]; then
      +       if doing_variant fakechroot; then
                      setup_proc_symlink
              fi
       }
      Edited by Eicke Herbertz
    • Another variant of hotfix-disabling the symlink working with Ubuntu and Debian in one go (but also probably maybe breaking fakechroot?):

      --- a/functions
      +++ b/functions
      @@ -1201,8 +1201,7 @@ setup_proc () {
       }
       
       setup_proc_symlink () {
      -       rm -rf "$TARGET/proc"
      -       ln -s /proc "$TARGET"
      +       return 0
       }
       
       # create the static device nodes
      Edited by Eicke Herbertz
    • Turns out I'm proposing reverting 5a0f1666 as 1e7549c5 works around it.

      Edited by Eicke Herbertz
    • Please register or sign in to reply
  • Eicke Herbertz mentioned in merge request !70

    mentioned in merge request !70

Please register or sign in to reply
Loading