Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"enroot-mount: failed to open: /proc/self/fd/0: No such file or directory" on some peculiar settings #219

Open
gwangmu opened this issue Dec 2, 2024 · 2 comments

Comments

@gwangmu
Copy link

gwangmu commented Dec 2, 2024

Hello. Thank you for maintaining Enroot. :)

I'd like to report a baffling error message from Enroot with some exotic settings.

Symptom

I earlier tried to launch Enroot inside a Podman container and got this error message.

$ podman run --rm -it opensuse/leap:15.5
# # Install Enroot...
# enroot import docker://ubuntu
# enroot start ubuntu.sqsh
enroot-mount: failed to open: /proc/self/fd/0: No such file or directory

The base operating system was also OpenSUSE 15.5, and installing Enroot with Zypper had to break one dependency to glibc-common, but it was okay as long as glibc was installed. (i.e., Enroot worked well in an unnested setting on OpenSUSE 15.5)

Reason

I found the error was generated by runtime.sh:258,263,266 (here), which was further generated by enroot-mount.c:651 (here).

enroot-mount attempted to open stdin via /proc/self/fd/0 if fstab was provided via stdin either via a pipe (cat | enroot-mount) or via a direct here-string (enroot-mount <<<). In this case, the kernel first writes fstab to a temporary file, creates a symbolic link in /proc/self/fd/0, and removes the temporary file. I don't know the exact mechanism, but apparently, the symbolic link /proc/self/fd/0 is still valid after this removal. Even newly opening /proc/self/fd/0 seems okay in common settings, which runtime.sh actually uses when it feeds fstab via a here-string.

However, in this peculiar setting, opening /proc/self/fd/0 after the original temporary file was removed caused the error. Simply using Enroot on a bare OpenSUSE 15.5 (=no nested container) didn't generate the error, so I can only assume the nested container somehow affected this. (But I thought the inode management occurs at the kernel level... anyway)

Mitigation

While the reason was complex, the mitigation was really simple. It only required replacing all here-string usages with pipes, just like at runtime.c:216,231. For example, for runtime.sh:258,

cat <<EOF | enroot-mount
none ${_rootfs} none remount,bind,nosuid,nodev,ro
EOF

Proposal

Because the mitigation is so simple, and we're not sure which setting is causing this, I'd like to ask if Enroot can replace runtime.sh:258,263,266 with pipes. I also suspected that opening a removed temporary file is not a well-defined feature of the Linux kernel. If this is true, I thought keeping Enroot within the well-defined territory is better.

@3XX0
Copy link
Member

3XX0 commented Dec 4, 2024

Looks like an issue with podman, try running it with --tmpfs /tmp to make sure you're not writing the temporary file on the overlay.

@gwangmu
Copy link
Author

gwangmu commented Dec 5, 2024

Thank you, I'll try it soon. I thought Enroot won't have a problem because it's mounting a squashfs image. (I vaguely heard overlayfs on overlayfs doesn't work.) Could you explain why Enroot may still have issues on overlayfs?

Edit: I can confirm that mounting /tmp to bypass overlayfs worked well.

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

No branches or pull requests

2 participants