]> git.ipfire.org Git - thirdparty/snapper.git/commitdiff
- avoid setenv after fork (bsc#1107587) 427/head
authorArvin Schnell <aschnell@suse.de>
Fri, 14 Sep 2018 10:16:11 +0000 (12:16 +0200)
committerArvin Schnell <aschnell@suse.de>
Fri, 14 Sep 2018 10:16:11 +0000 (12:16 +0200)
package/snapper.changes
snapper/SystemCmd.cc
snapper/SystemCmd.h

index 336c2e44e29d049e4ea8357910a07337c9d5a5be..aaf41e4a96db372d688ae777313363f89754bb2e 100644 (file)
@@ -1,3 +1,8 @@
+-------------------------------------------------------------------
+Fri Sep 14 12:13:05 CEST 2018 - aschnell@suse.com
+
+- avoid setenv after fork (bsc#1107587)
+
 -------------------------------------------------------------------
 Mon Jul 23 20:52:26 CEST 2018 - aschnell@suse.com
 
index 83612bb9e410bc58649ad438806ce594091536b2..223794795a68d7fc111029de179612cf8ae5fed9 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) [2004-2011] Novell, Inc.
+ * Copyright (c) 2018 SUSE LLC
  *
  * All Rights Reserved.
  *
@@ -30,6 +31,8 @@
 #include <string>
 #include <boost/algorithm/string.hpp>
 
+extern char **environ;
+
 #include "snapper/Log.h"
 #include "snapper/AppUtil.h"
 #include "snapper/SystemCmd.h"
@@ -205,11 +208,12 @@ SystemCmd::doExecute( const string& Cmd )
                }
            }
        y2deb("sout:" << pfds[0].fd << " serr:" << (Combine_b?-1:pfds[1].fd));
+
+       const vector<const char*> env = make_env();
+
        switch( (Pid_i=fork()) )
            {
            case 0:
-               setenv( "LC_ALL", "C", 1 );
-               setenv( "LANGUAGE", "C", 1 );
                if( dup2( sout[1], STDOUT_FILENO )<0 )
                    {
                    y2err("dup2 stdout child failed errno:" << errno << " (" << stringerror(errno) << ")");
@@ -231,8 +235,7 @@ SystemCmd::doExecute( const string& Cmd )
                    y2err("close child failed errno:" << errno << " (" << stringerror(errno) << ")");
                    }
                closeOpenFds();
-               Ret_i = execl( Shell_Ci.c_str(), Shell_Ci.c_str(), "-c",
-                              Cmd.c_str(), NULL );
+               Ret_i = execle(Shell_Ci.c_str(), Shell_Ci.c_str(), "-c", Cmd.c_str(), nullptr, &env[0]);
                y2err("SHOULD NOT HAPPEN \"" << Shell_Ci << "\" Ret:" << Ret_i);
                break;
            case -1:
@@ -567,6 +570,27 @@ SystemCmd::logOutput() const
 }
 
 
+    vector<const char*>
+    SystemCmd::make_env() const
+    {
+       vector<const char*> env;
+
+       for (char** v = environ; *v != NULL; ++v)
+       {
+           if (strncmp(*v, "LC_ALL=", strlen("LC_ALL=")) != 0 &&
+               strncmp(*v, "LANGUAGE=", strlen("LANGUAGE=")) != 0)
+               env.push_back(*v);
+       }
+
+       env.push_back("LC_ALL=C");
+       env.push_back("LANGUAGE=C");
+
+       env.push_back(nullptr);
+
+       return env;
+    }
+
+
 string
 SystemCmd::quote(const string& str)
 {
index 0b812ff3cac57f405d9f75daa851f953843a513e..91bffb3f835d94a125af97b7e86ebe67b59ec1a1 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) [2004-2014] Novell, Inc.
+ * Copyright (c) 2018 SUSE LLC
  *
  * All Rights Reserved.
  *
@@ -101,6 +102,16 @@ namespace snapper
 
        void logOutput() const;
 
+       /**
+        * Constructs the environment for the child process.
+        *
+        * Must not be called after exec since allocating the memory
+        * for the vector is not allowed then (in a multithreaded
+        * program), see fork(2) and signal-safety(7). So simply call
+        * it right before fork.
+        */
+       vector<const char*> make_env() const;
+
        FILE* File_aC[2];
        std::vector<string> Lines_aC[2];
        std::vector<string*> SelLines_aC[2];