From: Arvin Schnell Date: Fri, 14 Sep 2018 10:16:11 +0000 (+0200) Subject: - avoid setenv after fork (bsc#1107587) X-Git-Tag: v0.6.0~4^2 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=1d47bcbee58dc8a5a220fe2aa207dea5d943dd12;p=thirdparty%2Fsnapper.git - avoid setenv after fork (bsc#1107587) --- diff --git a/package/snapper.changes b/package/snapper.changes index 336c2e44..aaf41e4a 100644 --- a/package/snapper.changes +++ b/package/snapper.changes @@ -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 diff --git a/snapper/SystemCmd.cc b/snapper/SystemCmd.cc index 83612bb9..22379479 100644 --- a/snapper/SystemCmd.cc +++ b/snapper/SystemCmd.cc @@ -1,5 +1,6 @@ /* * Copyright (c) [2004-2011] Novell, Inc. + * Copyright (c) 2018 SUSE LLC * * All Rights Reserved. * @@ -30,6 +31,8 @@ #include #include +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 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 + SystemCmd::make_env() const + { + vector 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) { diff --git a/snapper/SystemCmd.h b/snapper/SystemCmd.h index 0b812ff3..91bffb3f 100644 --- a/snapper/SystemCmd.h +++ b/snapper/SystemCmd.h @@ -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 make_env() const; + FILE* File_aC[2]; std::vector Lines_aC[2]; std::vector SelLines_aC[2];