linux(4): Add compat.linux32.emulate_i386 knob.

Historically 32-bit Linuxulator under amd64 emulated the real i386
behavior. Since 3d8dd983 the old i386 Linux world can't be used under
amd64 Linuxulator as it don't know anything about amd64 machine (which
is returned now by newuname() syscall). So, add a knob to allow to swith
the behavior and use i386 Linux binaries on amd64.
Set knob to the new behavior as I think this is common to the modern
Linux distros.

Reviewed by:		Pau Amma (doc), emaste
Differential revision:	https://reviews.freebsd.org/D34708
MFC after:		2 weeks
This commit is contained in:
Dmitry Chagin 2022-03-31 21:01:09 +03:00
parent 099fa2feb3
commit d5dc757e84
4 changed files with 16 additions and 0 deletions

View File

@ -145,6 +145,12 @@ This might be reasonable or even required, because
does not emulate the Linux environment completely, and missed features
may result in security vulnerabilities.
Defaults to 1.
.It Va compat.linux32.emulate_i386
In the x86_64 (amd64) world enable the real i386 Linuxulator behavior.
For example, when set to 0, Linux uname -m will return "x86_64" even if
uname itself is a i386 Linux executable. When set to 1, Linux i386
uname -m will return "i686".
Defaults to 0.
.El
.Sh FILES
.Bl -tag -width /compat/linux/dev/shm -compact

View File

@ -637,4 +637,6 @@ struct reg32;
void bsd_to_linux_regset32(const struct reg32 *b_reg,
struct linux_pt_regset32 *l_regset);
extern bool linux32_emulate_i386;
#endif /* !_AMD64_LINUX_H_ */

View File

@ -885,6 +885,9 @@ SYSCTL_ULONG(_compat_linux32, OID_AUTO, maxssiz, CTLFLAG_RW,
static u_long linux32_maxvmem = LINUX32_MAXVMEM;
SYSCTL_ULONG(_compat_linux32, OID_AUTO, maxvmem, CTLFLAG_RW,
&linux32_maxvmem, 0, "");
bool linux32_emulate_i386 = false;
SYSCTL_BOOL(_compat_linux32, OID_AUTO, emulate_i386, CTLFLAG_RWTUN,
&linux32_emulate_i386, 0, "Emulate the real i386");
static void
linux32_fixlimit(struct rlimit *rl, int which)

View File

@ -720,6 +720,11 @@ linux_newuname(struct thread *td, struct linux_newuname_args *args)
* the string returned by getauxval(AT_PLATFORM) needs
* to remain "i686", though.
*/
#if defined(COMPAT_LINUX32)
if (linux32_emulate_i386)
strlcpy(utsname.machine, "i686", LINUX_MAX_UTSNAME);
else
#endif
strlcpy(utsname.machine, "x86_64", LINUX_MAX_UTSNAME);
#elif defined(__aarch64__)
strlcpy(utsname.machine, "aarch64", LINUX_MAX_UTSNAME);