https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=297426
--- Comment #8 from Devin Teske <[email protected]> --- (In reply to Alex S from comment #7) > I don't normally mount procfs at /proc, but there is no impact either > way. I repeated the exact Python test from your comment 3 while changing only the native procfs mount state. On this 16.0-CURRENT system, mount state directly changes the result. Test environment ---------------- kern.osreldate: 1600019 linux_base-rl9: 9.8 compat.linux.emul_path: /compat/linux unmodified source: 34718e01869b D58780 source: bec989b72aae The linprocfs module was rebuilt using the already-attached linux_rebuild2.sh and installed/reloaded using linux_reload2.sh. Exact Python reproduction ------------------------- With no native procfs mounted: $ mount | grep proc linprocfs on /compat/linux/proc (linprocfs, local) $ /compat/linux/usr/bin/python3.9 -c " import os print('readlink:', os.readlink('/proc/self/exe')) try: print('stat:', os.stat('/proc/self/exe')) except OSError as e: print('stat: FAIL --', e) try: os.execv('/proc/self/exe', ['python3', '-c', 'print(\"execv OK\")']) except OSError as e: print('execv: FAIL --', e) " readlink: /compat/linux/usr/bin/python3.9 stat: FAIL -- [Errno 2] No such file or directory: '/proc/self/exe' execv: FAIL -- [Errno 2] No such file or directory After mounting native procfs, with no other change: $ sudo mount -t procfs proc /proc $ mount | grep proc linprocfs on /compat/linux/proc (linprocfs, local) procfs on /proc (procfs, local) Running the same Python command then produces: readlink: /compat/linux/usr/bin/python3.9 stat: OK execv OK Thus native procfs mount state does affect the outcome: stat/execve change from ENOENT to success. The successful case still exposes the FreeBSD host path through readlink rather than the Linux-visible path. C litmus -------- The attached linux-proc-self-exe-litmus.c tests readlink, stat, access(X_OK), and execve independently. Install the Linux development tools and compile it as a Linux binary: $ sudo pkg install linux-rl9-devtools $ /compat/linux/usr/bin/gcc -O2 \ -o ~/linux-proc-self-exe-litmus \ ~/linux-proc-self-exe-litmus.c Run it first with its executable text outside the emulator root: $ ~/linux-proc-self-exe-litmus Create a Linux-side temporary directory under the emulator root. This directory is not created by default: $ sudo mkdir -p /compat/linux/tmp $ sudo chmod 1777 /compat/linux/tmp Copy the same binary beneath compat.linux.emul_path and run it using its FreeBSD host path: $ cp ~/linux-proc-self-exe-litmus /compat/linux/tmp/ $ /compat/linux/tmp/linux-proc-self-exe-litmus The program exits nonzero on failure and prints the result of readlink, stat, access(X_OK), and execve independently. Complete result matrix ---------------------- The complete observed matrix is: executable linprocfs native /proc readlink result verdict ------------ ----------- ------------- -------------------- ------- outside-emul unmodified absent host path FAIL outside-emul unmodified mounted host path PASS under-emul unmodified absent /compat/linux/... FAIL under-emul unmodified mounted /compat/linux/... FAIL (*) under-emul D58780 absent Linux-visible path PASS under-emul D58780 mounted Linux-visible path PASS (*) With native procfs mounted, stat/access/execve succeed through native-namespace fallback, but readlink still returns the host path including /compat/linux. The litmus therefore correctly reports failure: The Linuxulator should not expose FreeBSD host emulator configuration through /proc/self/exe. To emulate native Linux accurately, it should report the path in the process’s own namespace, improving compatibility with Linux binaries. Returning a host-only emulator prefix through an ABI-visible pathname is a Linuxulator implementation leak with no analogue in native Linux and is highly irregular for a Linux compatibility layer. Representative output --------------------- Unmodified linprocfs, executable outside emul_path, no native procfs: case: outside-emul readlink(/proc/self/exe) = /home/dteske/linux-proc-self-exe-litmus readlink: OK stat(/proc/self/exe): FAIL (No such file or directory) access(X_OK): FAIL (No such file or directory) execve(/proc/self/exe): FAIL VERDICT: FAIL (outside-emul) Unmodified linprocfs, executable outside emul_path, native procfs mounted: case: outside-emul readlink(/proc/self/exe) = /home/dteske/linux-proc-self-exe-litmus readlink: OK stat(/proc/self/exe): OK access(X_OK): OK execve(/proc/self/exe): OK VERDICT: PASS (outside-emul) Unmodified linprocfs, executable under emul_path, no native procfs: case: under-emul readlink(/proc/self/exe) = /compat/linux/tmp/linux-proc-self-exe-litmus readlink: FAIL (host path; expected the Linux namespace path) stat(/proc/self/exe): FAIL (No such file or directory) access(X_OK): FAIL (No such file or directory) execve(/proc/self/exe): FAIL VERDICT: FAIL (under-emul) Unmodified linprocfs, executable under emul_path, native procfs mounted: case: under-emul readlink(/proc/self/exe) = /compat/linux/tmp/linux-proc-self-exe-litmus readlink: FAIL (host path; expected the Linux namespace path) stat(/proc/self/exe): OK access(X_OK): OK execve(/proc/self/exe): OK VERDICT: FAIL (under-emul) D58780, executable under emul_path, no native procfs: case: under-emul readlink(/proc/self/exe) = /tmp/linux-proc-self-exe-litmus readlink: OK stat(/proc/self/exe): OK access(X_OK): OK execve(/proc/self/exe): OK VERDICT: PASS (under-emul) D58780, executable under emul_path, native procfs mounted: case: under-emul readlink(/proc/self/exe) = /tmp/linux-proc-self-exe-litmus readlink: OK stat(/proc/self/exe): OK access(X_OK): OK execve(/proc/self/exe): OK VERDICT: PASS (under-emul) Concrete consumer ----------------- This is not only a path-format discrepancy. www/linux-brave provides a concrete consumer of the failing follow operation. Brave is installed outside compat.linux.emul_path, under /usr/local/share/brave. Chromium starts helper processes by executing /proc/self/exe. Without procfs mounted at native /proc, that operation fails with ENOENT: LaunchProcess: failed to execvp: /proc/self/exe The GPU helper consequently exits and Brave cannot launch successfully. D58784 makes this requirement explicit by refusing to start www/linux-brave without native procfs and printing the required mount instructions. The two fixes address complementary cases: * Linux binaries outside compat.linux.emul_path, such as www/linux-brave, require procfs mounted at native /proc. * Linux binaries under compat.linux.emul_path should receive a Linux-visible /proc/self/exe target. D58780 supplies that behavior by stripping the emulator prefix. D58780 therefore does not attempt to replace native procfs for outside-emul binaries. It fixes the distinct under-emul case where linprocfs itself emits a target that is not valid in the process's Linux namespace. Mechanism and scope ------------------- proc_get_binpath() returns a FreeBSD host path. For executable text under the emulator root, unmodified linprocfs therefore reports a target such as: /compat/linux/usr/bin/python3.9 The Linux ABI first resolves that absolute path relative to compat.linux.emul_path, producing an initial lookup equivalent to: /compat/linux/compat/linux/usr/bin/python3.9 Without native procfs, following /proc/self/exe consequently fails with ENOENT. Native procfs can mask the follow operation through native-namespace fallback, but it cannot correct the readlink result. D58780 strips compat.linux.emul_path when the executable is beneath that root. The symlink then reports the Linux-visible path: /usr/bin/python3.9 That fixes readlink and makes stat/access/execve work regardless of whether native procfs is mounted. D58780 intentionally does not alter paths for executables outside the emulator root. Those require procfs mounted at native /proc. Making arbitrary FreeBSD host paths directly meaningful inside the Linux namespace is a separate and substantially broader problem and is not part of D58780. I am attaching the complete six output files underlying this matrix. If another system produces different results, please provide both `mount | grep proc` and the complete litmus output so the differing lookup path can be identified. Also, please provide for test env: 1. uname -K # for kernel version 2. pkg info linux_base-rl9 # for Linuxulator version -- You are receiving this mail because: You are the assignee for the bug.
