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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.