guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

01/05: daemon: Try to execute derivation builders only for matching OS k


From: guix-commits
Subject: 01/05: daemon: Try to execute derivation builders only for matching OS kernels.
Date: Thu, 1 Oct 2020 06:47:42 -0400 (EDT)

civodul pushed a commit to branch master
in repository guix.

commit 9556ac498fd648147ad7d3b52ec86202d0a8e171
Author: Ludovic Courtès <ludo@gnu.org>
AuthorDate: Thu Oct 1 11:17:12 2020 +0200

    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 7bf2a70a4ffd976d50638d3b9f2ec409763157df.
    
    * nix/libstore/build.cc (sameOperatingSystemKernel): New function.
    (DerivationGoal::runChild): Call 'execve' only when
    'sameOperatingSystemKernel' returns true.
---
 nix/libstore/build.cc | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc
index 88f8d11..ccec513d 100644
--- a/nix/libstore/build.cc
+++ b/nix/libstore/build.cc
@@ -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()
 {
@@ -2208,9 +2217,20 @@ void DerivationGoal::runChild()
         foreach (Strings::iterator, i, drv.args)
             args.push_back(rewriteHashes(*i, rewritesToTmp));
 
-        execve(drv.builder.c_str(), stringsToCharPtrs(args).data(), 
stringsToCharPtrs(envStrs).data());
-
-       int error = errno;
+       /* 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
+          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
           transparent emulation of different platforms with binfmt_misc



reply via email to

[Prev in Thread] Current Thread [Next in Thread]