From 9c54570beb5a3681bc744fe574d659b8255055a0 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 23 Jun 2014 11:43:33 +0000 Subject: [PATCH] * environ.cc (regopt): Allocate small local buffer to avoid copying twice. Fixes resource leak (CID 60012). Add comment. --- winsup/cygwin/ChangeLog | 5 +++++ winsup/cygwin/environ.cc | 14 +++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index ab98ebc7d..4d478d6e7 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,8 @@ +2014-06-23 Corinna Vinschen + + * environ.cc (regopt): Allocate small local buffer to avoid copying + twice. Fixes resource leak (CID 60012). Add comment. + 2014-06-23 Corinna Vinschen * dll_init.cc (dll_list::alloc): Fix buffer overrun (CID 59940). diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index a53b5f085..f56d19517 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -780,11 +780,15 @@ ucenv (char *p, const char *eq) /* Set options from the registry. */ static bool __stdcall -regopt (const WCHAR *name, char *buf) +regopt (PCWSTR name, char *buf) { bool parsed_something = false; UNICODE_STRING lname; size_t len = (wcslen(name) + 1) * sizeof (WCHAR); + WCHAR lbuf[1024]; /* Use reasonable size to lower stack pressure. + get_string alloca's this additionally and 1024 + is more than enough for CYGWIN env var values. */ + RtlInitEmptyUnicodeString(&lname, (PWCHAR) alloca (len), len); wcscpy(lname.Buffer, name); RtlDowncaseUnicodeString(&lname, &lname, FALSE); @@ -792,13 +796,9 @@ regopt (const WCHAR *name, char *buf) for (int i = 0; i < 2; i++) { reg_key r (i, KEY_READ, _WIDE (CYGWIN_INFO_PROGRAM_OPTIONS_NAME), NULL); - - if (NT_SUCCESS (r.get_string (lname.Buffer, (PWCHAR) buf, - NT_MAX_PATH, L""))) + if (NT_SUCCESS (r.get_string (lname.Buffer, lbuf, 1024, L""))) { - char *newp; - sys_wcstombs_alloc(&newp, HEAP_NOTHEAP, (PWCHAR) buf); - strcpy(buf, newp); + sys_wcstombs (buf, NT_MAX_PATH, lbuf); parse_options (buf); parsed_something = true; break;