std.process: Fix memory corruption in exec functions

Fixes issue #10639.
This commit is contained in:
Vladimir Panteleev 2025-02-17 20:48:27 +00:00 committed by The Dlang Bot
parent ea28abfadb
commit bb0c2953dd

View file

@ -4315,14 +4315,14 @@ version (Posix)
import core.sys.posix.stdlib; import core.sys.posix.stdlib;
} }
private void toAStringz(in string[] a, const(char)**az) private const(char)** toAStringz(in string[] a)
{ {
import std.string : toStringz; import std.string : toStringz;
foreach (string s; a) auto p = (new const(char)*[1 + a.length]).ptr;
{ foreach (i, string s; a)
*az++ = toStringz(s); p[i] = toStringz(s);
} p[a.length] = null;
*az = null; return p;
} }
@ -4452,45 +4452,17 @@ extern(C)
private int execv_(in string pathname, in string[] argv) private int execv_(in string pathname, in string[] argv)
{ {
import core.exception : OutOfMemoryError; return execv(pathname.tempCString(), toAStringz(argv));
import std.exception : enforce;
auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length));
enforce!OutOfMemoryError(argv_ !is null, "Out of memory in std.process.");
scope(exit) core.stdc.stdlib.free(argv_);
toAStringz(argv, argv_);
return execv(pathname.tempCString(), argv_);
} }
private int execve_(in string pathname, in string[] argv, in string[] envp) private int execve_(in string pathname, in string[] argv, in string[] envp)
{ {
import core.exception : OutOfMemoryError; return execve(pathname.tempCString(), toAStringz(argv), toAStringz(envp));
import std.exception : enforce;
auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length));
enforce!OutOfMemoryError(argv_ !is null, "Out of memory in std.process.");
scope(exit) core.stdc.stdlib.free(argv_);
auto envp_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + envp.length));
enforce!OutOfMemoryError(envp_ !is null, "Out of memory in std.process.");
scope(exit) core.stdc.stdlib.free(envp_);
toAStringz(argv, argv_);
toAStringz(envp, envp_);
return execve(pathname.tempCString(), argv_, envp_);
} }
private int execvp_(in string pathname, in string[] argv) private int execvp_(in string pathname, in string[] argv)
{ {
import core.exception : OutOfMemoryError; return execvp(pathname.tempCString(), toAStringz(argv));
import std.exception : enforce;
auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length));
enforce!OutOfMemoryError(argv_ !is null, "Out of memory in std.process.");
scope(exit) core.stdc.stdlib.free(argv_);
toAStringz(argv, argv_);
return execvp(pathname.tempCString(), argv_);
} }
private int execvpe_(in string pathname, in string[] argv, in string[] envp) private int execvpe_(in string pathname, in string[] argv, in string[] envp)
@ -4532,19 +4504,7 @@ version (Posix)
} }
else version (Windows) else version (Windows)
{ {
import core.exception : OutOfMemoryError; return execvpe(pathname.tempCString(), toAStringz(argv), toAStringz(envp));
import std.exception : enforce;
auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length));
enforce!OutOfMemoryError(argv_ !is null, "Out of memory in std.process.");
scope(exit) core.stdc.stdlib.free(argv_);
auto envp_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + envp.length));
enforce!OutOfMemoryError(envp_ !is null, "Out of memory in std.process.");
scope(exit) core.stdc.stdlib.free(envp_);
toAStringz(argv, argv_);
toAStringz(envp, envp_);
return execvpe(pathname.tempCString(), argv_, envp_);
} }
else else
{ {