[newlib-cygwin/main] Cygwin: ssp: Move command-line copy into run_program

Jon Turney via Cygwin-cvs <[email protected]> Tue, 30 Jun 2026 18:13:10 +0000 (GMT)
Newsgroups gmane.os.cygwin.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3De5dd6526360=
935740553ac92b5ca589fd8cb79b9

commit e5dd6526360935740553ac92b5ca589fd8cb79b9
Author: Chandru Kumaresan <chandru.kumaresan-ftNtnR/FhrXEC4y91aVriVaTQe2KTcn/@public.gmane.org>
Date:   Thu Jun 25 17:26:44 2026 +0530

    Cygwin: ssp: Move command-line copy into run_program
   =20
    The previous patch duplicated argv[optind] in main() before passing it =
to
    run_program(), but run_program() immediately assigns the received point=
er
    to dll_info[0].name and then passes the same pointer to CreateProcess.
    Since CreateProcess (with lpApplicationName =3D=3D NULL) may modify its
    lpCommandLine buffer in place, dll_info[0].name could end up pointing at
    corrupted data, producing a mangled name in the DLL-profile table.
   =20
    Fix this by performing the strdup inside run_program(), immediately bef=
ore
    the CreateProcess call.  The original cmdline pointer is stored in
    dll_info[0].name as before, preserving the intact name for later
    reporting, while CreateProcess receives the private copy to mutate free=
ly.
    The copy is intentionally leaked; ssp is short-lived and freeing it wou=
ld
    require threading the pointer across the entire debug loop.
   =20
    Revert the main() change from the previous patch so the caller passes
    argv[optind] directly again.
   =20
    Signed-off-by: Radek Barto=C5=88 <[email protected]>
    Signed-off-by: Thirumalai Nagalingam <thirumalai.nagalingam@multicorewa=
reinc.com>
    Signed-off-by: Chandru Kumaresan <chandru.kumaresan-ftNtnR/FhrXEC4y91aVridAWLNoT+7d/@public.gmane.org=
m>
    Fixes: 87c968601480 ("Cygwin: ssp: Add AArch64 implementation")

Diff:
---
 winsup/utils/ssp.c | 36 ++++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/winsup/utils/ssp.c b/winsup/utils/ssp.c
index 84de523be..deae839d6 100644
--- a/winsup/utils/ssp.c
+++ b/winsup/utils/ssp.c
@@ -379,11 +379,27 @@ run_program (char *cmdline)
   int tix, i;
   HANDLE hThread;
   char *string;
+  char *cmdline_copy;
=20
   memset (&startup, 0, sizeof (startup));
   startup.cb =3D sizeof (startup);
=20
-  if (!CreateProcess (0, cmdline, 0, 0, 0,
+  /* CreateProcess (called with lpApplicationName =3D=3D NULL) is document=
ed to
+     modify the lpCommandLine buffer in place.  dll_info[0].name below poi=
nts
+     at the caller's original string, which is read later when printing the
+     DLL-profile table, so hand CreateProcess a private writable copy to
+     scribble on instead; otherwise the program name comes back mangled
+     (observed on aarch64-cygwin as 'test_hello.exe' -> 'st_hello.exxee').
+     The copy is only needed for the CreateProcess call and is intentional=
ly
+     leaked rather than freed, as ssp is short-lived.  */
+  cmdline_copy =3D strdup (cmdline);
+  if (!cmdline_copy)
+    {
+      fprintf (stderr, "Out of memory duplicating cmdline\n");
+      exit (1);
+    }
+
+  if (!CreateProcess (0, cmdline_copy, 0, 0, 0,
 		     CREATE_NEW_PROCESS_GROUP
 		     | CREATE_SUSPENDED
 		     | DEBUG_PROCESS
@@ -1029,23 +1045,7 @@ main (int argc, char **argv)
=20
   fprintf (stderr, "prun: [" CONTEXT_REG_FMT "," CONTEXT_REG_FMT "] Runnin=
g '%s'\n",
 	  low_pc, high_pc, argv[optind]);
-  {
-    /* CreateProcess (called below with lpApplicationName =3D=3D NULL) is
-       documented to modify the lpCommandLine buffer in place.  argv[optin=
d]
-       points into our own argv, so passing it directly lets CreateProcess
-       scribble on it; this was observed on aarch64-cygwin as the command
-       line coming back mangled (e.g. 'test_hello.exe' -> 'st_hello.exxee')
-       on later use.  Pass a private writable copy instead.  It is not fre=
ed
-       because run_program() stores it in dll_info[0].name, which is read
-       later when printing the DLL-profile table.  */
-    char *cmdline_copy =3D strdup (argv[optind]);
-    if (!cmdline_copy)
-      {
-	fprintf (stderr, "Out of memory duplicating cmdline\n");
-	exit (1);
-      }
-    run_program (cmdline_copy);
-  }
+  run_program (argv[optind]);
=20
   hdr.lpc =3D low_pc;
   hdr.hpc =3D high_pc;