mirror of
https://git.savannah.gnu.org/git/guix.git
synced 2026-05-28 03:51:53 +02:00
daemon: Fix possible use-after-free.
This is essentially a backport of <https://github.com/NixOS/nix/commit/f52b6c944e90b3e35925122779175705fdc02e12> by Eelco Dolstra <eelco.dolstra@logicblox.com>. The use-after-free bug would typically manifest when building with GCC 5.1.
This commit is contained in:
+14
-6
@@ -852,16 +852,20 @@ void killUser(uid_t uid)
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
std::vector<const char *> stringsToCharPtrs(const Strings & ss)
|
||||
{
|
||||
std::vector<const char *> res;
|
||||
foreach (Strings::const_iterator, i, ss)
|
||||
res.push_back(i->c_str());
|
||||
res.push_back(0);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
string runProgram(Path program, bool searchPath, const Strings & args)
|
||||
{
|
||||
checkInterrupt();
|
||||
|
||||
std::vector<const char *> cargs; /* careful with c_str()! */
|
||||
cargs.push_back(program.c_str());
|
||||
for (Strings::const_iterator i = args.begin(); i != args.end(); ++i)
|
||||
cargs.push_back(i->c_str());
|
||||
cargs.push_back(0);
|
||||
|
||||
/* Create a pipe. */
|
||||
Pipe pipe;
|
||||
pipe.create();
|
||||
@@ -880,6 +884,10 @@ string runProgram(Path program, bool searchPath, const Strings & args)
|
||||
if (dup2(pipe.writeSide, STDOUT_FILENO) == -1)
|
||||
throw SysError("dupping stdout");
|
||||
|
||||
Strings args_(args);
|
||||
args_.push_front(program);
|
||||
auto cargs = stringsToCharPtrs(args_);
|
||||
|
||||
if (searchPath)
|
||||
execvp(program.c_str(), (char * *) &cargs[0]);
|
||||
else
|
||||
|
||||
@@ -257,6 +257,11 @@ void killUser(uid_t uid);
|
||||
string runProgram(Path program, bool searchPath = false,
|
||||
const Strings & args = Strings());
|
||||
|
||||
/* Convert a list of strings to a null-terminated vector of char
|
||||
*'s. The result must not be accessed beyond the lifetime of the
|
||||
list of strings. */
|
||||
std::vector<const char *> stringsToCharPtrs(const Strings & ss);
|
||||
|
||||
/* Close all file descriptors except stdin, stdout, stderr, and those
|
||||
listed in the given set. Good practice in child processes. */
|
||||
void closeMostFDs(const set<int> & exceptions);
|
||||
|
||||
Reference in New Issue
Block a user