Subject: Absolute symlinks and binary emulation
To: None <tech-kern@NetBSD.org, tech-toolchain@NetBSD.org>
From: Quentin Garnier <cube@NetBSD.org>
List: tech-kern
Date: 06/17/2004 11:42:37
Hi,

Our binary emulation layer is slightly broken by the way absolute
symlinks are handled.

It can be easily demonstrated using compat_netbsd32 with a dynamic-root
netbsd32 system.  Binaries in /bin and /sbin works fine, but binaries in
/usr/bin fail, rejected by the interpreter.

The reason for this is they are linked against /usr/libexec/ld.elf_so,
which, under the emulation tree, is an absolute symlink to
/libexec/ld.elf_so.  That symlink gets interpreted verbatim, and thus
the host's interpreter is used, and of course, the binary get rejected.

The same happens with libraries, once the interpreter issue is
workarounded.

The problem is that while the compat layer has tools to check if a file
exists in the emulation tree or not, it doesn't follow the entire lookup
process, it just tries a lookup, and then another.  And since lookup()
doesn't know about emulation symlinks gets interpreted globally.

The issue of being able to launch any netbsd32 binaries directly from
the host can be solved by using relative symlinks inside /usr/lib and
/usr/libexec.  I know the discussion came up some time ago (in February,
actually), I just want to add a point in favor of the relative symlinks
position.

The other way to solve this, I think, is to add emulation awareness to
the namei system.  I haven't looked close enough to the way namei works,
but I think that an "alternative root" could be added to the nameidata,
and then lookup would try both alternatives.  That would make the
absolute symlinks be interpreted at the emulation root first.

That would also avoid the use of the somewhat hacky emul_find, and we
wouldn't need to use CHECK_ALT* macros in all releveant syscall
emulations.

Comments?

Quentin Garnier.