4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-28 20:15:24 +08:00
Terraneo Federico 987d040394 Lift 256 arg limit in execl, execle and execlp
add --enable-newlib-use-malloc-in-execl option

The previous version of these functions allocated a 256 entry array and
copied arguments in that array with no bound checking. That
implementation always occupied 1024 bytes of stack for the array even in
the common case in which the number of passed arguments is far less than
256, risking stack overflows in environments with small stacks, and
caused a stack buffer overflow if called with more than 256 arguments.

The improved implementation counts the actual number of passed arguments
and allocates a suitable buffer. The default implementation uses alloca
to allocate the buffer to satisfy the POSIX.1-2008 requirement that
execl and execle should be callable from signal handlers, but it is
possible to override this behavior and use malloc for targets where the
risk of stack overflow due to unbounded stack allocations is a more
pressing requirement than the corner case of allowing execl calls from
signal handlers.
2025-02-03 12:43:51 +01:00

63 lines
1003 B
C

#ifndef _NO_EXECVE
/* execlp.c */
/* This and the other exec*.c files in this directory require
the target to provide the _execve syscall. */
#include <_ansi.h>
#include <unistd.h>
#ifdef _EXECL_USE_MALLOC
#include <errno.h>
#include <stdlib.h>
#else
#include <alloca.h>
#endif
#include <stdarg.h>
int
execlp (const char *path,
const char *arg0, ...)
{
int i;
va_list args;
const char **argv;
i = 1;
va_start (args, arg0);
do
i++;
while (va_arg (args, const char *) != NULL);
va_end (args);
#ifndef _EXECL_USE_MALLOC
argv = alloca (i * sizeof(const char *));
#else
argv = malloc (i * sizeof(const char *));
if (argv == NULL)
{
errno = ENOMEM;
return -1;
}
#endif
va_start (args, arg0);
argv[0] = arg0;
i = 1;
do
argv[i] = va_arg (args, const char *);
while (argv[i++] != NULL);
va_end (args);
i = execvp (path, (char * const *) argv);
#ifdef _EXECL_USE_MALLOC
free (argv);
#endif
return i;
}
#endif /* !_NO_EXECVE */