Use nssm_imagepath().
authorIain Patterson <me@iain.cx>
Mon, 2 Mar 2015 11:03:59 +0000 (11:03 +0000)
committerIain Patterson <me@iain.cx>
Mon, 2 Mar 2015 11:08:00 +0000 (11:08 +0000)
We were calling GetModuleFileName() in a number of places.  Use
nssm_imagepath() instead.

Ensure that a quoted path is used for the service image path when
creating the service, thus avoiding a theoretical security vulnerability
whereby the service manager could be tricked into launching the wrong
program.

When setting the path to NSSM in the environment for event hooks we
still use the unquoted path, as environment variables are typically
unquoted.

Thanks Gerald Haider.

README.txt
env.cpp
hook.cpp
nssm.cpp
registry.cpp
service.cpp

index ecca5e9..f48a7f1 100644 (file)
@@ -822,6 +822,8 @@ application's child processes.
 Thanks to Miguel Angel TerrĂ³n for suggesting copy/truncate rotation.\r
 Thanks to Yuriy Lesiuk for suggesting setting the environment before querying\r
 the registry for parameters.\r
+Thanks to Gerald Haider for noticing that installing a service with NSSM in a\r
+path containing spaces was technically a security vulnerability.\r
 \r
 Licence\r
 -------\r
diff --git a/env.cpp b/env.cpp
index 9945d20..083f46a 100644 (file)
--- a/env.cpp
+++ b/env.cpp
@@ -129,8 +129,7 @@ int duplicate_environment(TCHAR *rawenv) {
            -1 on error.
 */
 int test_environment(TCHAR *env) {
-  TCHAR path[PATH_LENGTH];
-  GetModuleFileName(0, path, _countof(path));
+  TCHAR *path = (TCHAR *) nssm_imagepath();
   STARTUPINFO si;
   ZeroMemory(&si, sizeof(si));
   si.cb = sizeof(si);
index 09b98d9..780590b 100644 (file)
--- a/hook.cpp
+++ b/hook.cpp
@@ -254,10 +254,8 @@ int nssm_hook(hook_thread_t *hook_threads, nssm_service_t *service, TCHAR *hook_
   /* Last control handled. */
   SetEnvironmentVariable(NSSM_HOOK_ENV_LAST_CONTROL, service_control_text(service->last_control));
 
-  /* Path to NSSM. */
-  TCHAR path[PATH_LENGTH];
-  GetModuleFileName(0, path, _countof(path));
-  SetEnvironmentVariable(NSSM_HOOK_ENV_IMAGE_PATH, path);
+  /* Path to NSSM, unquoted for the environment. */
+  SetEnvironmentVariable(NSSM_HOOK_ENV_IMAGE_PATH, nssm_unquoted_imagepath());
 
   /* NSSM version. */
   SetEnvironmentVariable(NSSM_HOOK_ENV_NSSM_CONFIGURATION, NSSM_CONFIGURATION);
index ddd1561..0b586f3 100644 (file)
--- a/nssm.cpp
+++ b/nssm.cpp
@@ -65,16 +65,10 @@ static int elevate(int argc, TCHAR **argv, unsigned long message) {
   ZeroMemory(&sei, sizeof(sei));\r
   sei.cbSize = sizeof(sei);\r
   sei.lpVerb = _T("runas");\r
-  sei.lpFile = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, PATH_LENGTH);\r
-  if (! sei.lpFile) {\r
-    print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("GetModuleFileName()"), _T("elevate()"));\r
-    return 111;\r
-  }\r
-  GetModuleFileName(0, (TCHAR *) sei.lpFile, PATH_LENGTH);\r
+  sei.lpFile = (TCHAR *) nssm_imagepath();\r
 \r
   TCHAR *args = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, EXE_LENGTH * sizeof(TCHAR));\r
   if (! args) {\r
-    HeapFree(GetProcessHeap(), 0, (void *) sei.lpFile);\r
     print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("GetCommandLine()"), _T("elevate()"));\r
     return 111;\r
   }\r
@@ -91,7 +85,6 @@ static int elevate(int argc, TCHAR **argv, unsigned long message) {
   unsigned long exitcode = 0;\r
   if (! ShellExecuteEx(&sei)) exitcode = 100;\r
 \r
-  HeapFree(GetProcessHeap(), 0, (void *) sei.lpFile);\r
   HeapFree(GetProcessHeap(), 0, (void *) args);\r
   return exitcode;\r
 }\r
index de3127f..5a4c652 100644 (file)
@@ -17,8 +17,7 @@ int create_messages() {
   }\r
 \r
   /* Get path of this program */\r
-  TCHAR path[PATH_LENGTH];\r
-  GetModuleFileName(0, path, _countof(path));\r
+  const TCHAR *path = nssm_imagepath();\r
 \r
   /* Try to register the module but don't worry so much on failure */\r
   RegSetValueEx(key, _T("EventMessageFile"), 0, REG_SZ, (const unsigned char *) path, (unsigned long) (_tcslen(path) +  1) * sizeof(TCHAR));\r
index 617cad1..6a3907e 100644 (file)
@@ -1126,7 +1126,7 @@ int install_service(nssm_service_t *service) {
   }\r
 \r
   /* Get path of this program */\r
-  GetModuleFileName(0, service->image, _countof(service->image));\r
+  _sntprintf_s(service->image, _countof(service->image), _TRUNCATE, _T("%s"), nssm_imagepath());\r
 \r
   /* Create the service - settings will be changed in edit_service() */\r
   service->handle = CreateService(services, service->name, service->name, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, service->image, 0, 0, 0, 0, 0);\r