[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;