daemon: Try to execute derivation builders only for matching OS kernels.
Fixes <https://bugs.gnu.org/43668>.
Previously, guix-daemon would try to run GNU/Hurd executables on
GNU/Linux. execve(2) would succeed, but the executable would
immediately crash.
This change prevents it from attempting to execute "i586-gnu" code on
"*-linux", while preserving the binfmt_misc-friendly behavior
implemented in commit 7bf2a70a4f
.
* nix/libstore/build.cc (sameOperatingSystemKernel): New function.
(DerivationGoal::runChild): Call 'execve' only when
'sameOperatingSystemKernel' returns true.
master
parent
905a2ff0c5
commit
9556ac498f
|
@ -1946,6 +1946,15 @@ void DerivationGoal::startBuilder()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return true if the operating system kernel part of SYSTEM1 and SYSTEM2 (the
|
||||||
|
bit that comes after the hyphen in system types such as "i686-linux") is
|
||||||
|
the same. */
|
||||||
|
static bool sameOperatingSystemKernel(const std::string& system1, const std::string& system2)
|
||||||
|
{
|
||||||
|
auto os1 = system1.substr(system1.find("-"));
|
||||||
|
auto os2 = system2.substr(system2.find("-"));
|
||||||
|
return os1 == os2;
|
||||||
|
}
|
||||||
|
|
||||||
void DerivationGoal::runChild()
|
void DerivationGoal::runChild()
|
||||||
{
|
{
|
||||||
|
@ -2208,9 +2217,20 @@ void DerivationGoal::runChild()
|
||||||
foreach (Strings::iterator, i, drv.args)
|
foreach (Strings::iterator, i, drv.args)
|
||||||
args.push_back(rewriteHashes(*i, rewritesToTmp));
|
args.push_back(rewriteHashes(*i, rewritesToTmp));
|
||||||
|
|
||||||
execve(drv.builder.c_str(), stringsToCharPtrs(args).data(), stringsToCharPtrs(envStrs).data());
|
/* If DRV targets the same operating system kernel, try to execute it:
|
||||||
|
there might be binfmt_misc set up for user-land emulation of other
|
||||||
int error = errno;
|
architectures. However, if it targets a different operating
|
||||||
|
system--e.g., "i586-gnu" vs. "x86_64-linux"--do not try executing
|
||||||
|
it: the ELF file for that OS is likely indistinguishable from a
|
||||||
|
native ELF binary and it would just crash at run time. */
|
||||||
|
int error;
|
||||||
|
if (sameOperatingSystemKernel(drv.platform, settings.thisSystem)) {
|
||||||
|
execve(drv.builder.c_str(), stringsToCharPtrs(args).data(),
|
||||||
|
stringsToCharPtrs(envStrs).data());
|
||||||
|
error = errno;
|
||||||
|
} else {
|
||||||
|
error = ENOEXEC;
|
||||||
|
}
|
||||||
|
|
||||||
/* Right platform? Check this after we've tried 'execve' to allow for
|
/* Right platform? Check this after we've tried 'execve' to allow for
|
||||||
transparent emulation of different platforms with binfmt_misc
|
transparent emulation of different platforms with binfmt_misc
|
||||||
|
|
Reference in New Issue