Cygwin: Fix segfalt when too many command line args are specified.
Previously, the number of command line args was not checked for cygwin process. Due to this, segmentation fault was caused if too many command line args are specified. https://cygwin.com/pipermail/cygwin/2023-August/254333.html Since char *argv[argc + 1] is placed on the stack in dll_crt0_1(), STATUS_STACK_OVERFLOW occurs if the stack does not have enough space. With this patch, char *argv[] is placed in heap instead of stack and ARG_MAX is increased from 32000 to 2097152 which is default value of Linux. The argument length is also compared with ARG_MAX and spawnve() returns E2BIG if it is too long. Reported-by: Ed Morton Reviewed-by: Corinna Vinschen <corinna@vinschen.de> Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
This commit is contained in:
parent
50ff7901a5
commit
44f73c5a62
|
@ -978,11 +978,8 @@ dll_crt0_1 (void *)
|
||||||
a change to an element of argv[] it does not affect Cygwin's argv.
|
a change to an element of argv[] it does not affect Cygwin's argv.
|
||||||
Changing the the contents of what argv[n] points to will still
|
Changing the the contents of what argv[n] points to will still
|
||||||
affect Cygwin. This is similar (but not exactly like) Linux. */
|
affect Cygwin. This is similar (but not exactly like) Linux. */
|
||||||
char *newargv[__argc + 1];
|
char **newargv = (char **) malloc ((__argc + 1) * sizeof (char *));
|
||||||
char **nav = newargv;
|
memcpy (newargv, __argv, (__argc + 1) * sizeof (char *));
|
||||||
char **oav = __argv;
|
|
||||||
while ((*nav++ = *oav++) != NULL)
|
|
||||||
continue;
|
|
||||||
/* Handle any signals which may have arrived */
|
/* Handle any signals which may have arrived */
|
||||||
sig_dispatch_pending (false);
|
sig_dispatch_pending (false);
|
||||||
_my_tls.call_signal_handler ();
|
_my_tls.call_signal_handler ();
|
||||||
|
|
|
@ -73,6 +73,10 @@ uint32_t cygwin_inet_addr (const char *cp);
|
||||||
application provided path strings we handle. */
|
application provided path strings we handle. */
|
||||||
#define NT_MAX_PATH 32768
|
#define NT_MAX_PATH 32768
|
||||||
|
|
||||||
|
/* CYG_ARG_MAX is the maximum total length of command line args.
|
||||||
|
The value 2097152 is the default ARG_MAX value in Linux. */
|
||||||
|
#define CYG_ARG_MAX 2097152
|
||||||
|
|
||||||
/* This definition allows to define wide char strings using macros as
|
/* This definition allows to define wide char strings using macros as
|
||||||
parameters. See the definition of __CONCAT in newlib's sys/cdefs.h
|
parameters. See the definition of __CONCAT in newlib's sys/cdefs.h
|
||||||
and accompanying comment. */
|
and accompanying comment. */
|
||||||
|
|
|
@ -8,3 +8,6 @@ Bug Fixes
|
||||||
- For the time being, disable creating special files using mknod/mkfifo
|
- For the time being, disable creating special files using mknod/mkfifo
|
||||||
on NFS.
|
on NFS.
|
||||||
Addresses: https://cygwin.com/pipermail/cygwin/2023-August/254266.html
|
Addresses: https://cygwin.com/pipermail/cygwin/2023-August/254266.html
|
||||||
|
|
||||||
|
- Fix segfault when too many command line args are specified.
|
||||||
|
Addresses: https://cygwin.com/pipermail/cygwin/2023-August/254333.html
|
||||||
|
|
|
@ -351,8 +351,9 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
||||||
We need to quote any argument that has whitespace or embedded "'s. */
|
We need to quote any argument that has whitespace or embedded "'s. */
|
||||||
|
|
||||||
int ac;
|
int ac;
|
||||||
|
size_t arg_len = 0;
|
||||||
for (ac = 0; argv[ac]; ac++)
|
for (ac = 0; argv[ac]; ac++)
|
||||||
/* nothing */;
|
arg_len += strlen (argv[ac]) + 1;
|
||||||
|
|
||||||
int err;
|
int err;
|
||||||
const char *ext;
|
const char *ext;
|
||||||
|
@ -521,6 +522,12 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
||||||
__leave;
|
__leave;
|
||||||
}
|
}
|
||||||
set (chtype, real_path.iscygexec ());
|
set (chtype, real_path.iscygexec ());
|
||||||
|
if (iscygwin () && arg_len > (size_t) sysconf (_SC_ARG_MAX))
|
||||||
|
{
|
||||||
|
set_errno (E2BIG);
|
||||||
|
res = -1;
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
__stdin = in__stdin;
|
__stdin = in__stdin;
|
||||||
__stdout = in__stdout;
|
__stdout = in__stdout;
|
||||||
record_children ();
|
record_children ();
|
||||||
|
|
|
@ -485,7 +485,7 @@ static struct
|
||||||
};
|
};
|
||||||
} sca[] =
|
} sca[] =
|
||||||
{
|
{
|
||||||
{cons, {c:ARG_MAX}}, /* 0, _SC_ARG_MAX */
|
{cons, {c:CYG_ARG_MAX}}, /* 0, _SC_ARG_MAX */
|
||||||
{cons, {c:CHILD_MAX}}, /* 1, _SC_CHILD_MAX */
|
{cons, {c:CHILD_MAX}}, /* 1, _SC_CHILD_MAX */
|
||||||
{cons, {c:CLOCKS_PER_SEC}}, /* 2, _SC_CLK_TCK */
|
{cons, {c:CLOCKS_PER_SEC}}, /* 2, _SC_CLK_TCK */
|
||||||
{cons, {c:NGROUPS_MAX}}, /* 3, _SC_NGROUPS_MAX */
|
{cons, {c:NGROUPS_MAX}}, /* 3, _SC_NGROUPS_MAX */
|
||||||
|
|
Loading…
Reference in New Issue