From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7868) id D1D2A3858D33; Mon, 28 Aug 2023 16:00:52 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D1D2A3858D33 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1693238452; bh=OguiAQhtylSD2TIYzIyy6GJ/OPcE5sGlUvgIwXc7+PU=; h=From:To:Subject:Date:From; b=wg9hpOJzFZdpYChwEGiS7oB9OCbYPL5hvZTh6uDBihHRgCGNEzvegrIkae8ITzBMS 0krQ3SAQS/LPBYy22wgpdOcnT7kriIi4HqOLJ+yrEK/jtFGe5mOG59E0JYpMtZ2qSO lG21w4qgr3TPA0Lo4JYoTN2S2vRHLp+8GRvcEGtY= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Takashi Yano To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin/cygwin-3_4-branch] Cygwin: Fix segfalt when too many command line args are specified. X-Act-Checkin: newlib-cygwin X-Git-Author: Takashi Yano X-Git-Refname: refs/heads/cygwin-3_4-branch X-Git-Oldrev: 208c3f68a30a7ab6cc53f30f8a119694ed29c866 X-Git-Newrev: 33cddf77974f9849cf8edafe9b3da46591b73d6e Message-Id: <20230828160052.D1D2A3858D33@sourceware.org> Date: Mon, 28 Aug 2023 16:00:52 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3D33cddf77974= f9849cf8edafe9b3da46591b73d6e commit 33cddf77974f9849cf8edafe9b3da46591b73d6e Author: Takashi Yano Date: Mon Aug 28 22:14:41 2023 +0900 Cygwin: Fix segfalt when too many command line args are specified. =20 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 =20 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. =20 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. =20 Reported-by: Ed Morton Reviewed-by: Corinna Vinschen Signed-off-by: Takashi Yano Diff: --- winsup/cygwin/dcrt0.cc | 7 ++----- winsup/cygwin/local_includes/winsup.h | 4 ++++ winsup/cygwin/release/3.4.9 | 3 +++ winsup/cygwin/spawn.cc | 9 ++++++++- winsup/cygwin/sysconf.cc | 2 +- 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 49b7a44ae..1d8810546 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -978,11 +978,8 @@ dll_crt0_1 (void *) 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 affect Cygwin. This is similar (but not exactly like) Linux. */ - char *newargv[__argc + 1]; - char **nav =3D newargv; - char **oav =3D __argv; - while ((*nav++ =3D *oav++) !=3D NULL) - continue; + char **newargv =3D (char **) malloc ((__argc + 1) * sizeof (char *)); + memcpy (newargv, __argv, (__argc + 1) * sizeof (char *)); /* Handle any signals which may have arrived */ sig_dispatch_pending (false); _my_tls.call_signal_handler (); diff --git a/winsup/cygwin/local_includes/winsup.h b/winsup/cygwin/local_in= cludes/winsup.h index 43dfbf46f..2d51722f3 100644 --- a/winsup/cygwin/local_includes/winsup.h +++ b/winsup/cygwin/local_includes/winsup.h @@ -68,6 +68,10 @@ uint32_t cygwin_inet_addr (const char *cp); application provided path strings we handle. */ #define NT_MAX_PATH 32768 =20 +/* 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 parameters. See the definition of __CONCAT in newlib's sys/cdefs.h and accompanying comment. */ diff --git a/winsup/cygwin/release/3.4.9 b/winsup/cygwin/release/3.4.9 index 2f2da9e13..53c4e5fc8 100644 --- a/winsup/cygwin/release/3.4.9 +++ b/winsup/cygwin/release/3.4.9 @@ -8,3 +8,6 @@ Bug Fixes - For the time being, disable creating special files using mknod/mkfifo on NFS. 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 diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 32ba5b377..c4888e823 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -340,8 +340,9 @@ child_info_spawn::worker (const char *prog_arg, const c= har *const *argv, We need to quote any argument that has whitespace or embedded "'s. */ =20 int ac; + size_t arg_len =3D 0; for (ac =3D 0; argv[ac]; ac++) - /* nothing */; + arg_len +=3D strlen (argv[ac]) + 1; =20 int err; const char *ext; @@ -510,6 +511,12 @@ child_info_spawn::worker (const char *prog_arg, const = char *const *argv, __leave; } set (chtype, real_path.iscygexec ()); + if (iscygwin () && arg_len > (size_t) sysconf (_SC_ARG_MAX)) + { + set_errno (E2BIG); + res =3D -1; + __leave; + } __stdin =3D in__stdin; __stdout =3D in__stdout; record_children (); diff --git a/winsup/cygwin/sysconf.cc b/winsup/cygwin/sysconf.cc index 2db92e4de..7cdfbdb9d 100644 --- a/winsup/cygwin/sysconf.cc +++ b/winsup/cygwin/sysconf.cc @@ -485,7 +485,7 @@ static struct }; } sca[] =3D { - {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:CLOCKS_PER_SEC}}, /* 2, _SC_CLK_TCK */ {cons, {c:NGROUPS_MAX}}, /* 3, _SC_NGROUPS_MAX */