Skip to content

Commit

Permalink
Fix Issue 16955 - std.process.spawnProcessImpl can crash due to alloca
Browse files Browse the repository at this point in the history
  • Loading branch information
John-Colvin committed Dec 9, 2016
1 parent 9939897 commit aec837b
Showing 1 changed file with 12 additions and 25 deletions.
37 changes: 12 additions & 25 deletions std/process.d
Expand Up @@ -450,6 +450,7 @@ private Pid spawnProcessImpl(in char[][] args,
{
import core.sys.posix.poll : pollfd, poll, POLLNVAL;
import core.sys.posix.sys.resource : rlimit, getrlimit, RLIMIT_NOFILE;
import core.stdc.stdlib : malloc;

// Get the maximum number of file descriptors that could be open.
rlimit r;
Expand All @@ -465,36 +466,22 @@ private Pid spawnProcessImpl(in char[][] args,
immutable maxToClose = maxDescriptors - 3;

// Call poll() to see which ones are actually open:
// Done as an internal function because MacOS won't allow
// alloca and exceptions to mix.
@nogc nothrow
static bool pollClose(int maxToClose)
pollfd* pfds = cast(pollfd*)malloc(pollfd.sizeof * maxToClose);
foreach (i; 0 .. maxToClose)
{
pfds[i].fd = i + 3;
pfds[i].events = 0;
pfds[i].revents = 0;
}
if (poll(pfds, maxToClose, 0) >= 0)
{
import core.stdc.stdlib : alloca;

pollfd* pfds = cast(pollfd*)alloca(pollfd.sizeof * maxToClose);
foreach (i; 0 .. maxToClose)
{
pfds[i].fd = i + 3;
pfds[i].events = 0;
pfds[i].revents = 0;
}
if (poll(pfds, maxToClose, 0) >= 0)
{
foreach (i; 0 .. maxToClose)
{
// POLLNVAL will be set if the file descriptor is invalid.
if (!(pfds[i].revents & POLLNVAL)) close(pfds[i].fd);
}
return true;
}
else
{
return false;
// POLLNVAL will be set if the file descriptor is invalid.
if (!(pfds[i].revents & POLLNVAL)) close(pfds[i].fd);
}
}

if (!pollClose(maxToClose))
else
{
// Fall back to closing everything.
foreach (i; 3 .. maxDescriptors) close(i);
Expand Down

0 comments on commit aec837b

Please sign in to comment.